@attlaz/client 1.115.0 → 1.115.3

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 CHANGED
@@ -77,6 +77,16 @@ export declare class Client {
77
77
  * Used for SPAs and other public clients that cannot keep a secret.
78
78
  */
79
79
  setPublicClient(clientId: string): void;
80
+ /**
81
+ * Overall budget for a single request. **Milliseconds** — the PHP client's `setTimeout()` takes
82
+ * seconds, so do not port a number across without converting.
83
+ *
84
+ * Defaults to 80 seconds, matching the PHP client. Raise it for a large upload or download: the
85
+ * budget covers the whole exchange, so a body big enough to take longer than this to transfer
86
+ * is aborted by the client itself, before the server has said anything. Pass 0 to disable the
87
+ * timeout entirely, which risks hanging the process on a stalled connection.
88
+ */
89
+ setTimeout(timeoutMs: number): void;
80
90
  setVersion(version: string | null): void;
81
91
  getHttpClient(): OAuthClient;
82
92
  /**
package/dist/Client.js CHANGED
@@ -152,6 +152,18 @@ export class Client {
152
152
  setPublicClient(clientId) {
153
153
  this.httpClient.setClientCredentials(clientId, null, ['all']);
154
154
  }
155
+ /**
156
+ * Overall budget for a single request. **Milliseconds** — the PHP client's `setTimeout()` takes
157
+ * seconds, so do not port a number across without converting.
158
+ *
159
+ * Defaults to 80 seconds, matching the PHP client. Raise it for a large upload or download: the
160
+ * budget covers the whole exchange, so a body big enough to take longer than this to transfer
161
+ * is aborted by the client itself, before the server has said anything. Pass 0 to disable the
162
+ * timeout entirely, which risks hanging the process on a stalled connection.
163
+ */
164
+ setTimeout(timeoutMs) {
165
+ this.httpClient.setTimeout(timeoutMs);
166
+ }
155
167
  setVersion(version) {
156
168
  this.httpClient.setVersion(version);
157
169
  }
@@ -2,6 +2,14 @@ export declare class ClientError extends Error {
2
2
  httpStatus: number | null;
3
3
  message: string;
4
4
  response: unknown;
5
+ /**
6
+ * The error this one was built from, when it wraps another (see {@link fromError}).
7
+ *
8
+ * Declared here rather than relying on the built-in `Error.cause`: that is ES2022 and this
9
+ * package compiles against es2017 so it still runs in older browsers. Assigning the property
10
+ * works on any engine, and a modern one treats it as the standard field.
11
+ */
12
+ cause?: unknown;
5
13
  constructor(message: string, httpErrorCode?: number | null);
6
14
  /**
7
15
  * Type guard: true when `error` is a ClientError (or a subclass such as ApiError). Use it to
@@ -3,6 +3,14 @@ export class ClientError extends Error {
3
3
  httpStatus = null;
4
4
  message;
5
5
  response;
6
+ /**
7
+ * The error this one was built from, when it wraps another (see {@link fromError}).
8
+ *
9
+ * Declared here rather than relying on the built-in `Error.cause`: that is ES2022 and this
10
+ * package compiles against es2017 so it still runs in older browsers. Assigning the property
11
+ * works on any engine, and a modern one treats it as the standard field.
12
+ */
13
+ cause;
6
14
  constructor(message, httpErrorCode = null) {
7
15
  super(message);
8
16
  this.message = message;
@@ -36,13 +44,22 @@ export class ClientError extends Error {
36
44
  return error;
37
45
  }
38
46
  // The transport uses fetch, which throws TypeError on network failures (DNS, refused
39
- // connection, TLS, etc.). Anything else reaching here is unexpected surface it as a
40
- // generic 500 while keeping the original name/stack for debugging.
47
+ // connection, TLS, etc.). That case keeps its own wording: "Service not available" says
48
+ // more to a caller than fetch's own "Failed to fetch".
49
+ //
50
+ // Anything else is unexpected, and its message is the only description of what actually
51
+ // went wrong — so it is carried through rather than replaced. This used to read
52
+ // 'Unknown error', which cost a production outage: a ReferenceError from a Node-only
53
+ // global in the browser reached the user as "Unknown error" with nothing naming Buffer,
54
+ // and the console showed the same for every failed call.
41
55
  const clientError = error instanceof TypeError
42
56
  ? new ClientError('Service not available', HttpStatus.HTTP_UNAVAILABLE)
43
- : new ClientError('Unknown error', HttpStatus.HTTP_INTERNAL_SERVER_ERROR);
57
+ : new ClientError(error.message === '' ? 'Unknown error' : error.message, HttpStatus.HTTP_INTERNAL_SERVER_ERROR);
44
58
  clientError.name = error.name;
45
59
  clientError.stack = error.stack;
60
+ // The original survives as `cause`, so a handler can inspect the real error even where the
61
+ // message has been rewritten — the TypeError branch above being exactly that case.
62
+ clientError.cause = error;
46
63
  return clientError;
47
64
  }
48
65
  static byStatus(statusCode, statusText) {
@@ -54,6 +54,14 @@ export declare class OAuthClient implements ITransport {
54
54
  */
55
55
  requestBytes(action: string, parameters?: Parameters, method?: string, signWithOauthToken?: boolean, headers?: Record<string, string>): Promise<Uint8Array>;
56
56
  request<T>(action: string, parameters?: Parameters, method?: string, signWithOauthToken?: boolean): Promise<T>;
57
+ /**
58
+ * Overall budget for a single request, in milliseconds. Applies to the token request too, so a
59
+ * raised budget covers authentication as well.
60
+ *
61
+ * There is no separate connect timeout, unlike the PHP client: `AbortSignal.timeout` bounds the
62
+ * whole exchange and fetch exposes no connect phase to bound on its own.
63
+ */
64
+ setTimeout(timeoutMs: number): void;
57
65
  isAuthenticated(): boolean;
58
66
  getToken(): OAuthClientToken | null;
59
67
  setToken(token: OAuthClientToken): void;
@@ -270,6 +270,16 @@ export class OAuthClient {
270
270
  throw error;
271
271
  }
272
272
  }
273
+ /**
274
+ * Overall budget for a single request, in milliseconds. Applies to the token request too, so a
275
+ * raised budget covers authentication as well.
276
+ *
277
+ * There is no separate connect timeout, unlike the PHP client: `AbortSignal.timeout` bounds the
278
+ * whole exchange and fetch exposes no connect phase to bound on its own.
279
+ */
280
+ setTimeout(timeoutMs) {
281
+ this.options.timeoutMs = timeoutMs;
282
+ }
273
283
  isAuthenticated() {
274
284
  // TODO: other ways to determine if the client is authenticated?
275
285
  return this.oauthClientToken !== null && this.oauthClientToken !== undefined;
@@ -168,10 +168,17 @@ export class Endpoint {
168
168
  }
169
169
  return apiError;
170
170
  }
171
- if (this.httpClient.isDebugEnabled()) {
172
- console.error('Unrecognised error type (not a ClientError)', { error });
173
- }
174
- return new ApiError('Unknown Error', HttpStatus.HTTP_INTERNAL_SERVER_ERROR);
171
+ // Not a ClientError at all — a bug in this client or in a dependency, rather than anything
172
+ // the API said. Its message is carried through and the original attached as `cause`:
173
+ // replacing both with 'Unknown Error' is what made a browser-only ReferenceError
174
+ // undiagnosable from the console during a production outage.
175
+ const apiError = new ApiError(error instanceof Error && error.message !== '' ? error.message : 'Unknown Error', HttpStatus.HTTP_INTERNAL_SERVER_ERROR);
176
+ if (error instanceof Error) {
177
+ apiError.name = error.name;
178
+ apiError.stack = error.stack;
179
+ }
180
+ apiError.cause = error;
181
+ return apiError;
175
182
  }
176
183
  parseCollection(rawData, parser) {
177
184
  const data = [];
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "1.115.0";
1
+ export declare const VERSION = "1.115.2";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "1.115.0";
1
+ export const VERSION = "1.115.2";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@attlaz/client",
3
- "version": "1.115.0",
3
+ "version": "1.115.3",
4
4
  "description": "Javascript Client to access Attlaz API",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "git+https://bitbucket.org/attlaz/javascript-client.git"
23
+ "url": "git+https://github.com/Attlaz-Platform/JS-Client.git"
24
24
  },
25
25
  "homepage": "https://attlaz.com",
26
26
  "keywords": [
@@ -49,7 +49,6 @@
49
49
  },
50
50
  "publishConfig": {
51
51
  "access": "public",
52
- "cache": "~/.npm",
53
52
  "registry": "https://registry.npmjs.org"
54
53
  },
55
54
  "devDependencies": {