@nauth-toolkit/client-angular 0.1.57 → 0.1.58
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/esm2022/ngmodule/http-adapter.mjs +62 -16
- package/esm2022/standalone/http-adapter.mjs +62 -16
- package/fesm2022/nauth-toolkit-client-angular-standalone.mjs +61 -15
- package/fesm2022/nauth-toolkit-client-angular-standalone.mjs.map +1 -1
- package/fesm2022/nauth-toolkit-client-angular.mjs +61 -15
- package/fesm2022/nauth-toolkit-client-angular.mjs.map +1 -1
- package/ngmodule/http-adapter.d.ts +16 -0
- package/package.json +2 -2
- package/standalone/http-adapter.d.ts +16 -0
|
@@ -29,6 +29,37 @@ export class AngularHttpAdapter {
|
|
|
29
29
|
constructor(http) {
|
|
30
30
|
this.http = http;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Safely parse a JSON response body.
|
|
34
|
+
*
|
|
35
|
+
* Angular's fetch backend (`withFetch()`) will throw a raw `SyntaxError` if
|
|
36
|
+
* `responseType: 'json'` is used and the backend returns HTML (common for
|
|
37
|
+
* proxies, 502 pages, SSR fallbacks, or misrouted requests).
|
|
38
|
+
*
|
|
39
|
+
* To avoid crashing consumer apps, we always request as text and then parse
|
|
40
|
+
* JSON only when the response actually looks like JSON.
|
|
41
|
+
*
|
|
42
|
+
* @param bodyText - Raw response body as text
|
|
43
|
+
* @param contentType - Content-Type header value (if available)
|
|
44
|
+
* @returns Parsed JSON value (unknown)
|
|
45
|
+
* @throws {SyntaxError} When body is non-empty but not valid JSON
|
|
46
|
+
*/
|
|
47
|
+
parseJsonBody(bodyText, contentType) {
|
|
48
|
+
const trimmed = bodyText.trim();
|
|
49
|
+
if (!trimmed)
|
|
50
|
+
return null;
|
|
51
|
+
// If it's clearly HTML, never attempt JSON.parse (some proxies mislabel Content-Type).
|
|
52
|
+
if (trimmed.startsWith('<')) {
|
|
53
|
+
return bodyText;
|
|
54
|
+
}
|
|
55
|
+
const looksLikeJson = trimmed.startsWith('{') || trimmed.startsWith('[');
|
|
56
|
+
const isJsonContentType = typeof contentType === 'string' && contentType.toLowerCase().includes('application/json');
|
|
57
|
+
if (!looksLikeJson && !isJsonContentType) {
|
|
58
|
+
// Return raw text when it doesn't look like JSON (e.g., HTML error pages).
|
|
59
|
+
return bodyText;
|
|
60
|
+
}
|
|
61
|
+
return JSON.parse(trimmed);
|
|
62
|
+
}
|
|
32
63
|
/**
|
|
33
64
|
* Execute HTTP request using Angular's HttpClient.
|
|
34
65
|
*
|
|
@@ -38,29 +69,40 @@ export class AngularHttpAdapter {
|
|
|
38
69
|
*/
|
|
39
70
|
async request(config) {
|
|
40
71
|
try {
|
|
41
|
-
// Use Angular's HttpClient - goes through ALL interceptors
|
|
42
|
-
|
|
72
|
+
// Use Angular's HttpClient - goes through ALL interceptors.
|
|
73
|
+
// IMPORTANT: Use responseType 'text' to avoid raw JSON.parse crashes when
|
|
74
|
+
// the backend returns HTML (seen in some proxy/SSR/misroute setups).
|
|
75
|
+
const res = await firstValueFrom(this.http.request(config.method, config.url, {
|
|
43
76
|
body: config.body,
|
|
44
77
|
headers: config.headers,
|
|
45
78
|
withCredentials: config.credentials === 'include',
|
|
46
|
-
observe: '
|
|
79
|
+
observe: 'response',
|
|
80
|
+
responseType: 'text',
|
|
47
81
|
}));
|
|
82
|
+
const contentType = res.headers?.get('content-type');
|
|
83
|
+
const parsed = this.parseJsonBody(res.body ?? '', contentType);
|
|
48
84
|
return {
|
|
49
|
-
data,
|
|
50
|
-
status:
|
|
51
|
-
headers: {}, //
|
|
85
|
+
data: parsed,
|
|
86
|
+
status: res.status,
|
|
87
|
+
headers: {}, // Reserved for future header passthrough if needed
|
|
52
88
|
};
|
|
53
89
|
}
|
|
54
90
|
catch (error) {
|
|
55
91
|
if (error instanceof HttpErrorResponse) {
|
|
56
|
-
// Convert Angular's HttpErrorResponse to NAuthClientError
|
|
57
|
-
|
|
58
|
-
const
|
|
92
|
+
// Convert Angular's HttpErrorResponse to NAuthClientError.
|
|
93
|
+
// When using responseType 'text', `error.error` is typically a string.
|
|
94
|
+
const contentType = error.headers?.get('content-type') ?? null;
|
|
95
|
+
const rawBody = typeof error.error === 'string' ? error.error : '';
|
|
96
|
+
const parsedError = this.parseJsonBody(rawBody, contentType);
|
|
97
|
+
const errorData = typeof parsedError === 'object' && parsedError !== null ? parsedError : {};
|
|
98
|
+
const code = typeof errorData['code'] === 'string' ? errorData['code'] : NAuthErrorCode.INTERNAL_ERROR;
|
|
59
99
|
const message = typeof errorData['message'] === 'string'
|
|
60
|
-
? errorData
|
|
61
|
-
:
|
|
62
|
-
|
|
63
|
-
|
|
100
|
+
? errorData['message']
|
|
101
|
+
: typeof parsedError === 'string' && parsedError.trim()
|
|
102
|
+
? parsedError
|
|
103
|
+
: error.message || `Request failed with status ${error.status}`;
|
|
104
|
+
const timestamp = typeof errorData['timestamp'] === 'string' ? errorData['timestamp'] : undefined;
|
|
105
|
+
const details = typeof errorData['details'] === 'object' ? errorData['details'] : undefined;
|
|
64
106
|
throw new NAuthClientError(code, message, {
|
|
65
107
|
statusCode: error.status,
|
|
66
108
|
timestamp,
|
|
@@ -68,8 +110,12 @@ export class AngularHttpAdapter {
|
|
|
68
110
|
isNetworkError: error.status === 0, // Network error (no response from server)
|
|
69
111
|
});
|
|
70
112
|
}
|
|
71
|
-
// Re-throw non-HTTP errors
|
|
72
|
-
|
|
113
|
+
// Re-throw non-HTTP errors as an SDK error so consumers don't see raw parser crashes.
|
|
114
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
115
|
+
throw new NAuthClientError(NAuthErrorCode.INTERNAL_ERROR, message, {
|
|
116
|
+
statusCode: 0,
|
|
117
|
+
isNetworkError: true,
|
|
118
|
+
});
|
|
73
119
|
}
|
|
74
120
|
}
|
|
75
121
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AngularHttpAdapter, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -78,4 +124,4 @@ export class AngularHttpAdapter {
|
|
|
78
124
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AngularHttpAdapter, decorators: [{
|
|
79
125
|
type: Injectable
|
|
80
126
|
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
81
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL25nbW9kdWxlL2h0dHAtYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBYyxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUEwQyxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBRWpIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBRUgsTUFBTSxPQUFPLGtCQUFrQjtJQUNBO0lBQTdCLFlBQTZCLElBQWdCO1FBQWhCLFNBQUksR0FBSixJQUFJLENBQVk7SUFBRyxDQUFDO0lBRWpEOzs7Ozs7T0FNRztJQUNILEtBQUssQ0FBQyxPQUFPLENBQUksTUFBbUI7UUFDbEMsSUFBSSxDQUFDO1lBQ0gsMkRBQTJEO1lBQzNELE1BQU0sSUFBSSxHQUFHLE1BQU0sY0FBYyxDQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBSSxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUU7Z0JBQzlDLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtnQkFDakIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO2dCQUN2QixlQUFlLEVBQUUsTUFBTSxDQUFDLFdBQVcsS0FBSyxTQUFTO2dCQUNqRCxPQUFPLEVBQUUsTUFBTSxFQUFFLHdCQUF3QjthQUMxQyxDQUFDLENBQ0gsQ0FBQztZQUVGLE9BQU87Z0JBQ0wsSUFBSTtnQkFDSixNQUFNLEVBQUUsR0FBRyxFQUFFLDBDQUEwQztnQkFDdkQsT0FBTyxFQUFFLEVBQUUsRUFBRSxpREFBaUQ7YUFDL0QsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxLQUFLLFlBQVksaUJBQWlCLEVBQUUsQ0FBQztnQkFDdkMsMERBQTBEO2dCQUMxRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxJQUFJLEdBQ1IsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBRSxTQUFTLENBQUMsSUFBdUIsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQztnQkFDN0csTUFBTSxPQUFPLEdBQ1gsT0FBTyxTQUFTLENBQUMsU0FBUyxDQUFDLEtBQUssUUFBUTtvQkFDdEMsQ0FBQyxDQUFFLFNBQVMsQ0FBQyxPQUFrQjtvQkFDL0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksOEJBQThCLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDcEUsTUFBTSxTQUFTLEdBQUcsT0FBTyxTQUFTLENBQUMsV0FBVyxDQUFDLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQy9GLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQXdDLENBQUM7Z0JBRTVFLE1BQU0sSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFO29CQUN4QyxVQUFVLEVBQUUsS0FBSyxDQUFDLE1BQU07b0JBQ3hCLFNBQVM7b0JBQ1QsT0FBTztvQkFDUCxjQUFjLEVBQUUsS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsMENBQTBDO2lCQUMvRSxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsMkJBQTJCO1lBQzNCLE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7d0dBbkRVLGtCQUFrQjs0R0FBbEIsa0JBQWtCOzs0RkFBbEIsa0JBQWtCO2tCQUQ5QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBmaXJzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSHR0cEFkYXB0ZXIsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2UsIE5BdXRoQ2xpZW50RXJyb3IsIE5BdXRoRXJyb3JDb2RlIH0gZnJvbSAnQG5hdXRoLXRvb2xraXQvY2xpZW50JztcblxuLyoqXG4gKiBIVFRQIGFkYXB0ZXIgZm9yIEFuZ3VsYXIgdXNpbmcgSHR0cENsaWVudC5cbiAqXG4gKiBUaGlzIGFkYXB0ZXI6XG4gKiAtIFVzZXMgQW5ndWxhcidzIEh0dHBDbGllbnQgZm9yIGFsbCByZXF1ZXN0c1xuICogLSBXb3JrcyB3aXRoIEFuZ3VsYXIncyBIVFRQIGludGVyY2VwdG9ycyAoaW5jbHVkaW5nIGF1dGhJbnRlcmNlcHRvcilcbiAqIC0gQXV0by1wcm92aWRlZCB2aWEgQW5ndWxhciBESSAocHJvdmlkZWRJbjogJ3Jvb3QnKVxuICogLSBDb252ZXJ0cyBIdHRwQ2xpZW50IHJlc3BvbnNlcyB0byBIdHRwUmVzcG9uc2UgZm9ybWF0XG4gKiAtIENvbnZlcnRzIEh0dHBFcnJvclJlc3BvbnNlIHRvIE5BdXRoQ2xpZW50RXJyb3JcbiAqXG4gKiBVc2VycyBkb24ndCBuZWVkIHRvIGNvbmZpZ3VyZSB0aGlzIG1hbnVhbGx5IC0gaXQncyBhdXRvbWF0aWNhbGx5XG4gKiBpbmplY3RlZCB3aGVuIHVzaW5nIEF1dGhTZXJ2aWNlIGluIEFuZ3VsYXIgYXBwcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQXV0b21hdGljIHVzYWdlIChubyBtYW51YWwgc2V0dXAgbmVlZGVkKVxuICogLy8gQXV0aFNlcnZpY2UgYXV0b21hdGljYWxseSBpbmplY3RzIEFuZ3VsYXJIdHRwQWRhcHRlclxuICogY29uc3RydWN0b3IocHJpdmF0ZSBhdXRoOiBBdXRoU2VydmljZSkge31cbiAqIGBgYFxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQW5ndWxhckh0dHBBZGFwdGVyIGltcGxlbWVudHMgSHR0cEFkYXB0ZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGh0dHA6IEh0dHBDbGllbnQpIHt9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgSFRUUCByZXF1ZXN0IHVzaW5nIEFuZ3VsYXIncyBIdHRwQ2xpZW50LlxuICAgKlxuICAgKiBAcGFyYW0gY29uZmlnIC0gUmVxdWVzdCBjb25maWd1cmF0aW9uXG4gICAqIEByZXR1cm5zIFJlc3BvbnNlIHdpdGggcGFyc2VkIGRhdGFcbiAgICogQHRocm93cyBOQXV0aENsaWVudEVycm9yIGlmIHJlcXVlc3QgZmFpbHNcbiAgICovXG4gIGFzeW5jIHJlcXVlc3Q8VD4oY29uZmlnOiBIdHRwUmVxdWVzdCk6IFByb21pc2U8SHR0cFJlc3BvbnNlPFQ+PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZSBBbmd1bGFyJ3MgSHR0cENsaWVudCAtIGdvZXMgdGhyb3VnaCBBTEwgaW50ZXJjZXB0b3JzXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20oXG4gICAgICAgIHRoaXMuaHR0cC5yZXF1ZXN0PFQ+KGNvbmZpZy5tZXRob2QsIGNvbmZpZy51cmwsIHtcbiAgICAgICAgICBib2R5OiBjb25maWcuYm9keSxcbiAgICAgICAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICAgICAgICB3aXRoQ3JlZGVudGlhbHM6IGNvbmZpZy5jcmVkZW50aWFscyA9PT0gJ2luY2x1ZGUnLFxuICAgICAgICAgIG9ic2VydmU6ICdib2R5JywgLy8gT25seSByZXR1cm4gYm9keSBkYXRhXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YSxcbiAgICAgICAgc3RhdHVzOiAyMDAsIC8vIEh0dHBDbGllbnQgb25seSByZXR1cm5zIGRhdGEgb24gc3VjY2Vzc1xuICAgICAgICBoZWFkZXJzOiB7fSwgLy8gQ2FuIGV4dHJhY3QgZnJvbSBvYnNlcnZlOiAncmVzcG9uc2UnIGlmIG5lZWRlZFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UpIHtcbiAgICAgICAgLy8gQ29udmVydCBBbmd1bGFyJ3MgSHR0cEVycm9yUmVzcG9uc2UgdG8gTkF1dGhDbGllbnRFcnJvclxuICAgICAgICBjb25zdCBlcnJvckRhdGEgPSBlcnJvci5lcnJvciB8fCB7fTtcbiAgICAgICAgY29uc3QgY29kZSA9XG4gICAgICAgICAgdHlwZW9mIGVycm9yRGF0YVsnY29kZSddID09PSAnc3RyaW5nJyA/IChlcnJvckRhdGEuY29kZSBhcyBOQXV0aEVycm9yQ29kZSkgOiBOQXV0aEVycm9yQ29kZS5JTlRFUk5BTF9FUlJPUjtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9XG4gICAgICAgICAgdHlwZW9mIGVycm9yRGF0YVsnbWVzc2FnZSddID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgPyAoZXJyb3JEYXRhLm1lc3NhZ2UgYXMgc3RyaW5nKVxuICAgICAgICAgICAgOiBlcnJvci5tZXNzYWdlIHx8IGBSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyAke2Vycm9yLnN0YXR1c31gO1xuICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSB0eXBlb2YgZXJyb3JEYXRhWyd0aW1lc3RhbXAnXSA9PT0gJ3N0cmluZycgPyBlcnJvckRhdGEudGltZXN0YW1wIDogdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBkZXRhaWxzID0gZXJyb3JEYXRhWydkZXRhaWxzJ10gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgdGhyb3cgbmV3IE5BdXRoQ2xpZW50RXJyb3IoY29kZSwgbWVzc2FnZSwge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IGVycm9yLnN0YXR1cyxcbiAgICAgICAgICB0aW1lc3RhbXAsXG4gICAgICAgICAgZGV0YWlscyxcbiAgICAgICAgICBpc05ldHdvcmtFcnJvcjogZXJyb3Iuc3RhdHVzID09PSAwLCAvLyBOZXR3b3JrIGVycm9yIChubyByZXNwb25zZSBmcm9tIHNlcnZlcilcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlLXRocm93IG5vbi1IVFRQIGVycm9yc1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
127
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL25nbW9kdWxlL2h0dHAtYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBYyxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUEwQyxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBRWpIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBRUgsTUFBTSxPQUFPLGtCQUFrQjtJQUNBO0lBQTdCLFlBQTZCLElBQWdCO1FBQWhCLFNBQUksR0FBSixJQUFJLENBQVk7SUFBRyxDQUFDO0lBRWpEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0ssYUFBYSxDQUFDLFFBQWdCLEVBQUUsV0FBMEI7UUFDaEUsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFMUIsdUZBQXVGO1FBQ3ZGLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzVCLE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUM7UUFFRCxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekUsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLFdBQVcsS0FBSyxRQUFRLElBQUksV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRXBILElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFD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QVMsQ0FBQztnQkFFM0csTUFBTSxJQUFJLGdCQUFnQixDQUFDLElBQUksRUFBRSxPQUFPLEVBQUU7b0JBQ3hDLFVBQVUsRUFBRSxLQUFLLENBQUMsTUFBTTtvQkFDeEIsU0FBUztvQkFDVCxPQUFPO29CQUNQLGNBQWMsRUFBRSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSwwQ0FBMEM7aUJBQy9FLENBQUMsQ0FBQztZQUNMLENBQUM7WUFFRCxzRkFBc0Y7WUFDdEYsTUFBTSxPQUFPLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO1lBQ3pFLE1BQU0sSUFBSSxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsY0FBYyxFQUFFLE9BQU8sRUFBRTtnQkFDakUsVUFBVSxFQUFFLENBQUM7Z0JBQ2IsY0FBYyxFQUFFLElBQUk7YUFDckIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7d0dBekdVLGtCQUFrQjs0R0FBbEIsa0JBQWtCOzs0RkFBbEIsa0JBQWtCO2tCQUQ5QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBmaXJzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSHR0cEFkYXB0ZXIsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2UsIE5BdXRoQ2xpZW50RXJyb3IsIE5BdXRoRXJyb3JDb2RlIH0gZnJvbSAnQG5hdXRoLXRvb2xraXQvY2xpZW50JztcblxuLyoqXG4gKiBIVFRQIGFkYXB0ZXIgZm9yIEFuZ3VsYXIgdXNpbmcgSHR0cENsaWVudC5cbiAqXG4gKiBUaGlzIGFkYXB0ZXI6XG4gKiAtIFVzZXMgQW5ndWxhcidzIEh0dHBDbGllbnQgZm9yIGFsbCByZXF1ZXN0c1xuICogLSBXb3JrcyB3aXRoIEFuZ3VsYXIncyBIVFRQIGludGVyY2VwdG9ycyAoaW5jbHVkaW5nIGF1dGhJbnRlcmNlcHRvcilcbiAqIC0gQXV0by1wcm92aWRlZCB2aWEgQW5ndWxhciBESSAocHJvdmlkZWRJbjogJ3Jvb3QnKVxuICogLSBDb252ZXJ0cyBIdHRwQ2xpZW50IHJlc3BvbnNlcyB0byBIdHRwUmVzcG9uc2UgZm9ybWF0XG4gKiAtIENvbnZlcnRzIEh0dHBFcnJvclJlc3BvbnNlIHRvIE5BdXRoQ2xpZW50RXJyb3JcbiAqXG4gKiBVc2VycyBkb24ndCBuZWVkIHRvIGNvbmZpZ3VyZSB0aGlzIG1hbnVhbGx5IC0gaXQncyBhdXRvbWF0aWNhbGx5XG4gKiBpbmplY3RlZCB3aGVuIHVzaW5nIEF1dGhTZXJ2aWNlIGluIEFuZ3VsYXIgYXBwcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQXV0b21hdGljIHVzYWdlIChubyBtYW51YWwgc2V0dXAgbmVlZGVkKVxuICogLy8gQXV0aFNlcnZpY2UgYXV0b21hdGljYWxseSBpbmplY3RzIEFuZ3VsYXJIdHRwQWRhcHRlclxuICogY29uc3RydWN0b3IocHJpdmF0ZSBhdXRoOiBBdXRoU2VydmljZSkge31cbiAqIGBgYFxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQW5ndWxhckh0dHBBZGFwdGVyIGltcGxlbWVudHMgSHR0cEFkYXB0ZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGh0dHA6IEh0dHBDbGllbnQpIHt9XG5cbiAgLyoqXG4gICAqIFNhZmVseSBwYXJzZSBhIEpTT04gcmVzcG9uc2UgYm9keS5cbiAgICpcbiAgICogQW5ndWxhcidzIGZldGNoIGJhY2tlbmQgKGB3aXRoRmV0Y2goKWApIHdpbGwgdGhyb3cgYSByYXcgYFN5bnRheEVycm9yYCBpZlxuICAgKiBgcmVzcG9uc2VUeXBlOiAnanNvbidgIGlzIHVzZWQgYW5kIHRoZSBiYWNrZW5kIHJldHVybnMgSFRNTCAoY29tbW9uIGZvclxuICAgKiBwcm94aWVzLCA1MDIgcGFnZXMsIFNTUiBmYWxsYmFja3MsIG9yIG1pc3JvdXRlZCByZXF1ZXN0cykuXG4gICAqXG4gICAqIFRvIGF2b2lkIGNyYXNoaW5nIGNvbnN1bWVyIGFwcHMsIHdlIGFsd2F5cyByZXF1ZXN0IGFzIHRleHQgYW5kIHRoZW4gcGFyc2VcbiAgICogSlNPTiBvbmx5IHdoZW4gdGhlIHJlc3BvbnNlIGFjdHVhbGx5IGxvb2tzIGxpa2UgSlNPTi5cbiAgICpcbiAgICogQHBhcmFtIGJvZHlUZXh0IC0gUmF3IHJlc3BvbnNlIGJvZHkgYXMgdGV4dFxuICAgKiBAcGFyYW0gY29udGVudFR5cGUgLSBDb250ZW50LVR5cGUgaGVhZGVyIHZhbHVlIChpZiBhdmFpbGFibGUpXG4gICAqIEByZXR1cm5zIFBhcnNlZCBKU09OIHZhbHVlICh1bmtub3duKVxuICAgKiBAdGhyb3dzIHtTeW50YXhFcnJvcn0gV2hlbiBib2R5IGlzIG5vbi1lbXB0eSBidXQgbm90IHZhbGlkIEpTT05cbiAgICovXG4gIHByaXZhdGUgcGFyc2VKc29uQm9keShib2R5VGV4dDogc3RyaW5nLCBjb250ZW50VHlwZTogc3RyaW5nIHwgbnVsbCk6IHVua25vd24ge1xuICAgIGNvbnN0IHRyaW1tZWQgPSBib2R5VGV4dC50cmltKCk7XG4gICAgaWYgKCF0cmltbWVkKSByZXR1cm4gbnVsbDtcblxuICAgIC8vIElmIGl0J3MgY2xlYXJseSBIVE1MLCBuZXZlciBhdHRlbXB0IEpTT04ucGFyc2UgKHNvbWUgcHJveGllcyBtaXNsYWJlbCBDb250ZW50LVR5cGUpLlxuICAgIGlmICh0cmltbWVkLnN0YXJ0c1dpdGgoJzwnKSkge1xuICAgICAgcmV0dXJuIGJvZHlUZXh0O1xuICAgIH1cblxuICAgIGNvbnN0IGxvb2tzTGlrZUpzb24gPSB0cmltbWVkLnN0YXJ0c1dpdGgoJ3snKSB8fCB0cmltbWVkLnN0YXJ0c1dpdGgoJ1snKTtcbiAgICBjb25zdCBpc0pzb25Db250ZW50VHlwZSA9IHR5cGVvZiBjb250ZW50VHlwZSA9PT0gJ3N0cmluZycgJiYgY29udGVudFR5cGUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnYXBwbGljYXRpb24vanNvbicpO1xuXG4gICAgaWYgKCFsb29rc0xpa2VKc29uICYmICFpc0pzb25Db250ZW50VHlwZSkge1xuICAgICAgLy8gUmV0dXJuIHJhdyB0ZXh0IHdoZW4gaXQgZG9lc24ndCBsb29rIGxpa2UgSlNPTiAoZS5nLiwgSFRNTCBlcnJvciBwYWdlcykuXG4gICAgICByZXR1cm4gYm9keVRleHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIEpTT04ucGFyc2UodHJpbW1lZCkgYXMgdW5rbm93bjtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIEhUVFAgcmVxdWVzdCB1c2luZyBBbmd1bGFyJ3MgSHR0cENsaWVudC5cbiAgICpcbiAgICogQHBhcmFtIGNvbmZpZyAtIFJlcXVlc3QgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJucyBSZXNwb25zZSB3aXRoIHBhcnNlZCBkYXRhXG4gICAqIEB0aHJvd3MgTkF1dGhDbGllbnRFcnJvciBpZiByZXF1ZXN0IGZhaWxzXG4gICAqL1xuICBhc3luYyByZXF1ZXN0PFQ+KGNvbmZpZzogSHR0cFJlcXVlc3QpOiBQcm9taXNlPEh0dHBSZXNwb25zZTxUPj4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBVc2UgQW5ndWxhcidzIEh0dHBDbGllbnQgLSBnb2VzIHRocm91Z2ggQUxMIGludGVyY2VwdG9ycy5cbiAgICAgIC8vIElNUE9SVEFOVDogVXNlIHJlc3BvbnNlVHlwZSAndGV4dCcgdG8gYXZvaWQgcmF3IEpTT04ucGFyc2UgY3Jhc2hlcyB3aGVuXG4gICAgICAvLyB0aGUgYmFja2VuZCByZXR1cm5zIEhUTUwgKHNlZW4gaW4gc29tZSBwcm94eS9TU1IvbWlzcm91dGUgc2V0dXBzKS5cbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKFxuICAgICAgICB0aGlzLmh0dHAucmVxdWVzdChjb25maWcubWV0aG9kLCBjb25maWcudXJsLCB7XG4gICAgICAgICAgYm9keTogY29uZmlnLmJvZHksXG4gICAgICAgICAgaGVhZGVyczogY29uZmlnLmhlYWRlcnMsXG4gICAgICAgICAgd2l0aENyZWRlbnRpYWxzOiBjb25maWcuY3JlZGVudGlhbHMgPT09ICdpbmNsdWRlJyxcbiAgICAgICAgICBvYnNlcnZlOiAncmVzcG9uc2UnLFxuICAgICAgICAgIHJlc3BvbnNlVHlwZTogJ3RleHQnLFxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzLmhlYWRlcnM/LmdldCgnY29udGVudC10eXBlJyk7XG4gICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLnBhcnNlSnNvbkJvZHkocmVzLmJvZHkgPz8gJycsIGNvbnRlbnRUeXBlKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YTogcGFyc2VkIGFzIFQsXG4gICAgICAgIHN0YXR1czogcmVzLnN0YXR1cyxcbiAgICAgICAgaGVhZGVyczoge30sIC8vIFJlc2VydmVkIGZvciBmdXR1cmUgaGVhZGVyIHBhc3N0aHJvdWdoIGlmIG5lZWRlZFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UpIHtcbiAgICAgICAgLy8gQ29udmVydCBBbmd1bGFyJ3MgSHR0cEVycm9yUmVzcG9uc2UgdG8gTkF1dGhDbGllbnRFcnJvci5cbiAgICAgICAgLy8gV2hlbiB1c2luZyByZXNwb25zZVR5cGUgJ3RleHQnLCBgZXJyb3IuZXJyb3JgIGlzIHR5cGljYWxseSBhIHN0cmluZy5cbiAgICAgICAgY29uc3QgY29udGVudFR5cGUgPSBlcnJvci5oZWFkZXJzPy5nZXQoJ2NvbnRlbnQtdHlwZScpID8/IG51bGw7XG4gICAgICAgIGNvbnN0IHJhd0JvZHkgPSB0eXBlb2YgZXJyb3IuZXJyb3IgPT09ICdzdHJpbmcnID8gZXJyb3IuZXJyb3IgOiAnJztcbiAgICAgICAgY29uc3QgcGFyc2VkRXJyb3IgPSB0aGlzLnBhcnNlSnNvbkJvZHkocmF3Qm9keSwgY29udGVudFR5cGUpO1xuXG4gICAgICAgIGNvbnN0IGVycm9yRGF0YSA9XG4gICAgICAgICAgdHlwZW9mIHBhcnNlZEVycm9yID09PSAnb2JqZWN0JyAmJiBwYXJzZWRFcnJvciAhPT0gbnVsbCA/IChwYXJzZWRFcnJvciBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgOiB7fTtcbiAgICAgICAgY29uc3QgY29kZSA9XG4gICAgICAgICAgdHlwZW9mIGVycm9yRGF0YVsnY29kZSddID09PSAnc3RyaW5nJyA/IChlcnJvckRhdGFbJ2NvZGUnXSBhcyBOQXV0aEVycm9yQ29kZSkgOiBOQXV0aEVycm9yQ29kZS5JTlRFUk5BTF9FUlJPUjtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9XG4gICAgICAgICAgdHlwZW9mIGVycm9yRGF0YVsnbWVzc2FnZSddID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgPyAoZXJyb3JEYXRhWydtZXNzYWdlJ10gYXMgc3RyaW5nKVxuICAgICAgICAgICAgOiB0eXBlb2YgcGFyc2VkRXJyb3IgPT09ICdzdHJpbmcnICYmIHBhcnNlZEVycm9yLnRyaW0oKVxuICAgICAgICAgICAgICA/IHBhcnNlZEVycm9yXG4gICAgICAgICAgICAgIDogZXJyb3IubWVzc2FnZSB8fCBgUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgJHtlcnJvci5zdGF0dXN9YDtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gdHlwZW9mIGVycm9yRGF0YVsndGltZXN0YW1wJ10gPT09ICdzdHJpbmcnID8gKGVycm9yRGF0YVsndGltZXN0YW1wJ10gYXMgc3RyaW5nKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgZGV0YWlscyA9XG4gICAgICAgICAgdHlwZW9mIGVycm9yRGF0YVsnZGV0YWlscyddID09PSAnb2JqZWN0JyA/IChlcnJvckRhdGFbJ2RldGFpbHMnXSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgdGhyb3cgbmV3IE5BdXRoQ2xpZW50RXJyb3IoY29kZSwgbWVzc2FnZSwge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IGVycm9yLnN0YXR1cyxcbiAgICAgICAgICB0aW1lc3RhbXAsXG4gICAgICAgICAgZGV0YWlscyxcbiAgICAgICAgICBpc05ldHdvcmtFcnJvcjogZXJyb3Iuc3RhdHVzID09PSAwLCAvLyBOZXR3b3JrIGVycm9yIChubyByZXNwb25zZSBmcm9tIHNlcnZlcilcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlLXRocm93IG5vbi1IVFRQIGVycm9ycyBhcyBhbiBTREsgZXJyb3Igc28gY29uc3VtZXJzIGRvbid0IHNlZSByYXcgcGFyc2VyIGNyYXNoZXMuXG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcic7XG4gICAgICB0aHJvdyBuZXcgTkF1dGhDbGllbnRFcnJvcihOQXV0aEVycm9yQ29kZS5JTlRFUk5BTF9FUlJPUiwgbWVzc2FnZSwge1xuICAgICAgICBzdGF0dXNDb2RlOiAwLFxuICAgICAgICBpc05ldHdvcmtFcnJvcjogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -29,6 +29,37 @@ export class AngularHttpAdapter {
|
|
|
29
29
|
constructor(http) {
|
|
30
30
|
this.http = http;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Safely parse a JSON response body.
|
|
34
|
+
*
|
|
35
|
+
* Angular's fetch backend (`withFetch()`) will throw a raw `SyntaxError` if
|
|
36
|
+
* `responseType: 'json'` is used and the backend returns HTML (common for
|
|
37
|
+
* proxies, 502 pages, SSR fallbacks, or misrouted requests).
|
|
38
|
+
*
|
|
39
|
+
* To avoid crashing consumer apps, we always request as text and then parse
|
|
40
|
+
* JSON only when the response actually looks like JSON.
|
|
41
|
+
*
|
|
42
|
+
* @param bodyText - Raw response body as text
|
|
43
|
+
* @param contentType - Content-Type header value (if available)
|
|
44
|
+
* @returns Parsed JSON value (unknown)
|
|
45
|
+
* @throws {SyntaxError} When body is non-empty but not valid JSON
|
|
46
|
+
*/
|
|
47
|
+
parseJsonBody(bodyText, contentType) {
|
|
48
|
+
const trimmed = bodyText.trim();
|
|
49
|
+
if (!trimmed)
|
|
50
|
+
return null;
|
|
51
|
+
// If it's clearly HTML, never attempt JSON.parse (some proxies mislabel Content-Type).
|
|
52
|
+
if (trimmed.startsWith('<')) {
|
|
53
|
+
return bodyText;
|
|
54
|
+
}
|
|
55
|
+
const looksLikeJson = trimmed.startsWith('{') || trimmed.startsWith('[');
|
|
56
|
+
const isJsonContentType = typeof contentType === 'string' && contentType.toLowerCase().includes('application/json');
|
|
57
|
+
if (!looksLikeJson && !isJsonContentType) {
|
|
58
|
+
// Return raw text when it doesn't look like JSON (e.g., HTML error pages).
|
|
59
|
+
return bodyText;
|
|
60
|
+
}
|
|
61
|
+
return JSON.parse(trimmed);
|
|
62
|
+
}
|
|
32
63
|
/**
|
|
33
64
|
* Execute HTTP request using Angular's HttpClient.
|
|
34
65
|
*
|
|
@@ -38,29 +69,40 @@ export class AngularHttpAdapter {
|
|
|
38
69
|
*/
|
|
39
70
|
async request(config) {
|
|
40
71
|
try {
|
|
41
|
-
// Use Angular's HttpClient - goes through ALL interceptors
|
|
42
|
-
|
|
72
|
+
// Use Angular's HttpClient - goes through ALL interceptors.
|
|
73
|
+
// IMPORTANT: Use responseType 'text' to avoid raw JSON.parse crashes when
|
|
74
|
+
// the backend returns HTML (seen in some proxy/SSR/misroute setups).
|
|
75
|
+
const res = await firstValueFrom(this.http.request(config.method, config.url, {
|
|
43
76
|
body: config.body,
|
|
44
77
|
headers: config.headers,
|
|
45
78
|
withCredentials: config.credentials === 'include',
|
|
46
|
-
observe: '
|
|
79
|
+
observe: 'response',
|
|
80
|
+
responseType: 'text',
|
|
47
81
|
}));
|
|
82
|
+
const contentType = res.headers?.get('content-type');
|
|
83
|
+
const parsed = this.parseJsonBody(res.body ?? '', contentType);
|
|
48
84
|
return {
|
|
49
|
-
data,
|
|
50
|
-
status:
|
|
51
|
-
headers: {}, //
|
|
85
|
+
data: parsed,
|
|
86
|
+
status: res.status,
|
|
87
|
+
headers: {}, // Reserved for future header passthrough if needed
|
|
52
88
|
};
|
|
53
89
|
}
|
|
54
90
|
catch (error) {
|
|
55
91
|
if (error instanceof HttpErrorResponse) {
|
|
56
|
-
// Convert Angular's HttpErrorResponse to NAuthClientError
|
|
57
|
-
|
|
58
|
-
const
|
|
92
|
+
// Convert Angular's HttpErrorResponse to NAuthClientError.
|
|
93
|
+
// When using responseType 'text', `error.error` is typically a string.
|
|
94
|
+
const contentType = error.headers?.get('content-type') ?? null;
|
|
95
|
+
const rawBody = typeof error.error === 'string' ? error.error : '';
|
|
96
|
+
const parsedError = this.parseJsonBody(rawBody, contentType);
|
|
97
|
+
const errorData = typeof parsedError === 'object' && parsedError !== null ? parsedError : {};
|
|
98
|
+
const code = typeof errorData['code'] === 'string' ? errorData['code'] : NAuthErrorCode.INTERNAL_ERROR;
|
|
59
99
|
const message = typeof errorData['message'] === 'string'
|
|
60
|
-
? errorData
|
|
61
|
-
:
|
|
62
|
-
|
|
63
|
-
|
|
100
|
+
? errorData['message']
|
|
101
|
+
: typeof parsedError === 'string' && parsedError.trim()
|
|
102
|
+
? parsedError
|
|
103
|
+
: error.message || `Request failed with status ${error.status}`;
|
|
104
|
+
const timestamp = typeof errorData['timestamp'] === 'string' ? errorData['timestamp'] : undefined;
|
|
105
|
+
const details = typeof errorData['details'] === 'object' ? errorData['details'] : undefined;
|
|
64
106
|
throw new NAuthClientError(code, message, {
|
|
65
107
|
statusCode: error.status,
|
|
66
108
|
timestamp,
|
|
@@ -68,8 +110,12 @@ export class AngularHttpAdapter {
|
|
|
68
110
|
isNetworkError: error.status === 0, // Network error (no response from server)
|
|
69
111
|
});
|
|
70
112
|
}
|
|
71
|
-
// Re-throw non-HTTP errors
|
|
72
|
-
|
|
113
|
+
// Re-throw non-HTTP errors as an SDK error so consumers don't see raw parser crashes.
|
|
114
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
115
|
+
throw new NAuthClientError(NAuthErrorCode.INTERNAL_ERROR, message, {
|
|
116
|
+
statusCode: 0,
|
|
117
|
+
isNetworkError: true,
|
|
118
|
+
});
|
|
73
119
|
}
|
|
74
120
|
}
|
|
75
121
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AngularHttpAdapter, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -78,4 +124,4 @@ export class AngularHttpAdapter {
|
|
|
78
124
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AngularHttpAdapter, decorators: [{
|
|
79
125
|
type: Injectable
|
|
80
126
|
}], ctorParameters: () => [{ type: i1.HttpClient }] });
|
|
81
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3RhbmRhbG9uZS9odHRwLWFkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNyRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RDLE9BQU8sRUFBMEMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7OztBQUVqSDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUVILE1BQU0sT0FBTyxrQkFBa0I7SUFDQTtJQUE3QixZQUE2QixJQUFnQjtRQUFoQixTQUFJLEdBQUosSUFBSSxDQUFZO0lBQUcsQ0FBQztJQUVqRDs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsT0FBTyxDQUFJLE1BQW1CO1FBQ2xDLElBQUksQ0FBQztZQUNILDJEQUEyRDtZQUMzRCxNQUFNLElBQUksR0FBRyxNQUFNLGNBQWMsQ0FDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUksTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFO2dCQUM5QyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7Z0JBQ2pCLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztnQkFDdkIsZUFBZSxFQUFFLE1BQU0sQ0FBQyxXQUFXLEtBQUssU0FBUztnQkFDakQsT0FBTyxFQUFFLE1BQU0sRUFBRSx3QkFBd0I7YUFDMUMsQ0FBQyxDQUNILENBQUM7WUFFRixPQUFPO2dCQUNMLElBQUk7Z0JBQ0osTUFBTSxFQUFFLEdBQUcsRUFBRSwwQ0FBMEM7Z0JBQ3ZELE9BQU8sRUFBRSxFQUFFLEVBQUUsaURBQWlEO2FBQy9ELENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3ZDLDBEQUEwRDtnQkFDMUQsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sSUFBSSxHQUNSLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUUsU0FBUyxDQUFDLElBQXVCLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUM7Z0JBQzdHLE1BQU0sT0FBTyxHQUNYLE9BQU8sU0FBUyxDQUFDLFNBQVMsQ0FBQyxLQUFLLFFBQVE7b0JBQ3RDLENBQUMsQ0FBRSxTQUFTLENBQUMsT0FBa0I7b0JBQy9CLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxJQUFJLDhCQUE4QixLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3BFLE1BQU0sU0FBUyxHQUFHLE9BQU8sU0FBUyxDQUFDLFdBQVcsQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUMvRixNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsU0FBUyxDQUF3QyxDQUFDO2dCQUU1RSxNQUFNLElBQUksZ0JBQWdCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRTtvQkFDeEMsVUFBVSxFQUFFLEtBQUssQ0FBQyxNQUFNO29CQUN4QixTQUFTO29CQUNULE9BQU87b0JBQ1AsY0FBYyxFQUFFLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLDBDQUEwQztpQkFDL0UsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELDJCQUEyQjtZQUMzQixNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO3dHQW5EVSxrQkFBa0I7NEdBQWxCLGtCQUFrQjs7NEZBQWxCLGtCQUFrQjtrQkFEOUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEh0dHBBZGFwdGVyLCBIdHRwUmVxdWVzdCwgSHR0cFJlc3BvbnNlLCBOQXV0aENsaWVudEVycm9yLCBOQXV0aEVycm9yQ29kZSB9IGZyb20gJ0BuYXV0aC10b29sa2l0L2NsaWVudCc7XG5cbi8qKlxuICogSFRUUCBhZGFwdGVyIGZvciBBbmd1bGFyIHVzaW5nIEh0dHBDbGllbnQuXG4gKlxuICogVGhpcyBhZGFwdGVyOlxuICogLSBVc2VzIEFuZ3VsYXIncyBIdHRwQ2xpZW50IGZvciBhbGwgcmVxdWVzdHNcbiAqIC0gV29ya3Mgd2l0aCBBbmd1bGFyJ3MgSFRUUCBpbnRlcmNlcHRvcnMgKGluY2x1ZGluZyBhdXRoSW50ZXJjZXB0b3IpXG4gKiAtIEF1dG8tcHJvdmlkZWQgdmlhIEFuZ3VsYXIgREkgKHByb3ZpZGVkSW46ICdyb290JylcbiAqIC0gQ29udmVydHMgSHR0cENsaWVudCByZXNwb25zZXMgdG8gSHR0cFJlc3BvbnNlIGZvcm1hdFxuICogLSBDb252ZXJ0cyBIdHRwRXJyb3JSZXNwb25zZSB0byBOQXV0aENsaWVudEVycm9yXG4gKlxuICogVXNlcnMgZG9uJ3QgbmVlZCB0byBjb25maWd1cmUgdGhpcyBtYW51YWxseSAtIGl0J3MgYXV0b21hdGljYWxseVxuICogaW5qZWN0ZWQgd2hlbiB1c2luZyBBdXRoU2VydmljZSBpbiBBbmd1bGFyIGFwcHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIEF1dG9tYXRpYyB1c2FnZSAobm8gbWFudWFsIHNldHVwIG5lZWRlZClcbiAqIC8vIEF1dGhTZXJ2aWNlIGF1dG9tYXRpY2FsbHkgaW5qZWN0cyBBbmd1bGFySHR0cEFkYXB0ZXJcbiAqIGNvbnN0cnVjdG9yKHByaXZhdGUgYXV0aDogQXV0aFNlcnZpY2UpIHt9XG4gKiBgYGBcbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJIdHRwQWRhcHRlciBpbXBsZW1lbnRzIEh0dHBBZGFwdGVyIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBodHRwOiBIdHRwQ2xpZW50KSB7fVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIEhUVFAgcmVxdWVzdCB1c2luZyBBbmd1bGFyJ3MgSHR0cENsaWVudC5cbiAgICpcbiAgICogQHBhcmFtIGNvbmZpZyAtIFJlcXVlc3QgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJucyBSZXNwb25zZSB3aXRoIHBhcnNlZCBkYXRhXG4gICAqIEB0aHJvd3MgTkF1dGhDbGllbnRFcnJvciBpZiByZXF1ZXN0IGZhaWxzXG4gICAqL1xuICBhc3luYyByZXF1ZXN0PFQ+KGNvbmZpZzogSHR0cFJlcXVlc3QpOiBQcm9taXNlPEh0dHBSZXNwb25zZTxUPj4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBVc2UgQW5ndWxhcidzIEh0dHBDbGllbnQgLSBnb2VzIHRocm91Z2ggQUxMIGludGVyY2VwdG9yc1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKFxuICAgICAgICB0aGlzLmh0dHAucmVxdWVzdDxUPihjb25maWcubWV0aG9kLCBjb25maWcudXJsLCB7XG4gICAgICAgICAgYm9keTogY29uZmlnLmJvZHksXG4gICAgICAgICAgaGVhZGVyczogY29uZmlnLmhlYWRlcnMsXG4gICAgICAgICAgd2l0aENyZWRlbnRpYWxzOiBjb25maWcuY3JlZGVudGlhbHMgPT09ICdpbmNsdWRlJyxcbiAgICAgICAgICBvYnNlcnZlOiAnYm9keScsIC8vIE9ubHkgcmV0dXJuIGJvZHkgZGF0YVxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGEsXG4gICAgICAgIHN0YXR1czogMjAwLCAvLyBIdHRwQ2xpZW50IG9ubHkgcmV0dXJucyBkYXRhIG9uIHN1Y2Nlc3NcbiAgICAgICAgaGVhZGVyczoge30sIC8vIENhbiBleHRyYWN0IGZyb20gb2JzZXJ2ZTogJ3Jlc3BvbnNlJyBpZiBuZWVkZWRcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XG4gICAgICAgIC8vIENvbnZlcnQgQW5ndWxhcidzIEh0dHBFcnJvclJlc3BvbnNlIHRvIE5BdXRoQ2xpZW50RXJyb3JcbiAgICAgICAgY29uc3QgZXJyb3JEYXRhID0gZXJyb3IuZXJyb3IgfHwge307XG4gICAgICAgIGNvbnN0IGNvZGUgPVxuICAgICAgICAgIHR5cGVvZiBlcnJvckRhdGFbJ2NvZGUnXSA9PT0gJ3N0cmluZycgPyAoZXJyb3JEYXRhLmNvZGUgYXMgTkF1dGhFcnJvckNvZGUpIDogTkF1dGhFcnJvckNvZGUuSU5URVJOQUxfRVJST1I7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPVxuICAgICAgICAgIHR5cGVvZiBlcnJvckRhdGFbJ21lc3NhZ2UnXSA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgID8gKGVycm9yRGF0YS5tZXNzYWdlIGFzIHN0cmluZylcbiAgICAgICAgICAgIDogZXJyb3IubWVzc2FnZSB8fCBgUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgJHtlcnJvci5zdGF0dXN9YDtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gdHlwZW9mIGVycm9yRGF0YVsndGltZXN0YW1wJ10gPT09ICdzdHJpbmcnID8gZXJyb3JEYXRhLnRpbWVzdGFtcCA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgZGV0YWlscyA9IGVycm9yRGF0YVsnZGV0YWlscyddIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIHRocm93IG5ldyBOQXV0aENsaWVudEVycm9yKGNvZGUsIG1lc3NhZ2UsIHtcbiAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXMsXG4gICAgICAgICAgdGltZXN0YW1wLFxuICAgICAgICAgIGRldGFpbHMsXG4gICAgICAgICAgaXNOZXR3b3JrRXJyb3I6IGVycm9yLnN0YXR1cyA9PT0gMCwgLy8gTmV0d29yayBlcnJvciAobm8gcmVzcG9uc2UgZnJvbSBzZXJ2ZXIpXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBSZS10aHJvdyBub24tSFRUUCBlcnJvcnNcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxufVxuIl19
|
|
127
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3RhbmRhbG9uZS9odHRwLWFkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNyRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RDLE9BQU8sRUFBMEMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7OztBQUVqSDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUVILE1BQU0sT0FBTyxrQkFBa0I7SUFDQTtJQUE3QixZQUE2QixJQUFnQjtRQUFoQixTQUFJLEdBQUosSUFBSSxDQUFZO0lBQUcsQ0FBQztJQUVqRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNLLGFBQWEsQ0FBQyxRQUFnQixFQUFFLFdBQTBCO1FBQ2hFLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRTFCLHVGQUF1RjtRQUN2RixJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM1QixPQUFPLFFBQVEsQ0FBQztRQUNsQixDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pFLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxXQUFXLEtBQUssUUFBUSxJQUFJLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUVwSCxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZ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LENBQUM7Z0JBRXpILE1BQU0sSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFO29CQUN4QyxVQUFVLEVBQUUsS0FBSyxDQUFDLE1BQU07b0JBQ3hCLFNBQVM7b0JBQ1QsT0FBTztvQkFDUCxjQUFjLEVBQUUsS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsMENBQTBDO2lCQUMvRSxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsc0ZBQXNGO1lBQ3RGLE1BQU0sT0FBTyxHQUFHLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQztZQUN6RSxNQUFNLElBQUksZ0JBQWdCLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFBRSxPQUFPLEVBQUU7Z0JBQ2pFLFVBQVUsRUFBRSxDQUFDO2dCQUNiLGNBQWMsRUFBRSxJQUFJO2FBQ3JCLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO3dHQXRHVSxrQkFBa0I7NEdBQWxCLGtCQUFrQjs7NEZBQWxCLGtCQUFrQjtrQkFEOUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEh0dHBBZGFwdGVyLCBIdHRwUmVxdWVzdCwgSHR0cFJlc3BvbnNlLCBOQXV0aENsaWVudEVycm9yLCBOQXV0aEVycm9yQ29kZSB9IGZyb20gJ0BuYXV0aC10b29sa2l0L2NsaWVudCc7XG5cbi8qKlxuICogSFRUUCBhZGFwdGVyIGZvciBBbmd1bGFyIHVzaW5nIEh0dHBDbGllbnQuXG4gKlxuICogVGhpcyBhZGFwdGVyOlxuICogLSBVc2VzIEFuZ3VsYXIncyBIdHRwQ2xpZW50IGZvciBhbGwgcmVxdWVzdHNcbiAqIC0gV29ya3Mgd2l0aCBBbmd1bGFyJ3MgSFRUUCBpbnRlcmNlcHRvcnMgKGluY2x1ZGluZyBhdXRoSW50ZXJjZXB0b3IpXG4gKiAtIEF1dG8tcHJvdmlkZWQgdmlhIEFuZ3VsYXIgREkgKHByb3ZpZGVkSW46ICdyb290JylcbiAqIC0gQ29udmVydHMgSHR0cENsaWVudCByZXNwb25zZXMgdG8gSHR0cFJlc3BvbnNlIGZvcm1hdFxuICogLSBDb252ZXJ0cyBIdHRwRXJyb3JSZXNwb25zZSB0byBOQXV0aENsaWVudEVycm9yXG4gKlxuICogVXNlcnMgZG9uJ3QgbmVlZCB0byBjb25maWd1cmUgdGhpcyBtYW51YWxseSAtIGl0J3MgYXV0b21hdGljYWxseVxuICogaW5qZWN0ZWQgd2hlbiB1c2luZyBBdXRoU2VydmljZSBpbiBBbmd1bGFyIGFwcHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIEF1dG9tYXRpYyB1c2FnZSAobm8gbWFudWFsIHNldHVwIG5lZWRlZClcbiAqIC8vIEF1dGhTZXJ2aWNlIGF1dG9tYXRpY2FsbHkgaW5qZWN0cyBBbmd1bGFySHR0cEFkYXB0ZXJcbiAqIGNvbnN0cnVjdG9yKHByaXZhdGUgYXV0aDogQXV0aFNlcnZpY2UpIHt9XG4gKiBgYGBcbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJIdHRwQWRhcHRlciBpbXBsZW1lbnRzIEh0dHBBZGFwdGVyIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBodHRwOiBIdHRwQ2xpZW50KSB7fVxuXG4gIC8qKlxuICAgKiBTYWZlbHkgcGFyc2UgYSBKU09OIHJlc3BvbnNlIGJvZHkuXG4gICAqXG4gICAqIEFuZ3VsYXIncyBmZXRjaCBiYWNrZW5kIChgd2l0aEZldGNoKClgKSB3aWxsIHRocm93IGEgcmF3IGBTeW50YXhFcnJvcmAgaWZcbiAgICogYHJlc3BvbnNlVHlwZTogJ2pzb24nYCBpcyB1c2VkIGFuZCB0aGUgYmFja2VuZCByZXR1cm5zIEhUTUwgKGNvbW1vbiBmb3JcbiAgICogcHJveGllcywgNTAyIHBhZ2VzLCBTU1IgZmFsbGJhY2tzLCBvciBtaXNyb3V0ZWQgcmVxdWVzdHMpLlxuICAgKlxuICAgKiBUbyBhdm9pZCBjcmFzaGluZyBjb25zdW1lciBhcHBzLCB3ZSBhbHdheXMgcmVxdWVzdCBhcyB0ZXh0IGFuZCB0aGVuIHBhcnNlXG4gICAqIEpTT04gb25seSB3aGVuIHRoZSByZXNwb25zZSBhY3R1YWxseSBsb29rcyBsaWtlIEpTT04uXG4gICAqXG4gICAqIEBwYXJhbSBib2R5VGV4dCAtIFJhdyByZXNwb25zZSBib2R5IGFzIHRleHRcbiAgICogQHBhcmFtIGNvbnRlbnRUeXBlIC0gQ29udGVudC1UeXBlIGhlYWRlciB2YWx1ZSAoaWYgYXZhaWxhYmxlKVxuICAgKiBAcmV0dXJucyBQYXJzZWQgSlNPTiB2YWx1ZSAodW5rbm93bilcbiAgICogQHRocm93cyB7U3ludGF4RXJyb3J9IFdoZW4gYm9keSBpcyBub24tZW1wdHkgYnV0IG5vdCB2YWxpZCBKU09OXG4gICAqL1xuICBwcml2YXRlIHBhcnNlSnNvbkJvZHkoYm9keVRleHQ6IHN0cmluZywgY29udGVudFR5cGU6IHN0cmluZyB8IG51bGwpOiB1bmtub3duIHtcbiAgICBjb25zdCB0cmltbWVkID0gYm9keVRleHQudHJpbSgpO1xuICAgIGlmICghdHJpbW1lZCkgcmV0dXJuIG51bGw7XG5cbiAgICAvLyBJZiBpdCdzIGNsZWFybHkgSFRNTCwgbmV2ZXIgYXR0ZW1wdCBKU09OLnBhcnNlIChzb21lIHByb3hpZXMgbWlzbGFiZWwgQ29udGVudC1UeXBlKS5cbiAgICBpZiAodHJpbW1lZC5zdGFydHNXaXRoKCc8JykpIHtcbiAgICAgIHJldHVybiBib2R5VGV4dDtcbiAgICB9XG5cbiAgICBjb25zdCBsb29rc0xpa2VKc29uID0gdHJpbW1lZC5zdGFydHNXaXRoKCd7JykgfHwgdHJpbW1lZC5zdGFydHNXaXRoKCdbJyk7XG4gICAgY29uc3QgaXNKc29uQ29udGVudFR5cGUgPSB0eXBlb2YgY29udGVudFR5cGUgPT09ICdzdHJpbmcnICYmIGNvbnRlbnRUeXBlLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL2pzb24nKTtcblxuICAgIGlmICghbG9va3NMaWtlSnNvbiAmJiAhaXNKc29uQ29udGVudFR5cGUpIHtcbiAgICAgIC8vIFJldHVybiByYXcgdGV4dCB3aGVuIGl0IGRvZXNuJ3QgbG9vayBsaWtlIEpTT04gKGUuZy4sIEhUTUwgZXJyb3IgcGFnZXMpLlxuICAgICAgcmV0dXJuIGJvZHlUZXh0O1xuICAgIH1cblxuICAgIHJldHVybiBKU09OLnBhcnNlKHRyaW1tZWQpIGFzIHVua25vd247XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBIVFRQIHJlcXVlc3QgdXNpbmcgQW5ndWxhcidzIEh0dHBDbGllbnQuXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBSZXF1ZXN0IGNvbmZpZ3VyYXRpb25cbiAgICogQHJldHVybnMgUmVzcG9uc2Ugd2l0aCBwYXJzZWQgZGF0YVxuICAgKiBAdGhyb3dzIE5BdXRoQ2xpZW50RXJyb3IgaWYgcmVxdWVzdCBmYWlsc1xuICAgKi9cbiAgYXN5bmMgcmVxdWVzdDxUPihjb25maWc6IEh0dHBSZXF1ZXN0KTogUHJvbWlzZTxIdHRwUmVzcG9uc2U8VD4+IHtcbiAgICB0cnkge1xuICAgICAgLy8gVXNlIEFuZ3VsYXIncyBIdHRwQ2xpZW50IC0gZ29lcyB0aHJvdWdoIEFMTCBpbnRlcmNlcHRvcnMuXG4gICAgICAvLyBJTVBPUlRBTlQ6IFVzZSByZXNwb25zZVR5cGUgJ3RleHQnIHRvIGF2b2lkIHJhdyBKU09OLnBhcnNlIGNyYXNoZXMgd2hlblxuICAgICAgLy8gdGhlIGJhY2tlbmQgcmV0dXJucyBIVE1MIChzZWVuIGluIHNvbWUgcHJveHkvU1NSL21pc3JvdXRlIHNldHVwcykuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbShcbiAgICAgICAgdGhpcy5odHRwLnJlcXVlc3QoY29uZmlnLm1ldGhvZCwgY29uZmlnLnVybCwge1xuICAgICAgICAgIGJvZHk6IGNvbmZpZy5ib2R5LFxuICAgICAgICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgICAgICAgIHdpdGhDcmVkZW50aWFsczogY29uZmlnLmNyZWRlbnRpYWxzID09PSAnaW5jbHVkZScsXG4gICAgICAgICAgb2JzZXJ2ZTogJ3Jlc3BvbnNlJyxcbiAgICAgICAgICByZXNwb25zZVR5cGU6ICd0ZXh0JyxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBjb25zdCBjb250ZW50VHlwZSA9IHJlcy5oZWFkZXJzPy5nZXQoJ2NvbnRlbnQtdHlwZScpO1xuICAgICAgY29uc3QgcGFyc2VkID0gdGhpcy5wYXJzZUpzb25Cb2R5KHJlcy5ib2R5ID8/ICcnLCBjb250ZW50VHlwZSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGE6IHBhcnNlZCBhcyBULFxuICAgICAgICBzdGF0dXM6IHJlcy5zdGF0dXMsXG4gICAgICAgIGhlYWRlcnM6IHt9LCAvLyBSZXNlcnZlZCBmb3IgZnV0dXJlIGhlYWRlciBwYXNzdGhyb3VnaCBpZiBuZWVkZWRcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEh0dHBFcnJvclJlc3BvbnNlKSB7XG4gICAgICAgIC8vIENvbnZlcnQgQW5ndWxhcidzIEh0dHBFcnJvclJlc3BvbnNlIHRvIE5BdXRoQ2xpZW50RXJyb3IuXG4gICAgICAgIC8vIFdoZW4gdXNpbmcgcmVzcG9uc2VUeXBlICd0ZXh0JywgYGVycm9yLmVycm9yYCBpcyB0eXBpY2FsbHkgYSBzdHJpbmcuXG4gICAgICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gZXJyb3IuaGVhZGVycz8uZ2V0KCdjb250ZW50LXR5cGUnKSA/PyBudWxsO1xuICAgICAgICBjb25zdCByYXdCb2R5ID0gdHlwZW9mIGVycm9yLmVycm9yID09PSAnc3RyaW5nJyA/IGVycm9yLmVycm9yIDogJyc7XG4gICAgICAgIGNvbnN0IHBhcnNlZEVycm9yID0gdGhpcy5wYXJzZUpzb25Cb2R5KHJhd0JvZHksIGNvbnRlbnRUeXBlKTtcblxuICAgICAgICBjb25zdCBlcnJvckRhdGEgPSB0eXBlb2YgcGFyc2VkRXJyb3IgPT09ICdvYmplY3QnICYmIHBhcnNlZEVycm9yICE9PSBudWxsID8gKHBhcnNlZEVycm9yIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA6IHt9O1xuICAgICAgICBjb25zdCBjb2RlID0gdHlwZW9mIGVycm9yRGF0YVsnY29kZSddID09PSAnc3RyaW5nJyA/IChlcnJvckRhdGFbJ2NvZGUnXSBhcyBOQXV0aEVycm9yQ29kZSkgOiBOQXV0aEVycm9yQ29kZS5JTlRFUk5BTF9FUlJPUjtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9XG4gICAgICAgICAgdHlwZW9mIGVycm9yRGF0YVsnbWVzc2FnZSddID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgPyAoZXJyb3JEYXRhWydtZXNzYWdlJ10gYXMgc3RyaW5nKVxuICAgICAgICAgICAgOiB0eXBlb2YgcGFyc2VkRXJyb3IgPT09ICdzdHJpbmcnICYmIHBhcnNlZEVycm9yLnRyaW0oKVxuICAgICAgICAgICAgICA/IHBhcnNlZEVycm9yXG4gICAgICAgICAgICAgIDogZXJyb3IubWVzc2FnZSB8fCBgUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgJHtlcnJvci5zdGF0dXN9YDtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gdHlwZW9mIGVycm9yRGF0YVsndGltZXN0YW1wJ10gPT09ICdzdHJpbmcnID8gKGVycm9yRGF0YVsndGltZXN0YW1wJ10gYXMgc3RyaW5nKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgZGV0YWlscyA9IHR5cGVvZiBlcnJvckRhdGFbJ2RldGFpbHMnXSA9PT0gJ29iamVjdCcgPyAoZXJyb3JEYXRhWydkZXRhaWxzJ10gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIHRocm93IG5ldyBOQXV0aENsaWVudEVycm9yKGNvZGUsIG1lc3NhZ2UsIHtcbiAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXMsXG4gICAgICAgICAgdGltZXN0YW1wLFxuICAgICAgICAgIGRldGFpbHMsXG4gICAgICAgICAgaXNOZXR3b3JrRXJyb3I6IGVycm9yLnN0YXR1cyA9PT0gMCwgLy8gTmV0d29yayBlcnJvciAobm8gcmVzcG9uc2UgZnJvbSBzZXJ2ZXIpXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBSZS10aHJvdyBub24tSFRUUCBlcnJvcnMgYXMgYW4gU0RLIGVycm9yIHNvIGNvbnN1bWVycyBkb24ndCBzZWUgcmF3IHBhcnNlciBjcmFzaGVzLlxuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InO1xuICAgICAgdGhyb3cgbmV3IE5BdXRoQ2xpZW50RXJyb3IoTkF1dGhFcnJvckNvZGUuSU5URVJOQUxfRVJST1IsIG1lc3NhZ2UsIHtcbiAgICAgICAgc3RhdHVzQ29kZTogMCxcbiAgICAgICAgaXNOZXR3b3JrRXJyb3I6IHRydWUsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -39,6 +39,37 @@ class AngularHttpAdapter {
|
|
|
39
39
|
constructor(http) {
|
|
40
40
|
this.http = http;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Safely parse a JSON response body.
|
|
44
|
+
*
|
|
45
|
+
* Angular's fetch backend (`withFetch()`) will throw a raw `SyntaxError` if
|
|
46
|
+
* `responseType: 'json'` is used and the backend returns HTML (common for
|
|
47
|
+
* proxies, 502 pages, SSR fallbacks, or misrouted requests).
|
|
48
|
+
*
|
|
49
|
+
* To avoid crashing consumer apps, we always request as text and then parse
|
|
50
|
+
* JSON only when the response actually looks like JSON.
|
|
51
|
+
*
|
|
52
|
+
* @param bodyText - Raw response body as text
|
|
53
|
+
* @param contentType - Content-Type header value (if available)
|
|
54
|
+
* @returns Parsed JSON value (unknown)
|
|
55
|
+
* @throws {SyntaxError} When body is non-empty but not valid JSON
|
|
56
|
+
*/
|
|
57
|
+
parseJsonBody(bodyText, contentType) {
|
|
58
|
+
const trimmed = bodyText.trim();
|
|
59
|
+
if (!trimmed)
|
|
60
|
+
return null;
|
|
61
|
+
// If it's clearly HTML, never attempt JSON.parse (some proxies mislabel Content-Type).
|
|
62
|
+
if (trimmed.startsWith('<')) {
|
|
63
|
+
return bodyText;
|
|
64
|
+
}
|
|
65
|
+
const looksLikeJson = trimmed.startsWith('{') || trimmed.startsWith('[');
|
|
66
|
+
const isJsonContentType = typeof contentType === 'string' && contentType.toLowerCase().includes('application/json');
|
|
67
|
+
if (!looksLikeJson && !isJsonContentType) {
|
|
68
|
+
// Return raw text when it doesn't look like JSON (e.g., HTML error pages).
|
|
69
|
+
return bodyText;
|
|
70
|
+
}
|
|
71
|
+
return JSON.parse(trimmed);
|
|
72
|
+
}
|
|
42
73
|
/**
|
|
43
74
|
* Execute HTTP request using Angular's HttpClient.
|
|
44
75
|
*
|
|
@@ -48,29 +79,40 @@ class AngularHttpAdapter {
|
|
|
48
79
|
*/
|
|
49
80
|
async request(config) {
|
|
50
81
|
try {
|
|
51
|
-
// Use Angular's HttpClient - goes through ALL interceptors
|
|
52
|
-
|
|
82
|
+
// Use Angular's HttpClient - goes through ALL interceptors.
|
|
83
|
+
// IMPORTANT: Use responseType 'text' to avoid raw JSON.parse crashes when
|
|
84
|
+
// the backend returns HTML (seen in some proxy/SSR/misroute setups).
|
|
85
|
+
const res = await firstValueFrom(this.http.request(config.method, config.url, {
|
|
53
86
|
body: config.body,
|
|
54
87
|
headers: config.headers,
|
|
55
88
|
withCredentials: config.credentials === 'include',
|
|
56
|
-
observe: '
|
|
89
|
+
observe: 'response',
|
|
90
|
+
responseType: 'text',
|
|
57
91
|
}));
|
|
92
|
+
const contentType = res.headers?.get('content-type');
|
|
93
|
+
const parsed = this.parseJsonBody(res.body ?? '', contentType);
|
|
58
94
|
return {
|
|
59
|
-
data,
|
|
60
|
-
status:
|
|
61
|
-
headers: {}, //
|
|
95
|
+
data: parsed,
|
|
96
|
+
status: res.status,
|
|
97
|
+
headers: {}, // Reserved for future header passthrough if needed
|
|
62
98
|
};
|
|
63
99
|
}
|
|
64
100
|
catch (error) {
|
|
65
101
|
if (error instanceof HttpErrorResponse) {
|
|
66
|
-
// Convert Angular's HttpErrorResponse to NAuthClientError
|
|
67
|
-
|
|
68
|
-
const
|
|
102
|
+
// Convert Angular's HttpErrorResponse to NAuthClientError.
|
|
103
|
+
// When using responseType 'text', `error.error` is typically a string.
|
|
104
|
+
const contentType = error.headers?.get('content-type') ?? null;
|
|
105
|
+
const rawBody = typeof error.error === 'string' ? error.error : '';
|
|
106
|
+
const parsedError = this.parseJsonBody(rawBody, contentType);
|
|
107
|
+
const errorData = typeof parsedError === 'object' && parsedError !== null ? parsedError : {};
|
|
108
|
+
const code = typeof errorData['code'] === 'string' ? errorData['code'] : NAuthErrorCode.INTERNAL_ERROR;
|
|
69
109
|
const message = typeof errorData['message'] === 'string'
|
|
70
|
-
? errorData
|
|
71
|
-
:
|
|
72
|
-
|
|
73
|
-
|
|
110
|
+
? errorData['message']
|
|
111
|
+
: typeof parsedError === 'string' && parsedError.trim()
|
|
112
|
+
? parsedError
|
|
113
|
+
: error.message || `Request failed with status ${error.status}`;
|
|
114
|
+
const timestamp = typeof errorData['timestamp'] === 'string' ? errorData['timestamp'] : undefined;
|
|
115
|
+
const details = typeof errorData['details'] === 'object' ? errorData['details'] : undefined;
|
|
74
116
|
throw new NAuthClientError(code, message, {
|
|
75
117
|
statusCode: error.status,
|
|
76
118
|
timestamp,
|
|
@@ -78,8 +120,12 @@ class AngularHttpAdapter {
|
|
|
78
120
|
isNetworkError: error.status === 0, // Network error (no response from server)
|
|
79
121
|
});
|
|
80
122
|
}
|
|
81
|
-
// Re-throw non-HTTP errors
|
|
82
|
-
|
|
123
|
+
// Re-throw non-HTTP errors as an SDK error so consumers don't see raw parser crashes.
|
|
124
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
125
|
+
throw new NAuthClientError(NAuthErrorCode.INTERNAL_ERROR, message, {
|
|
126
|
+
statusCode: 0,
|
|
127
|
+
isNetworkError: true,
|
|
128
|
+
});
|
|
83
129
|
}
|
|
84
130
|
}
|
|
85
131
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AngularHttpAdapter, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|