@qaick/http-executor 0.1.0-alpha.9 → 0.2.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.
@@ -83,6 +83,7 @@ export class HttpActionExecutor {
83
83
  if (typeof responseHeadersName === 'string')
84
84
  outputs[responseHeadersName] = response.headers ?? {};
85
85
  if (response.status < 200 || response.status >= 300) {
86
+ debugFailedRequest(request, response.status);
86
87
  throw new HttpActionError('HTTP_STATUS_ERROR', `HTTP Action returned status ${response.status}. ${requestDiagnostics(request, response)}`, { status: response.status });
87
88
  }
88
89
  const responseFields = isRecord(context.step.adapterConfig?.responseFields) ? context.step.adapterConfig.responseFields : undefined;
@@ -100,7 +101,12 @@ function requestDiagnostics(request, response) {
100
101
  const parsed = tryParseUrl(request.url);
101
102
  const body = request.body === undefined ? undefined : typeof request.body === 'string' ? request.body : JSON.stringify(request.body) ?? '';
102
103
  const responseBody = typeof response.body === 'string' ? response.body : JSON.stringify(response.body) ?? '';
103
- return `Request diagnostics: method=${request.method} path=${parsed?.pathname ?? '(invalid)'} bodyBytes=${byteLength(body)} requestHeaderNames=${headerNames(request.headers).join(',') || '(none)'} responseHeaderNames=${headerNames(response.headers).join(',') || '(none)'} responseBodyBytes=${byteLength(responseBody)}.`;
104
+ return `Request diagnostics: method=${request.method} path=${parsed?.pathname ?? '(invalid)'} bodyBytes=${byteLength(body)} requestHeaderNames=${headerNames(request.headers).join(',') || '(none)'} requestCookieNames=${cookieNames(request.headers).join(',') || '(none)'} requestCookieValueLengths=${cookieValueLengths(request.headers) || '(none)'} requestAuthHeaderLengths=${authHeaderLengths(request.headers) || '(none)'} responseHeaderNames=${headerNames(response.headers).join(',') || '(none)'} responseBodyBytes=${byteLength(responseBody)}.`;
105
+ }
106
+ function debugFailedRequest(request, status) {
107
+ if (typeof process === 'undefined' || process.env.QAICK_HTTP_DEBUG_FULL_REQUEST !== '1')
108
+ return;
109
+ console.error('[QAICK_HTTP_DEBUG_FULL_REQUEST]', { status, request });
104
110
  }
105
111
  function tryParseUrl(value) {
106
112
  try {
@@ -116,6 +122,20 @@ function headerNames(headers) {
116
122
  function byteLength(value) {
117
123
  return value === undefined ? 0 : new TextEncoder().encode(value).byteLength;
118
124
  }
125
+ function cookieNames(headers) {
126
+ const cookie = Object.entries(headers ?? {}).find(([name]) => name.toLowerCase() === 'cookie')?.[1];
127
+ return cookie ? cookie.split(';').map(item => item.trim().split('=', 1)[0]).filter(Boolean) : [];
128
+ }
129
+ function cookieValueLengths(headers) {
130
+ const cookie = Object.entries(headers ?? {}).find(([name]) => name.toLowerCase() === 'cookie')?.[1];
131
+ return cookie ? cookie.split(';').map(item => item.trim()).filter(Boolean).map(item => {
132
+ const separator = item.indexOf('=');
133
+ return separator > 0 ? `${item.slice(0, separator)}:${item.length - separator - 1}` : `${item}:0`;
134
+ }).join(',') : '';
135
+ }
136
+ function authHeaderLengths(headers) {
137
+ return Object.entries(headers ?? {}).filter(([name]) => ['x-auth-token', 'x-xsrf-token'].includes(name.toLowerCase())).map(([name, value]) => `${name.toLowerCase()}:${value.length}`).join(',');
138
+ }
119
139
  function responseCookies(headers) {
120
140
  const raw = headers && Object.entries(headers).find(([name]) => name.toLowerCase() === 'set-cookie')?.[1];
121
141
  const values = Array.isArray(raw) ? raw : raw ? raw.split(/\r?\n|,(?=\s*[^;,=\s]+=[^;,]*)/).map(item => item.trim()).filter(Boolean) : [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qaick/http-executor",
3
- "version": "0.1.0-alpha.9",
3
+ "version": "0.2.0",
4
4
  "description": "Reusable QAick HTTP Action execution with browser and native Node transports.",
5
5
  "keywords": [
6
6
  "qaick",
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "publishConfig": {
20
20
  "access": "public",
21
- "tag": "alpha"
21
+ "tag": "latest"
22
22
  },
23
23
  "main": "./dist/index.js",
24
24
  "types": "./dist/index.d.ts",
@@ -39,10 +39,10 @@
39
39
  "prepublishOnly": "npm run build"
40
40
  },
41
41
  "peerDependencies": {
42
- "@qaick/executor": ">=0.1.0-alpha.1 <0.2.0"
42
+ "@qaick/executor": "0.2.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@qaick/executor": "0.1.0-alpha.2",
45
+ "@qaick/executor": "0.2.0",
46
46
  "@types/node": "^24.13.3",
47
47
  "typescript": "~6.0.2",
48
48
  "vitest": "^5.0.1"