@attlaz/client 1.106.0 → 1.107.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.
- package/dist/Client.d.ts +8 -1
- package/dist/Client.js +9 -0
- package/dist/Http/Transport/OAuthClient.d.ts +20 -0
- package/dist/Http/Transport/OAuthClient.js +35 -3
- package/dist/MarketPulse/Model/CrawlJobPage.js +4 -1
- package/dist/index.d.ts +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/Client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OAuthClientToken } from './Http/OAuthClientToken.js';
|
|
2
2
|
import { ITransport, ParseErrorHandler } from './Http/Transport/ITransport.js';
|
|
3
|
-
import { OAuthClient } from './Http/Transport/OAuthClient.js';
|
|
3
|
+
import { OAuthClient, TokenChangeHandler } from './Http/Transport/OAuthClient.js';
|
|
4
4
|
import { AccessTokenEndpoint } from './Service/AccessTokenEndpoint.js';
|
|
5
5
|
import { AdapterConnectionEndpoint } from './Service/AdapterConnectionEndpoint.js';
|
|
6
6
|
import { AdapterEndpoint } from './Service/AdapterEndpoint.js';
|
|
@@ -91,6 +91,13 @@ export declare class Client {
|
|
|
91
91
|
getToken(): OAuthClientToken | null;
|
|
92
92
|
setToken(token: OAuthClientToken): void;
|
|
93
93
|
unsetAccessToken(): void;
|
|
94
|
+
/**
|
|
95
|
+
* Observe tokens the client acquires or discards on its own — see {@link TokenChangeHandler}.
|
|
96
|
+
* A consumer that persists the token must use this rather than reading getToken() after a call:
|
|
97
|
+
* refresh tokens rotate, so a refreshed token that is not written back is replayed later and
|
|
98
|
+
* rejected. Pass null to stop observing. OAuth-only; a custom transport has no token.
|
|
99
|
+
*/
|
|
100
|
+
setTokenChangeHandler(handler: TokenChangeHandler | null): void;
|
|
94
101
|
getApiInformation(): Promise<{
|
|
95
102
|
version: string;
|
|
96
103
|
}>;
|
package/dist/Client.js
CHANGED
|
@@ -184,6 +184,15 @@ export class Client {
|
|
|
184
184
|
unsetAccessToken() {
|
|
185
185
|
this.httpClient.unsetToken();
|
|
186
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Observe tokens the client acquires or discards on its own — see {@link TokenChangeHandler}.
|
|
189
|
+
* A consumer that persists the token must use this rather than reading getToken() after a call:
|
|
190
|
+
* refresh tokens rotate, so a refreshed token that is not written back is replayed later and
|
|
191
|
+
* rejected. Pass null to stop observing. OAuth-only; a custom transport has no token.
|
|
192
|
+
*/
|
|
193
|
+
setTokenChangeHandler(handler) {
|
|
194
|
+
this.httpClient.setTokenChangeHandler(handler);
|
|
195
|
+
}
|
|
187
196
|
async getApiInformation() {
|
|
188
197
|
const result = await this.httpClient.request('/system/health', null, 'GET', false);
|
|
189
198
|
if (result.version === undefined) {
|
|
@@ -3,10 +3,20 @@ import { Parameters } from '../Data/Parameters.js';
|
|
|
3
3
|
import { OAuthClientOptions } from '../OAuthClientOptions.js';
|
|
4
4
|
import { OAuthClientToken } from '../OAuthClientToken.js';
|
|
5
5
|
import { ITransport, ParseErrorHandler } from './ITransport.js';
|
|
6
|
+
/**
|
|
7
|
+
* Invoked whenever the client changes the token by itself: after a successful authenticate or
|
|
8
|
+
* refresh (the server rotates refresh tokens, so the previous one is revoked at that moment), and
|
|
9
|
+
* with null when a refresh is rejected and the session is gone. A consumer that persists the token
|
|
10
|
+
* must listen here — reading getToken() after a call is too late, because a rotated token that is
|
|
11
|
+
* never written back is replayed later and rejected. Not invoked for setToken()/unsetToken(), which
|
|
12
|
+
* are the caller's own writes.
|
|
13
|
+
*/
|
|
14
|
+
export type TokenChangeHandler = (token: OAuthClientToken | null) => void;
|
|
6
15
|
export declare class OAuthClient implements ITransport {
|
|
7
16
|
private readonly options;
|
|
8
17
|
private debug;
|
|
9
18
|
private oauthClientToken;
|
|
19
|
+
private tokenChangeHandler;
|
|
10
20
|
private tokenAcquisitionPromise;
|
|
11
21
|
private version;
|
|
12
22
|
private parseErrorHandler;
|
|
@@ -43,6 +53,16 @@ export declare class OAuthClient implements ITransport {
|
|
|
43
53
|
getToken(): OAuthClientToken | null;
|
|
44
54
|
setToken(token: OAuthClientToken): void;
|
|
45
55
|
unsetToken(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Observe tokens the client acquires or discards on its own. See {@link TokenChangeHandler}.
|
|
58
|
+
* Pass null to stop observing.
|
|
59
|
+
*/
|
|
60
|
+
setTokenChangeHandler(handler: TokenChangeHandler | null): void;
|
|
61
|
+
/**
|
|
62
|
+
* The single place the client updates its own token, so no acquisition path can change it
|
|
63
|
+
* without the handler hearing about it.
|
|
64
|
+
*/
|
|
65
|
+
private applyToken;
|
|
46
66
|
enableDebug(): void;
|
|
47
67
|
disableDebug(): void;
|
|
48
68
|
isDebugEnabled(): boolean;
|
|
@@ -9,6 +9,7 @@ export class OAuthClient {
|
|
|
9
9
|
options;
|
|
10
10
|
debug = false;
|
|
11
11
|
oauthClientToken = null;
|
|
12
|
+
tokenChangeHandler = null;
|
|
12
13
|
// Single-flight guard for token acquisition (initial client-credentials auth or refresh), so
|
|
13
14
|
// concurrent requests share one in-flight acquisition instead of each hitting the token endpoint.
|
|
14
15
|
tokenAcquisitionPromise = null;
|
|
@@ -34,7 +35,7 @@ export class OAuthClient {
|
|
|
34
35
|
params.client_secret = this.options.clientSecret;
|
|
35
36
|
}
|
|
36
37
|
const rawAuthToken = await this.requestToken(params);
|
|
37
|
-
this.
|
|
38
|
+
this.applyToken(this.tokenToOauthClientToken(rawAuthToken));
|
|
38
39
|
return true;
|
|
39
40
|
}
|
|
40
41
|
if (this.options.clientId !== null && this.options.clientSecret !== null) {
|
|
@@ -45,7 +46,7 @@ export class OAuthClient {
|
|
|
45
46
|
client_secret: this.options.clientSecret,
|
|
46
47
|
scope: this.options.scopes.join(' '),
|
|
47
48
|
});
|
|
48
|
-
this.
|
|
49
|
+
this.applyToken(this.tokenToOauthClientToken(rawAuthToken));
|
|
49
50
|
}
|
|
50
51
|
return true;
|
|
51
52
|
}
|
|
@@ -77,7 +78,7 @@ export class OAuthClient {
|
|
|
77
78
|
params.client_secret = this.options.clientSecret;
|
|
78
79
|
}
|
|
79
80
|
const rawAuthToken = await this.requestToken(params);
|
|
80
|
-
this.
|
|
81
|
+
this.applyToken(this.tokenToOauthClientToken(rawAuthToken));
|
|
81
82
|
}
|
|
82
83
|
catch (e) {
|
|
83
84
|
if (e instanceof ClientError) {
|
|
@@ -88,6 +89,11 @@ export class OAuthClient {
|
|
|
88
89
|
// error. Transient failures (network / 5xx) are rethrown unchanged so a
|
|
89
90
|
// hiccup doesn't force a logout.
|
|
90
91
|
if (e.httpStatus !== null && e.httpStatus >= 400 && e.httpStatus < 500) {
|
|
92
|
+
// Drop the rejected token: keeping it means every later request retries the
|
|
93
|
+
// same dead refresh token, and the server's firewall blocks the IP after a
|
|
94
|
+
// handful of those. A confidential client re-mints via client_credentials on
|
|
95
|
+
// the next request; a public one now fails fast with 401 instead of looping.
|
|
96
|
+
this.applyToken(null);
|
|
91
97
|
throw new ClientError('Refresh token rejected, re-authentication required', HttpStatus.HTTP_UNAUTHORIZED);
|
|
92
98
|
}
|
|
93
99
|
throw e;
|
|
@@ -258,6 +264,32 @@ export class OAuthClient {
|
|
|
258
264
|
unsetToken() {
|
|
259
265
|
this.oauthClientToken = null;
|
|
260
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Observe tokens the client acquires or discards on its own. See {@link TokenChangeHandler}.
|
|
269
|
+
* Pass null to stop observing.
|
|
270
|
+
*/
|
|
271
|
+
setTokenChangeHandler(handler) {
|
|
272
|
+
this.tokenChangeHandler = handler;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* The single place the client updates its own token, so no acquisition path can change it
|
|
276
|
+
* without the handler hearing about it.
|
|
277
|
+
*/
|
|
278
|
+
applyToken(token) {
|
|
279
|
+
this.oauthClientToken = token;
|
|
280
|
+
if (this.tokenChangeHandler === null) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
this.tokenChangeHandler(token);
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
// A consumer's persistence failure must not fail the authentication that succeeded —
|
|
288
|
+
// the token in memory is valid either way. Report it: silently dropping it would hide
|
|
289
|
+
// exactly the stale-token bug this handler exists to prevent.
|
|
290
|
+
console.error('[OAuthClient] Token change handler threw', { error });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
261
293
|
enableDebug() {
|
|
262
294
|
this.debug = true;
|
|
263
295
|
}
|
|
@@ -13,7 +13,10 @@ export class CrawlJobPage {
|
|
|
13
13
|
this.url = url;
|
|
14
14
|
}
|
|
15
15
|
static parse(raw) {
|
|
16
|
-
|
|
16
|
+
// `crawl_job`, not `crawl_job_id`: the API's output serializer snake_cases every key and then
|
|
17
|
+
// strips a trailing `_id` (ApiOutputSerializer.formatKey), so `crawlJobId` arrives as
|
|
18
|
+
// `crawl_job` — the same shape CrawlJob's own `vendorId` takes.
|
|
19
|
+
const page = new CrawlJobPage(raw.id, (raw.crawl_job ?? raw.crawl_job_id), raw.url);
|
|
17
20
|
page.status = (raw.status ?? 'pending');
|
|
18
21
|
page.claimedAt = raw.claimed_at === undefined || raw.claimed_at === null ? null : new Date(raw.claimed_at);
|
|
19
22
|
page.attempts = Number(raw.attempts ?? 0);
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { ITransport } from './Http/Transport/ITransport.js';
|
|
|
11
11
|
export { DirectTransport } from './Http/Transport/DirectTransport.js';
|
|
12
12
|
export type { DirectTransportRoute } from './Http/Transport/DirectTransport.js';
|
|
13
13
|
export { OAuthClient } from './Http/Transport/OAuthClient.js';
|
|
14
|
+
export type { TokenChangeHandler } from './Http/Transport/OAuthClient.js';
|
|
14
15
|
export { OAuthClientOptions } from './Http/OAuthClientOptions.js';
|
|
15
16
|
export { OAuthClientToken } from './Http/OAuthClientToken.js';
|
|
16
17
|
export { ClientError } from './Http/ClientError.js';
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.
|
|
1
|
+
export declare const VERSION = "1.107.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "1.
|
|
1
|
+
export const VERSION = "1.107.0";
|