@outfoxx/sunday 2.0.0-beta.17 → 2.0.0-beta.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -30
- package/build/client-settings.d.ts +6 -7
- package/build/client-settings.js +58 -28
- package/build/client-settings.js.map +1 -1
- package/build/event-parser.d.ts +21 -8
- package/build/event-parser.js +93 -121
- package/build/event-parser.js.map +1 -1
- package/build/fetch-copy.d.ts +15 -0
- package/build/fetch-copy.js +70 -0
- package/build/fetch-copy.js.map +1 -0
- package/build/fetch-event-source.d.ts +6 -5
- package/build/fetch-event-source.js +168 -137
- package/build/fetch-event-source.js.map +1 -1
- package/build/fetch-oauth-token-provider.js +61 -19
- package/build/fetch-oauth-token-provider.js.map +1 -1
- package/build/fetch-transport.d.ts +14 -6
- package/build/fetch-transport.js +126 -168
- package/build/fetch-transport.js.map +1 -1
- package/build/fetch.js +5 -0
- package/build/fetch.js.map +1 -1
- package/build/index.d.ts +7 -2
- package/build/index.js +6 -2
- package/build/index.js.map +1 -1
- package/build/request-adapter.d.ts +8 -0
- package/build/{token-manager-factory.js → request-adapter.js} +1 -1
- package/build/request-adapter.js.map +1 -0
- package/build/request-adapters.d.ts +25 -8
- package/build/request-adapters.js +126 -14
- package/build/request-adapters.js.map +1 -1
- package/build/request-body.d.ts +24 -0
- package/build/request-body.js +104 -0
- package/build/request-body.js.map +1 -0
- package/build/request-cancellation-error.d.ts +13 -0
- package/build/request-cancellation-error.js +43 -0
- package/build/request-cancellation-error.js.map +1 -0
- package/build/request-execution.d.ts +18 -0
- package/build/request-execution.js +108 -0
- package/build/request-execution.js.map +1 -0
- package/build/request-security.d.ts +9 -3
- package/build/request-security.js +101 -36
- package/build/request-security.js.map +1 -1
- package/build/response-adapter.d.ts +10 -0
- package/build/response-adapter.js +15 -0
- package/build/response-adapter.js.map +1 -0
- package/build/response-adapters.d.ts +13 -0
- package/build/response-adapters.js +75 -0
- package/build/response-adapters.js.map +1 -0
- package/build/token-manager.d.ts +13 -4
- package/build/token-manager.js +110 -33
- package/build/token-manager.js.map +1 -1
- package/build/token-provider.d.ts +8 -1
- package/build/token-provider.js +71 -0
- package/build/token-provider.js.map +1 -1
- package/build/transport.d.ts +3 -3
- package/build/util/abort.d.ts +3 -0
- package/build/util/abort.js +42 -0
- package/build/util/abort.js.map +1 -0
- package/build/util/native-fetch.d.ts +2 -0
- package/build/util/native-fetch.js +39 -0
- package/build/util/native-fetch.js.map +1 -0
- package/build/util/owned-body.d.ts +12 -0
- package/build/util/owned-body.js +243 -0
- package/build/util/owned-body.js.map +1 -0
- package/package.json +9 -6
- package/build/token-manager-factory.d.ts +0 -9
- package/build/token-manager-factory.js.map +0 -1
package/build/token-manager.js
CHANGED
|
@@ -11,12 +11,17 @@
|
|
|
11
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
|
+
import { withAbort } from './util/abort.js';
|
|
15
|
+
import { isRequestStopped } from './request-cancellation-error.js';
|
|
14
16
|
import { AuthorizationRequiredError, TokenProviderError, } from './token-provider.js';
|
|
15
17
|
/**
|
|
16
18
|
* Shared token lifecycle with one renewal per cache key. Canceling one caller leaves other waiters
|
|
17
|
-
* running; canceling the last waiter
|
|
19
|
+
* running; canceling the last waiter stops waiting for the provider without abandoning storage commits.
|
|
20
|
+
* A failed or cancelled acquisition is never cached.
|
|
18
21
|
*/
|
|
19
22
|
export class TokenManager {
|
|
23
|
+
identity;
|
|
24
|
+
provider;
|
|
20
25
|
providers;
|
|
21
26
|
store;
|
|
22
27
|
renewals = new Map();
|
|
@@ -25,28 +30,50 @@ export class TokenManager {
|
|
|
25
30
|
now;
|
|
26
31
|
skew;
|
|
27
32
|
constructor(providers, options = {}) {
|
|
28
|
-
this.
|
|
33
|
+
this.provider =
|
|
34
|
+
typeof providers.acquire === 'function'
|
|
35
|
+
? providers
|
|
36
|
+
: undefined;
|
|
37
|
+
this.providers = new Map(this.provider
|
|
38
|
+
? []
|
|
39
|
+
: Object.entries(providers));
|
|
40
|
+
this.identity = this.provider?.identity ?? crypto.randomUUID();
|
|
29
41
|
this.store = options.store ?? new MemoryTokenStore();
|
|
30
42
|
this.now = options.now ?? Date.now;
|
|
31
43
|
this.skew = options.expirySkewMs ?? 30_000;
|
|
32
44
|
if (!Number.isFinite(this.skew) || this.skew < 0)
|
|
33
45
|
throw new RangeError('Invalid token expiry skew');
|
|
34
46
|
}
|
|
47
|
+
/** Forwards application configuration to the explicitly managed provider. */
|
|
48
|
+
configure(binding) {
|
|
49
|
+
const provider = this.provider ?? this.providers.get(binding.provider);
|
|
50
|
+
if (!provider)
|
|
51
|
+
throw new TokenProviderError();
|
|
52
|
+
return provider.configure(binding);
|
|
53
|
+
}
|
|
54
|
+
/** Obtains managed credentials; receipt acquisition preserves rejection context. */
|
|
55
|
+
async acquire(request, signal) {
|
|
56
|
+
return (await this.credentials(request, signal)).tokens;
|
|
57
|
+
}
|
|
35
58
|
/** Acquires current credentials without invoking authorization twice for an expired interactive session. */
|
|
36
59
|
async credentials(binding, signal) {
|
|
37
60
|
signal?.throwIfAborted();
|
|
38
|
-
const provider = this.providers.get(binding.provider);
|
|
61
|
+
const provider = this.provider ?? this.providers.get(binding.provider);
|
|
39
62
|
if (!provider)
|
|
40
63
|
throw new TokenProviderError();
|
|
41
64
|
let configuration;
|
|
42
65
|
try {
|
|
43
66
|
configuration = provider.configure(binding);
|
|
44
67
|
}
|
|
45
|
-
catch {
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (isRequestStopped(error))
|
|
70
|
+
throw error;
|
|
46
71
|
throw new TokenProviderError();
|
|
47
72
|
}
|
|
48
|
-
if (!provider.identity.trim() ||
|
|
49
|
-
|
|
73
|
+
if (!provider.identity.trim() ||
|
|
74
|
+
!configuration.clientIdentity.trim() ||
|
|
75
|
+
(binding.flow === 'authorizationCode' &&
|
|
76
|
+
!configuration.grantIdentity?.trim()))
|
|
50
77
|
throw new TokenProviderError();
|
|
51
78
|
const request = Object.freeze({
|
|
52
79
|
...binding,
|
|
@@ -60,26 +87,49 @@ export class TokenManager {
|
|
|
60
87
|
transport: Object.freeze({ ...binding.transport }),
|
|
61
88
|
});
|
|
62
89
|
const key = JSON.stringify([
|
|
63
|
-
request.scheme,
|
|
64
|
-
|
|
65
|
-
|
|
90
|
+
request.scheme,
|
|
91
|
+
binding.provider,
|
|
92
|
+
provider.identity,
|
|
93
|
+
request.clientIdentity,
|
|
94
|
+
request.grantIdentity,
|
|
95
|
+
request.profile,
|
|
96
|
+
request.flow,
|
|
97
|
+
request.discoveryUrl,
|
|
98
|
+
request.authorizationUrl,
|
|
99
|
+
request.tokenUrl,
|
|
100
|
+
request.refreshUrl,
|
|
101
|
+
request.scopes,
|
|
102
|
+
request.audience,
|
|
103
|
+
request.resource,
|
|
66
104
|
]);
|
|
67
105
|
let renewal = this.renewals.get(key);
|
|
68
106
|
if (!renewal || renewal.controller.signal.aborted) {
|
|
69
107
|
const controller = new AbortController();
|
|
70
108
|
const created = {
|
|
71
|
-
controller,
|
|
109
|
+
controller,
|
|
110
|
+
waiters: 0,
|
|
111
|
+
settled: false,
|
|
112
|
+
committing: false,
|
|
72
113
|
promise: this.exclusive(key, () => this.renew(key, provider, request, controller.signal)),
|
|
73
114
|
};
|
|
74
115
|
this.renewals.set(key, created);
|
|
75
|
-
void created.promise
|
|
116
|
+
void created.promise
|
|
117
|
+
.finally(() => {
|
|
76
118
|
created.settled = true;
|
|
77
119
|
if (this.renewals.get(key) === created)
|
|
78
120
|
this.renewals.delete(key);
|
|
79
|
-
})
|
|
121
|
+
})
|
|
122
|
+
.catch(() => undefined);
|
|
80
123
|
renewal = created;
|
|
81
124
|
}
|
|
82
|
-
|
|
125
|
+
const lease = await this.join(renewal, signal);
|
|
126
|
+
return {
|
|
127
|
+
...lease,
|
|
128
|
+
invalidate: async () => {
|
|
129
|
+
await this.invalidate(lease);
|
|
130
|
+
return true;
|
|
131
|
+
},
|
|
132
|
+
};
|
|
83
133
|
}
|
|
84
134
|
/** Invalidates only the credential that failed, preserving a token already renewed by another caller. */
|
|
85
135
|
async invalidate(lease) {
|
|
@@ -91,7 +141,9 @@ export class TokenManager {
|
|
|
91
141
|
}
|
|
92
142
|
});
|
|
93
143
|
}
|
|
94
|
-
catch {
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (isRequestStopped(error))
|
|
146
|
+
throw error;
|
|
95
147
|
throw new TokenProviderError();
|
|
96
148
|
}
|
|
97
149
|
}
|
|
@@ -99,10 +151,12 @@ export class TokenManager {
|
|
|
99
151
|
const prior = this.locks.get(key) ?? Promise.resolve();
|
|
100
152
|
const next = prior.catch(() => undefined).then(action);
|
|
101
153
|
this.locks.set(key, next);
|
|
102
|
-
void next
|
|
154
|
+
void next
|
|
155
|
+
.finally(() => {
|
|
103
156
|
if (this.locks.get(key) === next)
|
|
104
157
|
this.locks.delete(key);
|
|
105
|
-
})
|
|
158
|
+
})
|
|
159
|
+
.catch(() => undefined);
|
|
106
160
|
return next;
|
|
107
161
|
}
|
|
108
162
|
async renew(key, provider, request, signal) {
|
|
@@ -110,12 +164,16 @@ export class TokenManager {
|
|
|
110
164
|
signal.throwIfAborted();
|
|
111
165
|
const stored = await this.store.load(key);
|
|
112
166
|
signal.throwIfAborted();
|
|
113
|
-
if (stored &&
|
|
167
|
+
if (stored &&
|
|
168
|
+
(stored.expiresAt === undefined ||
|
|
169
|
+
stored.expiresAt > this.now() + this.skew)) {
|
|
114
170
|
return { key, tokens: Object.freeze({ ...stored }) };
|
|
115
171
|
}
|
|
116
172
|
const tokens = await this.acquireOrRefresh(key, stored, provider, request, signal);
|
|
117
|
-
if (!tokens.accessToken ||
|
|
118
|
-
(
|
|
173
|
+
if (!tokens.accessToken ||
|
|
174
|
+
(tokens.expiresAt !== undefined &&
|
|
175
|
+
(!Number.isFinite(tokens.expiresAt) ||
|
|
176
|
+
tokens.expiresAt <= this.now())))
|
|
119
177
|
throw new TokenProviderError();
|
|
120
178
|
const snapshot = Object.freeze({ ...tokens });
|
|
121
179
|
signal.throwIfAborted();
|
|
@@ -130,33 +188,44 @@ export class TokenManager {
|
|
|
130
188
|
catch (error) {
|
|
131
189
|
if (signal.aborted)
|
|
132
190
|
throw signal.reason;
|
|
133
|
-
if (error
|
|
191
|
+
if (isRequestStopped(error))
|
|
192
|
+
throw error;
|
|
193
|
+
if (error instanceof AuthorizationRequiredError ||
|
|
194
|
+
error instanceof TokenProviderError)
|
|
134
195
|
throw error;
|
|
135
196
|
throw new TokenProviderError();
|
|
136
197
|
}
|
|
137
198
|
}
|
|
138
199
|
async acquireOrRefresh(key, stored, provider, request, signal) {
|
|
139
|
-
|
|
200
|
+
const refreshToken = stored?.refreshToken;
|
|
201
|
+
if (refreshToken && provider.refresh) {
|
|
140
202
|
try {
|
|
141
|
-
const refreshed = await provider.refresh(request,
|
|
142
|
-
return {
|
|
203
|
+
const refreshed = await withAbort(() => provider.refresh(request, refreshToken, signal), signal);
|
|
204
|
+
return {
|
|
205
|
+
...refreshed,
|
|
206
|
+
refreshToken: refreshed.refreshToken ?? refreshToken,
|
|
207
|
+
};
|
|
143
208
|
}
|
|
144
209
|
catch (error) {
|
|
145
|
-
if (!(error instanceof TokenProviderError) ||
|
|
210
|
+
if (!(error instanceof TokenProviderError) ||
|
|
211
|
+
error.reason !== 'invalidGrant' ||
|
|
212
|
+
request.flow !== 'clientCredentials')
|
|
146
213
|
throw error;
|
|
147
214
|
signal.throwIfAborted();
|
|
148
215
|
await this.store.remove(key);
|
|
149
|
-
return provider.acquire(request, signal);
|
|
150
216
|
}
|
|
151
217
|
}
|
|
152
|
-
else if (request.flow === 'authorizationCode' &&
|
|
218
|
+
else if (request.flow === 'authorizationCode' &&
|
|
219
|
+
(stored || this.authorizationAttempts.has(key))) {
|
|
153
220
|
throw new AuthorizationRequiredError();
|
|
154
221
|
}
|
|
155
|
-
|
|
222
|
+
// Only provider work is cancellable: storage mutations must finish before releasing the
|
|
223
|
+
// key's lock. Late provider completion is observed by withAbort but cannot reach persistence.
|
|
224
|
+
return withAbort(() => {
|
|
156
225
|
if (request.flow === 'authorizationCode')
|
|
157
226
|
this.authorizationAttempts.add(key);
|
|
158
227
|
return provider.acquire(request, signal);
|
|
159
|
-
}
|
|
228
|
+
}, signal);
|
|
160
229
|
}
|
|
161
230
|
join(renewal, signal) {
|
|
162
231
|
renewal.waiters++;
|
|
@@ -169,7 +238,7 @@ export class TokenManager {
|
|
|
169
238
|
signal?.removeEventListener('abort', abort);
|
|
170
239
|
renewal.waiters--;
|
|
171
240
|
if (renewal.waiters === 0 && !renewal.settled && !renewal.committing)
|
|
172
|
-
renewal.controller.abort();
|
|
241
|
+
renewal.controller.abort(error);
|
|
173
242
|
if (value)
|
|
174
243
|
resolve(value);
|
|
175
244
|
else
|
|
@@ -179,15 +248,23 @@ export class TokenManager {
|
|
|
179
248
|
signal?.addEventListener('abort', abort, { once: true });
|
|
180
249
|
if (signal?.aborted)
|
|
181
250
|
abort();
|
|
182
|
-
renewal.promise.then(value => finish(value), error => finish(undefined, error));
|
|
251
|
+
renewal.promise.then((value) => finish(value), (error) => finish(undefined, error));
|
|
183
252
|
});
|
|
184
253
|
}
|
|
185
254
|
}
|
|
186
255
|
class MemoryTokenStore {
|
|
187
256
|
tokens = new Map();
|
|
188
|
-
load(key) {
|
|
189
|
-
|
|
190
|
-
|
|
257
|
+
load(key) {
|
|
258
|
+
return Promise.resolve(this.tokens.get(key));
|
|
259
|
+
}
|
|
260
|
+
save(key, tokens) {
|
|
261
|
+
this.tokens.set(key, tokens);
|
|
262
|
+
return Promise.resolve();
|
|
263
|
+
}
|
|
264
|
+
remove(key) {
|
|
265
|
+
this.tokens.delete(key);
|
|
266
|
+
return Promise.resolve();
|
|
267
|
+
}
|
|
191
268
|
}
|
|
192
269
|
function compareScopes(left, right) {
|
|
193
270
|
if (left < right)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-manager.js","sourceRoot":"","sources":["../src/token-manager.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;
|
|
1
|
+
{"version":3,"file":"token-manager.js","sourceRoot":"","sources":["../src/token-manager.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EACL,0BAA0B,EAG1B,kBAAkB,GAInB,MAAM,qBAAqB,CAAC;AAkB7B;;;;GAIG;AACH,MAAM,OAAO,YAAY;IACd,QAAQ,CAAS;IACT,QAAQ,CAAiB;IACzB,SAAS,CAAqC;IAC9C,KAAK,CAAa;IAClB,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;IACtC,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC5C,GAAG,CAAe;IAClB,IAAI,CAAS;IAE9B,YACE,SAAkE,EAClE,UAII,EAAE;QAEN,IAAI,CAAC,QAAQ;YACX,OAAO,SAAS,CAAC,OAAO,KAAK,UAAU;gBACrC,CAAC,CAAE,SAA2B;gBAC9B,CAAC,CAAC,SAAS,CAAC;QAChB,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,CACtB,IAAI,CAAC,QAAQ;YACX,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,SAAoD,CAAC,CACzE,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/D,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACrD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC;YAC9C,MAAM,IAAI,UAAU,CAAC,2BAA2B,CAAC,CAAC;IACtD,CAAC;IAED,6EAA6E;IAC7E,SAAS,CAAC,OAAwB;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvE,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,kBAAkB,EAAE,CAAC;QAC9C,OAAO,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,oFAAoF;IACpF,KAAK,CAAC,OAAO,CAAC,OAAqB,EAAE,MAAmB;QACtD,OAAO,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1D,CAAC;IAED,4GAA4G;IAC5G,KAAK,CAAC,WAAW,CACf,OAAwB,EACxB,MAAoB;QAEpB,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvE,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,kBAAkB,EAAE,CAAC;QAC9C,IAAI,aAAiC,CAAC;QACtC,IAAI,CAAC;YACH,aAAa,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,gBAAgB,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YACzC,MAAM,IAAI,kBAAkB,EAAE,CAAC;QACjC,CAAC;QACD,IACE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE;YACzB,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,EAAE;YACpC,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB;gBACnC,CAAC,aAAa,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;YAEvC,MAAM,IAAI,kBAAkB,EAAE,CAAC;QACjC,MAAM,OAAO,GAAiB,MAAM,CAAC,MAAM,CAAC;YAC1C,GAAG,OAAO;YACV,YAAY,EACV,aAAa,CAAC,SAAS,EAAE,YAAY,IAAI,OAAO,CAAC,YAAY;YAC/D,gBAAgB,EACd,aAAa,CAAC,SAAS,EAAE,gBAAgB,IAAI,OAAO,CAAC,gBAAgB;YACvE,QAAQ,EAAE,aAAa,CAAC,SAAS,EAAE,QAAQ,IAAI,OAAO,CAAC,QAAQ;YAC/D,UAAU,EAAE,aAAa,CAAC,SAAS,EAAE,UAAU,IAAI,OAAO,CAAC,UAAU;YACrE,cAAc,EAAE,aAAa,CAAC,cAAc;YAC5C,aAAa,EAAE,aAAa,CAAC,aAAa;YAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACvE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;SACnD,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC;YACzB,OAAO,CAAC,MAAM;YACd,OAAO,CAAC,QAAQ;YAChB,QAAQ,CAAC,QAAQ;YACjB,OAAO,CAAC,cAAc;YACtB,OAAO,CAAC,aAAa;YACrB,OAAO,CAAC,OAAO;YACf,OAAO,CAAC,IAAI;YACZ,OAAO,CAAC,YAAY;YACpB,OAAO,CAAC,gBAAgB;YACxB,OAAO,CAAC,QAAQ;YAChB,OAAO,CAAC,UAAU;YAClB,OAAO,CAAC,MAAM;YACd,OAAO,CAAC,QAAQ;YAChB,OAAO,CAAC,QAAQ;SACjB,CAAC,CAAC;QACH,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,OAAO,GAAY;gBACvB,UAAU;gBACV,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,KAAK;gBACjB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAChC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,CACtD;aACF,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAChC,KAAK,OAAO,CAAC,OAAO;iBACjB,OAAO,CAAC,GAAG,EAAE;gBACZ,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;gBACvB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO;oBAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpE,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC1B,OAAO,GAAG,OAAO,CAAC;QACpB,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO;YACL,GAAG,KAAK;YACR,UAAU,EAAE,KAAK,IAAI,EAAE;gBACrB,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO,IAAI,CAAC;YACd,CAAC;SACF,CAAC;IACJ,CAAC;IAED,yGAAyG;IACzG,KAAK,CAAC,UAAU,CAAC,KAAiB;QAChC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;gBACzC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjD,IAAI,OAAO,EAAE,WAAW,KAAK,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;oBACtD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CACnB,KAAK,CAAC,GAAG,EACT,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAC5C,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,gBAAgB,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YACzC,MAAM,IAAI,kBAAkB,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAEO,SAAS,CAAI,GAAW,EAAE,MAAwB;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,KAAK,IAAI;aACN,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3D,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,KAAK,CACjB,GAAW,EACX,QAAuB,EACvB,OAAqB,EACrB,MAAmB;QAEnB,IAAI,CAAC;YACH,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,IACE,MAAM;gBACN,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS;oBAC7B,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAC5C,CAAC;gBACD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC;YACvD,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,CACxC,GAAG,EACH,MAAM,EACN,QAAQ,EACR,OAAO,EACP,MAAM,CACP,CAAC;YACF,IACE,CAAC,MAAM,CAAC,WAAW;gBACnB,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS;oBAC7B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;wBACjC,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAEpC,MAAM,IAAI,kBAAkB,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;YAC9C,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,OAAO,EAAE,UAAU,CAAC,MAAM,KAAK,MAAM;gBACvC,MAAM,IAAI,YAAY,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;YAC1D,kFAAkF;YAClF,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;YAC1B,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACrC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,CAAC,OAAO;gBAAE,MAAM,MAAM,CAAC,MAAM,CAAC;YACxC,IAAI,gBAAgB,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YACzC,IACE,KAAK,YAAY,0BAA0B;gBAC3C,KAAK,YAAY,kBAAkB;gBAEnC,MAAM,KAAK,CAAC;YACd,MAAM,IAAI,kBAAkB,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,GAAW,EACX,MAA4B,EAC5B,QAAuB,EACvB,OAAqB,EACrB,MAAmB;QAEnB,MAAM,YAAY,GAAG,MAAM,EAAE,YAAY,CAAC;QAC1C,IAAI,YAAY,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,SAAS,CAC/B,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EACtD,MAAM,CACP,CAAC;gBACF,OAAO;oBACL,GAAG,SAAS;oBACZ,YAAY,EAAE,SAAS,CAAC,YAAY,IAAI,YAAY;iBACrD,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IACE,CAAC,CAAC,KAAK,YAAY,kBAAkB,CAAC;oBACtC,KAAK,CAAC,MAAM,KAAK,cAAc;oBAC/B,OAAO,CAAC,IAAI,KAAK,mBAAmB;oBAEpC,MAAM,KAAK,CAAC;gBACd,MAAM,CAAC,cAAc,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;aAAM,IACL,OAAO,CAAC,IAAI,KAAK,mBAAmB;YACpC,CAAC,MAAM,IAAI,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAC/C,CAAC;YACD,MAAM,IAAI,0BAA0B,EAAE,CAAC;QACzC,CAAC;QACD,wFAAwF;QACxF,8FAA8F;QAC9F,OAAO,SAAS,CAAC,GAAG,EAAE;YACpB,IAAI,OAAO,CAAC,IAAI,KAAK,mBAAmB;gBACtC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtC,OAAO,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC,EAAE,MAAM,CAAC,CAAC;IACb,CAAC;IAEO,IAAI,CAAC,OAAgB,EAAE,MAAoB;QACjD,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAE,KAAe,EAAE,EAAE;gBACrD,IAAI,SAAS;oBAAE,OAAO;gBACtB,SAAS,GAAG,IAAI,CAAC;gBACjB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAC5C,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU;oBAClE,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAClC,IAAI,KAAK;oBAAE,OAAO,CAAC,KAAK,CAAC,CAAC;;oBACrB,MAAM,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC,CAAC;YACF,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACtD,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,IAAI,MAAM,EAAE,OAAO;gBAAE,KAAK,EAAE,CAAC;YAC7B,OAAO,CAAC,OAAO,CAAC,IAAI,CAClB,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EACxB,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CACpC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,gBAAgB;IACH,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IACtD,IAAI,CAAC,GAAW;QACd,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,CAAC,GAAW,EAAE,MAAgB;QAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;IACD,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,KAAa;IAChD,IAAI,IAAI,GAAG,KAAK;QAAE,OAAO,CAAC,CAAC,CAAC;IAC5B,IAAI,IAAI,GAAG,KAAK;QAAE,OAAO,CAAC,CAAC;IAC3B,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SecurityBinding, SecurityEndpoints } from './security-binding.js';
|
|
2
|
+
import type { TokenLease } from './token-manager.js';
|
|
2
3
|
/** Credentials returned by an application provider; values are never included in runtime diagnostics. */
|
|
3
4
|
export interface TokenSet {
|
|
4
5
|
readonly accessToken: string;
|
|
@@ -18,12 +19,16 @@ export interface TokenRequest extends SecurityBinding {
|
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
21
|
* Application credential binding. OAuth providers exchange fresh authorization and refresh tokens;
|
|
21
|
-
*
|
|
22
|
+
* providers own their lifecycle; TokenManager adds caching only when explicitly supplied.
|
|
22
23
|
*/
|
|
23
24
|
export interface TokenProvider {
|
|
24
25
|
readonly identity: string;
|
|
25
26
|
configure(binding: SecurityBinding): TokenConfiguration;
|
|
26
27
|
acquire(request: TokenRequest, signal: AbortSignal): Promise<TokenSet>;
|
|
28
|
+
/** Optional receipt acquisition, used by caching decorators to retain their original cache identity. */
|
|
29
|
+
credentials?(binding: SecurityBinding, signal?: AbortSignal): Promise<TokenLease>;
|
|
30
|
+
/** Rejects only this token in its original session. False leaves recovery to the caller. */
|
|
31
|
+
reject?(request: TokenRequest, rejectedToken: string): Promise<boolean>;
|
|
27
32
|
refresh?(request: TokenRequest, refreshToken: string, signal: AbortSignal): Promise<TokenSet>;
|
|
28
33
|
}
|
|
29
34
|
/** Application-owned storage. Implementations must serialize writes and keep credentials private. */
|
|
@@ -42,3 +47,5 @@ export declare class TokenProviderError extends Error {
|
|
|
42
47
|
/** Safe recovery classification; provider messages and credentials are never retained. */
|
|
43
48
|
constructor(reason?: 'unavailable' | 'temporary' | 'invalidGrant');
|
|
44
49
|
}
|
|
50
|
+
/** Acquires once from an application provider without adding storage or refresh policy. */
|
|
51
|
+
export declare function providerCredentials(provider: TokenProvider, binding: SecurityBinding, signal: AbortSignal): Promise<TokenLease>;
|
package/build/token-provider.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
|
+
import { isRequestStopped } from './request-cancellation-error.js';
|
|
14
15
|
/** Signals that an interactive application must supply a fresh authorization session. */
|
|
15
16
|
export class AuthorizationRequiredError extends Error {
|
|
16
17
|
constructor() {
|
|
@@ -28,4 +29,74 @@ export class TokenProviderError extends Error {
|
|
|
28
29
|
this.name = 'TokenProviderError';
|
|
29
30
|
}
|
|
30
31
|
}
|
|
32
|
+
/** Acquires once from an application provider without adding storage or refresh policy. */
|
|
33
|
+
export async function providerCredentials(provider, binding, signal) {
|
|
34
|
+
signal.throwIfAborted();
|
|
35
|
+
try {
|
|
36
|
+
if (provider.credentials) {
|
|
37
|
+
const lease = await provider.credentials(binding, signal);
|
|
38
|
+
signal.throwIfAborted();
|
|
39
|
+
return {
|
|
40
|
+
...lease,
|
|
41
|
+
invalidate: lease.invalidate
|
|
42
|
+
? async () => {
|
|
43
|
+
try {
|
|
44
|
+
return await lease.invalidate();
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw safeProviderError(error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
: undefined,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const configuration = provider.configure(binding);
|
|
54
|
+
if (!provider.identity.trim() || !configuration.clientIdentity.trim())
|
|
55
|
+
throw new TokenProviderError();
|
|
56
|
+
const request = Object.freeze({
|
|
57
|
+
...binding,
|
|
58
|
+
...Object.fromEntries(Object.entries(configuration.endpoints ?? {}).filter(([, value]) => value !== undefined)),
|
|
59
|
+
clientIdentity: configuration.clientIdentity,
|
|
60
|
+
grantIdentity: configuration.grantIdentity,
|
|
61
|
+
scopes: Object.freeze([...new Set(binding.scopes)].sort((left, right) => {
|
|
62
|
+
// Credential scope order must not depend on the host locale.
|
|
63
|
+
if (left === right)
|
|
64
|
+
return 0;
|
|
65
|
+
return left < right ? -1 : 1;
|
|
66
|
+
})),
|
|
67
|
+
transport: Object.freeze({ ...binding.transport }),
|
|
68
|
+
});
|
|
69
|
+
const tokens = Object.freeze({
|
|
70
|
+
...(await provider.acquire(request, signal)),
|
|
71
|
+
});
|
|
72
|
+
signal.throwIfAborted();
|
|
73
|
+
if (!tokens.accessToken ||
|
|
74
|
+
(tokens.expiresAt !== undefined &&
|
|
75
|
+
(!Number.isFinite(tokens.expiresAt) || tokens.expiresAt <= Date.now())))
|
|
76
|
+
throw new TokenProviderError();
|
|
77
|
+
return {
|
|
78
|
+
key: '',
|
|
79
|
+
tokens,
|
|
80
|
+
invalidate: async () => {
|
|
81
|
+
try {
|
|
82
|
+
return ((await provider.reject?.(request, tokens.accessToken)) ?? false);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
throw safeProviderError(error);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
signal.throwIfAborted();
|
|
92
|
+
throw safeProviderError(error);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function safeProviderError(error) {
|
|
96
|
+
return isRequestStopped(error) ||
|
|
97
|
+
error instanceof AuthorizationRequiredError ||
|
|
98
|
+
error instanceof TokenProviderError
|
|
99
|
+
? error
|
|
100
|
+
: new TokenProviderError();
|
|
101
|
+
}
|
|
31
102
|
//# sourceMappingURL=token-provider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-provider.js","sourceRoot":"","sources":["../src/token-provider.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;
|
|
1
|
+
{"version":3,"file":"token-provider.js","sourceRoot":"","sources":["../src/token-provider.ts"],"names":[],"mappings":"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"}
|
package/build/transport.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface Transport<NativeRequest = Request> {
|
|
|
21
21
|
}
|
|
22
22
|
export interface ExtEventSource extends EventSource {
|
|
23
23
|
connect(): void;
|
|
24
|
+
/** Stops the subscription and forwards an optional failure to upstream cleanup. */
|
|
25
|
+
close(reason?: unknown): void;
|
|
24
26
|
}
|
|
25
27
|
export type RequestMethod = 'GET' | 'PUT' | 'POST' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
26
28
|
export interface RequestSpec<B> {
|
|
@@ -41,6 +43,4 @@ export interface RequestSpec<B> {
|
|
|
41
43
|
/** Complete, explicitly selected credential bindings for this operation. */
|
|
42
44
|
security?: readonly SecurityBinding[];
|
|
43
45
|
}
|
|
44
|
-
export
|
|
45
|
-
adapt(transport: Transport, request: Request): Promise<Request>;
|
|
46
|
-
}
|
|
46
|
+
export type { RequestAdapter } from './request-adapter.js';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { discardBody } from './owned-body.js';
|
|
2
|
+
/** Waits cooperatively without leaving abort listeners or late resource results behind. */
|
|
3
|
+
export declare function withAbort<T>(action: () => T | PromiseLike<T>, signal: AbortSignal, discard?: (value: T, reason: unknown) => void): Promise<T>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
export { discardBody } from './owned-body.js';
|
|
15
|
+
/** Waits cooperatively without leaving abort listeners or late resource results behind. */
|
|
16
|
+
export function withAbort(action, signal, discard) {
|
|
17
|
+
signal.throwIfAborted();
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
let aborted = false;
|
|
20
|
+
const onAbort = () => {
|
|
21
|
+
aborted = true;
|
|
22
|
+
reject(signal.reason);
|
|
23
|
+
};
|
|
24
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
25
|
+
Promise.resolve()
|
|
26
|
+
.then(() => {
|
|
27
|
+
signal.throwIfAborted();
|
|
28
|
+
return action();
|
|
29
|
+
})
|
|
30
|
+
.then((value) => {
|
|
31
|
+
signal.removeEventListener('abort', onAbort);
|
|
32
|
+
if (aborted)
|
|
33
|
+
discard?.(value, signal.reason);
|
|
34
|
+
else
|
|
35
|
+
resolve(value);
|
|
36
|
+
}, (error) => {
|
|
37
|
+
signal.removeEventListener('abort', onAbort);
|
|
38
|
+
reject(error);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=abort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.js","sourceRoot":"","sources":["../../src/util/abort.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,2FAA2F;AAC3F,MAAM,UAAU,SAAS,CACvB,MAAgC,EAChC,MAAmB,EACnB,OAA6C;IAE7C,MAAM,CAAC,cAAc,EAAE,CAAC;IACxB,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,OAAO,EAAE;aACd,IAAI,CAAC,GAAG,EAAE;YACT,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO,MAAM,EAAE,CAAC;QAClB,CAAC,CAAC;aACD,IAAI,CACH,CAAC,KAAK,EAAE,EAAE;YACR,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,IAAI,OAAO;gBAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;;gBACxC,OAAO,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;YACR,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CACF,CAAC;IACN,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { isRequestStopped } from '../request-cancellation-error.js';
|
|
15
|
+
import { nativeBodyOperation } from './owned-body.js';
|
|
16
|
+
/** @internal Repairs native Fetch failures only; source ownership takes precedence over native causes. */
|
|
17
|
+
export function nativeFetch(request, signal) {
|
|
18
|
+
return nativeBodyOperation(request.body, async () => {
|
|
19
|
+
try {
|
|
20
|
+
return await fetch(request, { signal });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (signal.aborted)
|
|
24
|
+
throw signal.reason;
|
|
25
|
+
// Node may carry an unmanaged upload's stop error in Fetch's cause chain. This walk must
|
|
26
|
+
// never surround adapters, credential providers, decoders, or custom Fetch callbacks.
|
|
27
|
+
const seen = new Set();
|
|
28
|
+
let cause = error;
|
|
29
|
+
while (typeof cause === 'object' && cause !== null && !seen.has(cause)) {
|
|
30
|
+
if (isRequestStopped(cause))
|
|
31
|
+
throw cause;
|
|
32
|
+
seen.add(cause);
|
|
33
|
+
cause = 'cause' in cause ? cause.cause : undefined;
|
|
34
|
+
}
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=native-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-fetch.js","sourceRoot":"","sources":["../../src/util/native-fetch.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,0GAA0G;AAC1G,MAAM,UAAU,WAAW,CACzB,OAAgB,EAChB,MAAmB;IAEnB,OAAO,mBAAmB,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;QAClD,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,CAAC,OAAO;gBAAE,MAAM,MAAM,CAAC,MAAM,CAAC;YACxC,yFAAyF;YACzF,sFAAsF;YACtF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAC;YAChC,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvE,IAAI,gBAAgB,CAAC,KAAK,CAAC;oBAAE,MAAM,KAAK,CAAC;gBACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAChB,KAAK,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;YACrD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** @internal Owns only application streams, preserving byte-stream capability and backpressure. */
|
|
2
|
+
export declare function ownBody(source: ReadableStream<Uint8Array>, signal?: AbortSignal): ReadableStream<Uint8Array>;
|
|
3
|
+
/** @internal Transfers body metadata and retires unused native branches without consuming the active body. */
|
|
4
|
+
export declare function inheritBody(source: ReadableStream<Uint8Array> | null | undefined, target: Request | Response, previousBody?: ReadableStream<Uint8Array> | null): void;
|
|
5
|
+
/** @internal Recognizes constructor-transferred bodies even when a runtime creates a new stream handle. */
|
|
6
|
+
export declare function sameBody(left: ReadableStream<Uint8Array> | null, right: ReadableStream<Uint8Array> | null): boolean;
|
|
7
|
+
/** @internal Restores errors only at a native read/fetch boundary, never around application callbacks. */
|
|
8
|
+
export declare function nativeBodyOperation<T>(body: ReadableStream<Uint8Array> | null | undefined, action: () => Promise<T>): Promise<T>;
|
|
9
|
+
/** @internal Gives native bulk reads exact source errors and request reads cooperative cancellation. */
|
|
10
|
+
export declare function bodyReads(value: Request | Response): void;
|
|
11
|
+
/** @internal Disposes transferred bodies without waiting for user cleanup or replacing the original error. */
|
|
12
|
+
export declare function discardBody(value: Request | Response, reason?: unknown): void;
|