norn-cli 2.4.0 → 2.6.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.
Files changed (96) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +26 -1
  3. package/dist/cli.js +330 -85
  4. package/package.json +24 -5
  5. package/schemas/norn.config.schema.json +43 -1
  6. package/scripts/__pycache__/reddit_signal_miner.cpython-312.pyc +0 -0
  7. package/scripts/reddit_signal_miner.py +482 -0
  8. package/.claude/settings.local.json +0 -18
  9. package/.claude/skills/norn-social-campaign/SKILL.md +0 -70
  10. package/out/apiResponseIntellisenseCache.js +0 -394
  11. package/out/assertionRunner.js +0 -567
  12. package/out/cacheDir.js +0 -136
  13. package/out/chatParticipant.js +0 -763
  14. package/out/cli/colors.js +0 -127
  15. package/out/cli/formatters/assertion.js +0 -102
  16. package/out/cli/formatters/index.js +0 -23
  17. package/out/cli/formatters/response.js +0 -106
  18. package/out/cli/formatters/summary.js +0 -246
  19. package/out/cli/redaction.js +0 -237
  20. package/out/cli/reporters/html.js +0 -689
  21. package/out/cli/reporters/index.js +0 -22
  22. package/out/cli/reporters/junit.js +0 -226
  23. package/out/codeLensProvider.js +0 -351
  24. package/out/compareContentProvider.js +0 -85
  25. package/out/completionProvider.js +0 -3739
  26. package/out/contractAssertionSummary.js +0 -225
  27. package/out/contractDecorationProvider.js +0 -243
  28. package/out/coverageCalculator.js +0 -879
  29. package/out/coveragePanel.js +0 -597
  30. package/out/debug/breakpointResolver.js +0 -84
  31. package/out/debug/breakpoints.js +0 -52
  32. package/out/debug/nornDebugAdapter.js +0 -166
  33. package/out/debug/nornDebugSession.js +0 -613
  34. package/out/debug/sequenceLocationIndex.js +0 -77
  35. package/out/debug/types.js +0 -3
  36. package/out/deepClone.js +0 -21
  37. package/out/diagnosticProvider.js +0 -2554
  38. package/out/environmentParser.js +0 -736
  39. package/out/environmentProvider.js +0 -544
  40. package/out/environmentTemplates.js +0 -146
  41. package/out/errors/formatError.js +0 -113
  42. package/out/errors/nornError.js +0 -29
  43. package/out/formUrlEncoded.js +0 -89
  44. package/out/httpClient.js +0 -348
  45. package/out/httpRuntimeOptions.js +0 -16
  46. package/out/importErrors.js +0 -31
  47. package/out/inlayHintResolver.js +0 -70
  48. package/out/jsonFileReader.js +0 -323
  49. package/out/mcpClient.js +0 -193
  50. package/out/mcpConfig.js +0 -184
  51. package/out/mcpToolIntellisenseCache.js +0 -96
  52. package/out/mcpToolSchema.js +0 -50
  53. package/out/nornConfig.js +0 -132
  54. package/out/nornHoverProvider.js +0 -124
  55. package/out/nornInlayHintsProvider.js +0 -191
  56. package/out/nornPrompt.js +0 -755
  57. package/out/nornSqlParser.js +0 -286
  58. package/out/nornapiHoverProvider.js +0 -135
  59. package/out/nornapiInlayHintsProvider.js +0 -94
  60. package/out/nornapiParser.js +0 -324
  61. package/out/nornenvCodeActionProvider.js +0 -101
  62. package/out/nornenvDecorationProvider.js +0 -239
  63. package/out/nornenvFoldingProvider.js +0 -63
  64. package/out/nornenvHoverProvider.js +0 -114
  65. package/out/nornenvInlayHintsProvider.js +0 -99
  66. package/out/nornenvLanguageModel.js +0 -187
  67. package/out/nornenvRegionRefactor.js +0 -267
  68. package/out/nornsqlHoverProvider.js +0 -95
  69. package/out/nornsqlInlayHintsProvider.js +0 -114
  70. package/out/parser.js +0 -839
  71. package/out/pathAccess.js +0 -28
  72. package/out/postmanImportPanel.js +0 -732
  73. package/out/postmanImportPlanner.js +0 -1155
  74. package/out/postmanImportSidebarView.js +0 -532
  75. package/out/quotedString.js +0 -35
  76. package/out/requestPreparation.js +0 -179
  77. package/out/requestValidation.js +0 -146
  78. package/out/responsePanel.js +0 -7754
  79. package/out/schemaGenerator.js +0 -562
  80. package/out/scriptRunner.js +0 -419
  81. package/out/secrets/cliSecrets.js +0 -415
  82. package/out/secrets/crypto.js +0 -105
  83. package/out/secrets/envFileSecrets.js +0 -177
  84. package/out/secrets/keyStore.js +0 -259
  85. package/out/sequenceDeclaration.js +0 -15
  86. package/out/sequenceRunner.js +0 -3590
  87. package/out/sqlAdapterRunner.js +0 -122
  88. package/out/sqlBuiltInAdapters.js +0 -604
  89. package/out/sqlConfig.js +0 -184
  90. package/out/starterCatalog.js +0 -554
  91. package/out/stringUtils.js +0 -25
  92. package/out/swaggerBodyIntellisenseCache.js +0 -114
  93. package/out/swaggerParser.js +0 -464
  94. package/out/testProvider.js +0 -767
  95. package/out/theoryCaseLoader.js +0 -113
  96. package/out/validationCache.js +0 -211
@@ -1,113 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatUserFacingError = formatUserFacingError;
4
- const nornError_1 = require("./nornError");
5
- function mergeContext(base, overrides) {
6
- if (!base && !overrides) {
7
- return undefined;
8
- }
9
- return {
10
- ...(base || {}),
11
- ...(overrides || {}),
12
- environment: {
13
- ...(base?.environment || {}),
14
- ...(overrides?.environment || {})
15
- }
16
- };
17
- }
18
- function normalizeKnownError(error, context) {
19
- if ((0, nornError_1.isNornError)(error)) {
20
- if (!context) {
21
- return error;
22
- }
23
- return new nornError_1.NornError({
24
- category: error.category,
25
- code: error.code,
26
- message: error.message,
27
- hint: error.hint,
28
- details: error.details,
29
- context: mergeContext(error.context, context),
30
- cause: error.cause
31
- });
32
- }
33
- if (error instanceof Error) {
34
- const msg = error.message || String(error);
35
- if (msg === 'No valid HTTP method found') {
36
- return new nornError_1.NornError({
37
- category: 'syntax',
38
- code: 'request-missing-method',
39
- message: 'Could not parse request: no valid HTTP method found.',
40
- hint: 'Start the request with a valid HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS).',
41
- context: mergeContext(undefined, context)
42
- });
43
- }
44
- if (msg.startsWith('Unknown endpoint: ')) {
45
- const endpointName = msg.slice('Unknown endpoint: '.length).trim();
46
- return new nornError_1.NornError({
47
- category: 'validation',
48
- code: 'unknown-endpoint',
49
- message: `Unknown endpoint '${endpointName}'.`,
50
- hint: 'Import a .nornapi file that defines this endpoint, or fix the endpoint name.',
51
- context: mergeContext(undefined, context)
52
- });
53
- }
54
- if (/invalid url/i.test(msg) || /unsupported protocol/i.test(msg)) {
55
- return new nornError_1.NornError({
56
- category: 'url',
57
- code: 'invalid-url',
58
- message: `Invalid request URL.`,
59
- details: msg,
60
- hint: 'Check the request URL and any substituted variables (for example {{baseUrl}}).',
61
- context: mergeContext(undefined, context)
62
- });
63
- }
64
- return error;
65
- }
66
- return new Error(String(error));
67
- }
68
- function formatUserFacingError(error, context) {
69
- const normalized = normalizeKnownError(error, context);
70
- if (!(0, nornError_1.isNornError)(normalized)) {
71
- if (normalized instanceof Error) {
72
- return normalized.message;
73
- }
74
- return String(normalized);
75
- }
76
- const lines = [normalized.message];
77
- const ctx = normalized.context;
78
- if (ctx?.stepIndex !== undefined) {
79
- lines.push(`Step: ${ctx.stepIndex}`);
80
- }
81
- if (ctx?.requestName) {
82
- lines.push(`Request: ${ctx.requestName}`);
83
- }
84
- else if (ctx?.method || ctx?.url) {
85
- const requestLine = [ctx.method, ctx.url].filter(Boolean).join(' ');
86
- if (requestLine) {
87
- lines.push(`Request: ${requestLine}`);
88
- }
89
- }
90
- if (ctx?.filePath) {
91
- lines.push(`File: ${ctx.filePath}`);
92
- }
93
- if (ctx?.environment) {
94
- const env = ctx.environment;
95
- if (env.hasEnvFile) {
96
- const active = env.activeEnvironment ?? 'none';
97
- const available = env.availableEnvironments?.length
98
- ? env.availableEnvironments.join(', ')
99
- : 'none';
100
- lines.push(`Environment: ${active} (available: ${available})`);
101
- }
102
- }
103
- if (normalized.details) {
104
- for (const detail of normalized.details) {
105
- lines.push(detail);
106
- }
107
- }
108
- if (normalized.hint) {
109
- lines.push(`Hint: ${normalized.hint}`);
110
- }
111
- return lines.join('\n');
112
- }
113
- //# sourceMappingURL=formatError.js.map
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NornError = void 0;
4
- exports.isNornError = isNornError;
5
- class NornError extends Error {
6
- category;
7
- code;
8
- hint;
9
- details;
10
- context;
11
- cause;
12
- constructor(options) {
13
- super(options.message);
14
- this.name = 'NornError';
15
- this.category = options.category;
16
- this.code = options.code;
17
- this.hint = options.hint;
18
- this.details = Array.isArray(options.details)
19
- ? options.details
20
- : options.details ? [options.details] : undefined;
21
- this.context = options.context;
22
- this.cause = options.cause;
23
- }
24
- }
25
- exports.NornError = NornError;
26
- function isNornError(error) {
27
- return error instanceof NornError;
28
- }
29
- //# sourceMappingURL=nornError.js.map
@@ -1,89 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isFormUrlEncodedContentType = isFormUrlEncodedContentType;
4
- exports.parseFormUrlEncodedLines = parseFormUrlEncodedLines;
5
- exports.parseFormUrlEncodedBody = parseFormUrlEncodedBody;
6
- exports.encodeFormUrlEncodedBody = encodeFormUrlEncodedBody;
7
- function parseEqualsField(segment) {
8
- const eqIndex = segment.indexOf('=');
9
- if (eqIndex <= 0) {
10
- return null;
11
- }
12
- return {
13
- key: segment.substring(0, eqIndex).trim(),
14
- value: segment.substring(eqIndex + 1).trim()
15
- };
16
- }
17
- function isFormUrlEncodedContentType(contentType) {
18
- return Boolean(contentType && contentType.toLowerCase().includes('application/x-www-form-urlencoded'));
19
- }
20
- function parseFormUrlEncodedLines(lines) {
21
- const fields = [];
22
- const errors = [];
23
- for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
24
- const line = lines[lineIndex].trim();
25
- if (!line) {
26
- continue;
27
- }
28
- const firstEqIndex = line.indexOf('=');
29
- const firstColonIndex = line.indexOf(':');
30
- if (firstEqIndex > 0 && (firstColonIndex === -1 || firstEqIndex < firstColonIndex)) {
31
- if (line.includes('&')) {
32
- const segments = line.split('&').map(segment => segment.trim());
33
- const hasInvalidSegment = segments.some(segment => !parseEqualsField(segment));
34
- if (hasInvalidSegment) {
35
- errors.push({
36
- lineIndex,
37
- line,
38
- message: 'Ampersand-delimited form body lines must use key=value for every segment.'
39
- });
40
- continue;
41
- }
42
- for (const segment of segments) {
43
- const field = parseEqualsField(segment);
44
- if (field) {
45
- fields.push(field);
46
- }
47
- }
48
- continue;
49
- }
50
- const field = parseEqualsField(line);
51
- if (field) {
52
- fields.push(field);
53
- continue;
54
- }
55
- }
56
- if (firstColonIndex > 0) {
57
- fields.push({
58
- key: line.substring(0, firstColonIndex).trim(),
59
- value: line.substring(firstColonIndex + 1).trim()
60
- });
61
- continue;
62
- }
63
- errors.push({
64
- lineIndex,
65
- line,
66
- message: 'Expected key=value, key: value, or ampersand-delimited key=value pairs.'
67
- });
68
- }
69
- return { fields, errors };
70
- }
71
- function parseFormUrlEncodedBody(body) {
72
- if (!body) {
73
- return { fields: [], errors: [] };
74
- }
75
- return parseFormUrlEncodedLines(body.split('\n'));
76
- }
77
- function encodeFormUrlEncodedBody(body) {
78
- const { fields, errors } = parseFormUrlEncodedBody(body);
79
- if (errors.length > 0) {
80
- return { encodedBody: '', errors };
81
- }
82
- return {
83
- encodedBody: fields
84
- .map(field => `${encodeURIComponent(field.key)}=${encodeURIComponent(field.value)}`)
85
- .join('&'),
86
- errors: []
87
- };
88
- }
89
- //# sourceMappingURL=formUrlEncoded.js.map
package/out/httpClient.js DELETED
@@ -1,348 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.createCookieJar = createCookieJar;
40
- exports.getSharedCookieJar = getSharedCookieJar;
41
- exports.clearCookies = clearCookies;
42
- exports.getCookiesForUrl = getCookiesForUrl;
43
- exports.getAllCookies = getAllCookies;
44
- exports.sendRequest = sendRequest;
45
- exports.sendRequestWithJar = sendRequestWithJar;
46
- const axios_1 = __importDefault(require("axios"));
47
- const https = __importStar(require("https"));
48
- const tough_cookie_1 = require("tough-cookie");
49
- const nornError_1 = require("./errors/nornError");
50
- const httpRuntimeOptions_1 = require("./httpRuntimeOptions");
51
- const formUrlEncoded_1 = require("./formUrlEncoded");
52
- // Shared cookie jar for VS Code extension (persists across requests)
53
- let sharedCookieJar = new tough_cookie_1.CookieJar();
54
- const insecureHttpsAgent = new https.Agent({ rejectUnauthorized: false });
55
- function getHttpsAgent() {
56
- return (0, httpRuntimeOptions_1.getVerifyTlsCertificates)() ? undefined : insecureHttpsAgent;
57
- }
58
- /**
59
- * Creates a fresh cookie jar for isolated execution (CLI, sequences)
60
- */
61
- function createCookieJar() {
62
- return new tough_cookie_1.CookieJar();
63
- }
64
- /**
65
- * Gets the shared cookie jar
66
- */
67
- function getSharedCookieJar() {
68
- return sharedCookieJar;
69
- }
70
- /**
71
- * Clears all cookies from the shared jar
72
- */
73
- function clearCookies() {
74
- sharedCookieJar = new tough_cookie_1.CookieJar();
75
- }
76
- /**
77
- * Gets all cookies from a jar for a specific URL
78
- */
79
- async function getCookiesForUrl(url, jar) {
80
- const targetJar = jar || sharedCookieJar;
81
- try {
82
- const cookies = await targetJar.getCookies(url);
83
- return cookies.map(cookieToInfo);
84
- }
85
- catch {
86
- return [];
87
- }
88
- }
89
- /**
90
- * Gets all cookies from a jar
91
- */
92
- async function getAllCookies(jar) {
93
- const targetJar = jar || sharedCookieJar;
94
- const serialized = await targetJar.serialize();
95
- return (serialized.cookies || []).map((c) => ({
96
- name: String(c.key || ''),
97
- value: String(c.value || ''),
98
- domain: String(c.domain || ''),
99
- path: String(c.path || '/'),
100
- expires: c.expires ? String(c.expires) : undefined,
101
- httpOnly: Boolean(c.httpOnly),
102
- secure: Boolean(c.secure),
103
- }));
104
- }
105
- function cookieToInfo(cookie) {
106
- return {
107
- name: cookie.key,
108
- value: cookie.value,
109
- domain: cookie.domain || '',
110
- path: cookie.path || '/',
111
- expires: cookie.expires instanceof Date ? cookie.expires.toISOString() : undefined,
112
- httpOnly: cookie.httpOnly || false,
113
- secure: cookie.secure || false,
114
- };
115
- }
116
- /**
117
- * Sends a request using the shared cookie jar (for VS Code extension)
118
- */
119
- async function sendRequest(request, retryOptions) {
120
- return sendRequestWithJar(request, sharedCookieJar, retryOptions);
121
- }
122
- /**
123
- * Helper function to wait
124
- */
125
- function sleep(ms) {
126
- return new Promise(resolve => setTimeout(resolve, ms));
127
- }
128
- /**
129
- * Check if a response indicates failure (should retry)
130
- * Retries on: network errors, 5xx server errors, 429 rate limit
131
- */
132
- function shouldRetry(response, error) {
133
- // Always retry on network errors
134
- if (error) {
135
- return true;
136
- }
137
- // Retry on server errors (5xx) or rate limiting (429)
138
- if (response && (response.status >= 500 || response.status === 429)) {
139
- return true;
140
- }
141
- return false;
142
- }
143
- /**
144
- * Sends a request using a specific cookie jar
145
- * Manually follows redirects to properly capture Set-Cookie headers at each step
146
- * Supports automatic retry with linear backoff
147
- */
148
- async function sendRequestWithJar(request, jar, retryOptions) {
149
- const totalAttempts = (retryOptions?.retryCount ?? 0) + 1; // +1 for initial attempt
150
- const backoffMs = retryOptions?.backoffMs ?? 1000;
151
- const retriedErrors = [];
152
- let lastError = null;
153
- let attemptsMade = 0;
154
- for (let attempt = 1; attempt <= totalAttempts; attempt++) {
155
- attemptsMade = attempt;
156
- const startTime = Date.now();
157
- const maxRedirects = 10;
158
- let redirectCount = 0;
159
- let currentUrl = request.url;
160
- let currentMethod = request.method;
161
- let currentBody = request.body;
162
- let finalResponse = null;
163
- let sentRequestBody = undefined;
164
- let sentRequestHeaders = {};
165
- try {
166
- while (redirectCount <= maxRedirects) {
167
- // Get cookies for current URL
168
- const existingCookies = await jar.getCookies(currentUrl);
169
- const cookieHeader = existingCookies.map(c => `${c.key}=${c.value}`).join('; ');
170
- const headers = { ...request.headers };
171
- if (cookieHeader) {
172
- headers['Cookie'] = cookieHeader;
173
- }
174
- // Determine how to send the body based on Content-Type
175
- let data = undefined;
176
- if (currentBody) {
177
- const contentType = Object.keys(headers).find((key) => key.toLowerCase() === 'content-type');
178
- const contentTypeValue = contentType ? headers[contentType] : '';
179
- if ((0, formUrlEncoded_1.isFormUrlEncodedContentType)(contentTypeValue)) {
180
- const encoded = (0, formUrlEncoded_1.encodeFormUrlEncodedBody)(currentBody);
181
- if (encoded.errors.length > 0) {
182
- throw new nornError_1.NornError({
183
- category: 'syntax',
184
- code: 'invalid-form-urlencoded-body',
185
- message: 'Request body is not valid application/x-www-form-urlencoded syntax.',
186
- details: encoded.errors.map(error => `Body line ${error.lineIndex + 1}: ${error.message} (${error.line})`),
187
- hint: 'Use key=value, key: value, or a single line like key1=value1&key2=value2.',
188
- context: {
189
- source: 'httpClient',
190
- method: currentMethod,
191
- url: currentUrl
192
- }
193
- });
194
- }
195
- data = encoded.encodedBody;
196
- }
197
- else if (contentTypeValue.includes('application/json')) {
198
- try {
199
- data = JSON.parse(currentBody);
200
- }
201
- catch {
202
- data = currentBody;
203
- }
204
- }
205
- else {
206
- try {
207
- data = JSON.parse(currentBody);
208
- }
209
- catch {
210
- data = currentBody;
211
- }
212
- }
213
- }
214
- // Capture what we're actually sending (for debugging)
215
- sentRequestBody = data;
216
- sentRequestHeaders = { ...headers };
217
- const response = await (0, axios_1.default)({
218
- method: currentMethod,
219
- url: currentUrl,
220
- adapter: 'http',
221
- headers,
222
- data,
223
- timeout: 30000,
224
- maxRedirects: 0,
225
- validateStatus: () => true,
226
- httpsAgent: getHttpsAgent(),
227
- });
228
- // Store any Set-Cookie headers in the jar
229
- const setCookieHeader = response.headers['set-cookie'];
230
- if (setCookieHeader) {
231
- const cookies = Array.isArray(setCookieHeader) ? setCookieHeader : [setCookieHeader];
232
- for (const cookieStr of cookies) {
233
- try {
234
- await jar.setCookie(cookieStr, currentUrl);
235
- }
236
- catch {
237
- // Ignore invalid cookies
238
- }
239
- }
240
- }
241
- // Check if this is a redirect
242
- if (response.status >= 300 && response.status < 400 && response.headers['location']) {
243
- redirectCount++;
244
- const location = response.headers['location'];
245
- currentUrl = new URL(location, currentUrl).toString();
246
- if (currentMethod !== 'GET' && currentMethod !== 'HEAD') {
247
- currentMethod = 'GET';
248
- currentBody = undefined;
249
- }
250
- continue;
251
- }
252
- finalResponse = response;
253
- break;
254
- }
255
- if (!finalResponse) {
256
- throw new Error('Too many redirects');
257
- }
258
- // Check if we should retry on this response status
259
- if (shouldRetry(finalResponse, null) && attempt < totalAttempts) {
260
- const waitMs = backoffMs * attempt; // Linear backoff
261
- const errorMessage = `HTTP ${finalResponse.status} ${finalResponse.statusText}`;
262
- retriedErrors.push(`Attempt ${attempt}: ${errorMessage}`);
263
- // Call retry callback if provided
264
- if (retryOptions?.onRetry) {
265
- retryOptions.onRetry(attempt, totalAttempts, errorMessage, waitMs);
266
- }
267
- await sleep(waitMs);
268
- continue;
269
- }
270
- // Get ALL cookies in the jar
271
- const cookies = await getAllCookies(jar);
272
- const result = {
273
- status: finalResponse.status,
274
- statusText: finalResponse.statusText,
275
- headers: finalResponse.headers,
276
- body: finalResponse.data,
277
- duration: Date.now() - startTime,
278
- cookies,
279
- requestBody: sentRequestBody,
280
- requestHeaders: sentRequestHeaders,
281
- };
282
- // Add retry info if we made retries
283
- if (attemptsMade > 1 || totalAttempts > 1) {
284
- result.retryInfo = {
285
- attemptsMade,
286
- totalAttempts,
287
- retriedErrors,
288
- };
289
- }
290
- return result;
291
- }
292
- catch (error) {
293
- const errorMessage = error.message || String(error);
294
- const effectiveUrl = currentUrl || request.url;
295
- const isUrlError = /invalid url/i.test(errorMessage) || /unsupported protocol/i.test(errorMessage);
296
- const isAxiosNetworkError = Boolean(error?.isAxiosError) && !error?.response;
297
- if (isUrlError) {
298
- lastError = new nornError_1.NornError({
299
- category: 'url',
300
- code: 'http-invalid-url',
301
- message: `Invalid request URL: ${effectiveUrl}`,
302
- details: errorMessage,
303
- hint: 'Check the URL and any variables used to build it before sending the request.',
304
- context: {
305
- source: 'httpClient',
306
- method: currentMethod,
307
- url: effectiveUrl,
308
- },
309
- cause: error,
310
- });
311
- }
312
- else if (isAxiosNetworkError) {
313
- lastError = new nornError_1.NornError({
314
- category: 'network',
315
- code: 'http-network-error',
316
- message: `Network request failed.`,
317
- details: [`${errorMessage}`, `URL used: ${effectiveUrl}`],
318
- hint: 'Check connectivity, DNS/host availability, TLS settings, and the request URL.',
319
- context: {
320
- source: 'httpClient',
321
- method: currentMethod,
322
- url: effectiveUrl,
323
- },
324
- cause: error,
325
- });
326
- }
327
- else {
328
- lastError = new Error(`${errorMessage}\nURL used: ${effectiveUrl}`);
329
- }
330
- // If we have more attempts, wait and retry
331
- if (attempt < totalAttempts) {
332
- const waitMs = backoffMs * attempt; // Linear backoff
333
- retriedErrors.push(`Attempt ${attempt}: ${errorMessage}`);
334
- // Call retry callback if provided
335
- if (retryOptions?.onRetry) {
336
- retryOptions.onRetry(attempt, totalAttempts, errorMessage, waitMs);
337
- }
338
- await sleep(waitMs);
339
- continue;
340
- }
341
- // No more retries, throw the error
342
- throw lastError;
343
- }
344
- }
345
- // Should never reach here, but TypeScript needs this
346
- throw lastError || new Error('Request failed');
347
- }
348
- //# sourceMappingURL=httpClient.js.map
@@ -1,16 +0,0 @@
1
- "use strict";
2
- /**
3
- * Shared runtime HTTP options for extension + CLI execution paths.
4
- * Keep this module Node-only (no VS Code imports).
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.setVerifyTlsCertificates = setVerifyTlsCertificates;
8
- exports.getVerifyTlsCertificates = getVerifyTlsCertificates;
9
- let verifyTlsCertificates = true;
10
- function setVerifyTlsCertificates(enabled) {
11
- verifyTlsCertificates = enabled;
12
- }
13
- function getVerifyTlsCertificates() {
14
- return verifyTlsCertificates;
15
- }
16
- //# sourceMappingURL=httpRuntimeOptions.js.map
@@ -1,31 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isBlockingImportError = isBlockingImportError;
4
- exports.getBlockingImportErrors = getBlockingImportErrors;
5
- exports.splitImportResolutionErrors = splitImportResolutionErrors;
6
- const BLOCKING_IMPORT_ERROR_MARKERS = [
7
- 'Duplicate header group',
8
- 'Duplicate endpoint',
9
- 'Duplicate named request',
10
- 'Duplicate sequence',
11
- ];
12
- function isBlockingImportError(error) {
13
- return Boolean(error.blocking) || BLOCKING_IMPORT_ERROR_MARKERS.some(marker => error.error.includes(marker));
14
- }
15
- function getBlockingImportErrors(errors) {
16
- return errors.filter(isBlockingImportError);
17
- }
18
- function splitImportResolutionErrors(errors) {
19
- const blockingErrors = [];
20
- const warningErrors = [];
21
- for (const error of errors) {
22
- if (isBlockingImportError(error)) {
23
- blockingErrors.push(error);
24
- }
25
- else {
26
- warningErrors.push(error);
27
- }
28
- }
29
- return { blockingErrors, warningErrors };
30
- }
31
- //# sourceMappingURL=importErrors.js.map