norn-cli 1.6.0 → 1.6.2

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 (40) hide show
  1. package/AGENTS.md +9 -1
  2. package/CHANGELOG.md +23 -0
  3. package/dist/cli.js +246 -80
  4. package/package.json +1 -1
  5. package/out/assertionRunner.js +0 -537
  6. package/out/chatParticipant.js +0 -722
  7. package/out/cli/colors.js +0 -129
  8. package/out/cli/formatters/assertion.js +0 -75
  9. package/out/cli/formatters/index.js +0 -23
  10. package/out/cli/formatters/response.js +0 -106
  11. package/out/cli/formatters/summary.js +0 -187
  12. package/out/cli/redaction.js +0 -237
  13. package/out/cli/reporters/html.js +0 -634
  14. package/out/cli/reporters/index.js +0 -22
  15. package/out/cli/reporters/junit.js +0 -211
  16. package/out/cli.js +0 -989
  17. package/out/codeLensProvider.js +0 -248
  18. package/out/compareContentProvider.js +0 -85
  19. package/out/completionProvider.js +0 -2404
  20. package/out/contractDecorationProvider.js +0 -243
  21. package/out/coverageCalculator.js +0 -837
  22. package/out/coveragePanel.js +0 -545
  23. package/out/diagnosticProvider.js +0 -1113
  24. package/out/environmentProvider.js +0 -442
  25. package/out/extension.js +0 -1114
  26. package/out/httpClient.js +0 -269
  27. package/out/jsonFileReader.js +0 -320
  28. package/out/nornPrompt.js +0 -580
  29. package/out/nornapiParser.js +0 -326
  30. package/out/parser.js +0 -725
  31. package/out/responsePanel.js +0 -4674
  32. package/out/schemaGenerator.js +0 -393
  33. package/out/scriptRunner.js +0 -419
  34. package/out/sequenceRunner.js +0 -3046
  35. package/out/swaggerBodyIntellisenseCache.js +0 -147
  36. package/out/swaggerParser.js +0 -419
  37. package/out/test/coverageCalculator.test.js +0 -100
  38. package/out/test/extension.test.js +0 -48
  39. package/out/testProvider.js +0 -658
  40. package/out/validationCache.js +0 -245
@@ -1,442 +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
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.findEnvFile = findEnvFile;
37
- exports.findEnvFileFromPath = findEnvFileFromPath;
38
- exports.parseEnvFile = parseEnvFile;
39
- exports.loadEnvironmentConfig = loadEnvironmentConfig;
40
- exports.getActiveEnvironment = getActiveEnvironment;
41
- exports.setActiveEnvironment = setActiveEnvironment;
42
- exports.getEnvironmentVariables = getEnvironmentVariables;
43
- exports.getAvailableEnvironments = getAvailableEnvironments;
44
- exports.createStatusBarItem = createStatusBarItem;
45
- exports.refreshEnvironmentStatusBar = refreshEnvironmentStatusBar;
46
- exports.showEnvironmentPicker = showEnvironmentPicker;
47
- exports.disposeStatusBar = disposeStatusBar;
48
- exports.createCoverageStatusBarItem = createCoverageStatusBarItem;
49
- exports.refreshCoverageStatusBarContext = refreshCoverageStatusBarContext;
50
- exports.updateCoverageStatusBar = updateCoverageStatusBar;
51
- exports.getCoverageStatusBarItem = getCoverageStatusBarItem;
52
- const vscode = __importStar(require("vscode"));
53
- const fs = __importStar(require("fs"));
54
- const path = __importStar(require("path"));
55
- const ENV_FILENAME = '.nornenv';
56
- // Current active environment (stored globally)
57
- let activeEnvironment;
58
- let statusBarItem;
59
- let coverageStatusBarItem;
60
- let hasCoverageData = false;
61
- /**
62
- * Resolves where environment file discovery should start.
63
- * If the path points to a directory, search from that directory.
64
- * If it points to a file (or non-existent path), search from the parent directory.
65
- */
66
- function getEnvSearchStartDirectory(targetPath) {
67
- const resolvedPath = path.resolve(targetPath);
68
- try {
69
- const stats = fs.statSync(resolvedPath);
70
- return stats.isDirectory() ? resolvedPath : path.dirname(resolvedPath);
71
- }
72
- catch {
73
- return path.dirname(resolvedPath);
74
- }
75
- }
76
- function getContextEnvFile() {
77
- const activeEditor = vscode.window.activeTextEditor;
78
- if (activeEditor && activeEditor.document.uri.scheme === 'file') {
79
- return findEnvFileFromPath(activeEditor.document.uri.fsPath);
80
- }
81
- return findEnvFile();
82
- }
83
- function resolveEnvFilePath(pathOrSourceFile) {
84
- if (!pathOrSourceFile) {
85
- return getContextEnvFile();
86
- }
87
- const resolvedPath = path.resolve(pathOrSourceFile);
88
- if (path.basename(resolvedPath) === ENV_FILENAME && fs.existsSync(resolvedPath)) {
89
- return resolvedPath;
90
- }
91
- return findEnvFileFromPath(resolvedPath);
92
- }
93
- /**
94
- * Finds the .nornenv file in the workspace
95
- */
96
- function findEnvFile() {
97
- const workspaceFolders = vscode.workspace.workspaceFolders;
98
- if (!workspaceFolders) {
99
- return undefined;
100
- }
101
- for (const folder of workspaceFolders) {
102
- const envPath = path.join(folder.uri.fsPath, ENV_FILENAME);
103
- if (fs.existsSync(envPath)) {
104
- return envPath;
105
- }
106
- }
107
- return undefined;
108
- }
109
- /**
110
- * Finds .nornenv file relative to a specific file path (for CLI usage)
111
- */
112
- function findEnvFileFromPath(filePath) {
113
- let dir = getEnvSearchStartDirectory(filePath);
114
- while (true) {
115
- const envPath = path.join(dir, ENV_FILENAME);
116
- if (fs.existsSync(envPath)) {
117
- return envPath;
118
- }
119
- const parentDir = path.dirname(dir);
120
- if (parentDir === dir) {
121
- break;
122
- }
123
- dir = parentDir;
124
- }
125
- return undefined;
126
- }
127
- /**
128
- * Parses the .nornenv file content
129
- */
130
- function parseEnvFile(content) {
131
- const lines = content.split('\n');
132
- const config = {
133
- common: {},
134
- environments: [],
135
- secretNames: new Set(),
136
- secretValues: new Map()
137
- };
138
- let currentEnv = null;
139
- const envRegex = /^\[env:([a-zA-Z_][a-zA-Z0-9_-]*)\]$/;
140
- const varRegex = /^var\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
141
- const secretRegex = /^secret\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
142
- for (const line of lines) {
143
- const trimmed = line.trim();
144
- // Skip empty lines and comments
145
- if (!trimmed || trimmed.startsWith('#')) {
146
- continue;
147
- }
148
- // Check for environment section
149
- const envMatch = trimmed.match(envRegex);
150
- if (envMatch) {
151
- currentEnv = {
152
- name: envMatch[1],
153
- variables: {}
154
- };
155
- config.environments.push(currentEnv);
156
- continue;
157
- }
158
- // Check for secret declaration (treated like var but marked for redaction)
159
- const secretMatch = trimmed.match(secretRegex);
160
- if (secretMatch) {
161
- const varName = secretMatch[1];
162
- const varValue = secretMatch[2].trim();
163
- // Track as secret
164
- config.secretNames.add(varName);
165
- config.secretValues.set(varName, varValue);
166
- // Also add to variables so it can be used
167
- if (currentEnv) {
168
- currentEnv.variables[varName] = varValue;
169
- }
170
- else {
171
- config.common[varName] = varValue;
172
- }
173
- continue;
174
- }
175
- // Check for variable declaration
176
- const varMatch = trimmed.match(varRegex);
177
- if (varMatch) {
178
- const varName = varMatch[1];
179
- const varValue = varMatch[2].trim();
180
- if (currentEnv) {
181
- currentEnv.variables[varName] = varValue;
182
- }
183
- else {
184
- config.common[varName] = varValue;
185
- }
186
- }
187
- }
188
- return config;
189
- }
190
- /**
191
- * Reads and parses the resolved .nornenv file.
192
- * Accepts either:
193
- * - a path to a .nornenv file, or
194
- * - a source file/directory path (it will resolve nearest .nornenv), or
195
- * - undefined (uses current editor context/workspace fallback).
196
- */
197
- function loadEnvironmentConfig(pathOrSourceFile) {
198
- const filePath = resolveEnvFilePath(pathOrSourceFile);
199
- if (!filePath || !fs.existsSync(filePath)) {
200
- return undefined;
201
- }
202
- try {
203
- const content = fs.readFileSync(filePath, 'utf-8');
204
- return parseEnvFile(content);
205
- }
206
- catch {
207
- return undefined;
208
- }
209
- }
210
- /**
211
- * Gets the currently active environment name
212
- */
213
- function getActiveEnvironment() {
214
- return activeEnvironment;
215
- }
216
- /**
217
- * Sets the active environment
218
- */
219
- function setActiveEnvironment(envName) {
220
- activeEnvironment = envName;
221
- updateStatusBar();
222
- }
223
- /**
224
- * Gets all variables for the current environment (common + environment-specific)
225
- */
226
- function getEnvironmentVariables(pathOrSourceFile) {
227
- const config = loadEnvironmentConfig(pathOrSourceFile);
228
- if (!config) {
229
- return {};
230
- }
231
- // Start with common variables
232
- const variables = { ...config.common };
233
- // Override with environment-specific variables if an environment is active
234
- if (activeEnvironment) {
235
- const env = config.environments.find(e => e.name === activeEnvironment);
236
- if (env) {
237
- Object.assign(variables, env.variables);
238
- }
239
- }
240
- return variables;
241
- }
242
- /**
243
- * Gets available environment names
244
- */
245
- function getAvailableEnvironments(pathOrSourceFile) {
246
- const config = loadEnvironmentConfig(pathOrSourceFile);
247
- if (!config) {
248
- return [];
249
- }
250
- return config.environments.map(e => e.name);
251
- }
252
- /**
253
- * Creates and shows the status bar item
254
- */
255
- function createStatusBarItem() {
256
- statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
257
- statusBarItem.command = 'norn.selectEnvironment';
258
- updateStatusBar();
259
- statusBarItem.show();
260
- return statusBarItem;
261
- }
262
- /**
263
- * Refreshes the status bar text based on current editor context.
264
- */
265
- function refreshEnvironmentStatusBar() {
266
- updateStatusBar();
267
- }
268
- /**
269
- * Updates the status bar item text
270
- */
271
- function updateStatusBar() {
272
- if (!statusBarItem) {
273
- return;
274
- }
275
- const envFile = getContextEnvFile();
276
- if (!envFile) {
277
- statusBarItem.text = '$(globe) Norn: No Env';
278
- statusBarItem.tooltip = 'No .nornenv file found';
279
- return;
280
- }
281
- if (activeEnvironment) {
282
- statusBarItem.text = `$(globe) Norn: ${activeEnvironment}`;
283
- statusBarItem.tooltip = `Active environment: ${activeEnvironment}\nClick to change`;
284
- }
285
- else {
286
- statusBarItem.text = '$(globe) Norn: Select Env';
287
- statusBarItem.tooltip = 'Click to select an environment';
288
- }
289
- }
290
- /**
291
- * Shows the environment picker
292
- */
293
- async function showEnvironmentPicker() {
294
- const envFilePath = getContextEnvFile();
295
- const environments = getAvailableEnvironments(envFilePath);
296
- if (environments.length === 0) {
297
- const createFile = await vscode.window.showInformationMessage('No .nornenv file found. Would you like to create one?', 'Create .nornenv', 'Cancel');
298
- if (createFile === 'Create .nornenv') {
299
- await createEnvFileTemplate();
300
- }
301
- return;
302
- }
303
- const items = [
304
- {
305
- label: '$(circle-slash) None',
306
- description: 'Use only common variables',
307
- picked: !activeEnvironment
308
- },
309
- ...environments.map(env => ({
310
- label: `$(server-environment) ${env}`,
311
- description: env === activeEnvironment ? '(active)' : '',
312
- picked: env === activeEnvironment
313
- }))
314
- ];
315
- const selected = await vscode.window.showQuickPick(items, {
316
- placeHolder: 'Select environment',
317
- title: 'Norn Environment'
318
- });
319
- if (selected) {
320
- if (selected.label.includes('None')) {
321
- setActiveEnvironment(undefined);
322
- vscode.window.showInformationMessage('Norn: Environment cleared');
323
- }
324
- else {
325
- const envName = selected.label.replace('$(server-environment) ', '');
326
- setActiveEnvironment(envName);
327
- vscode.window.showInformationMessage(`Norn: Switched to "${envName}" environment`);
328
- }
329
- }
330
- }
331
- /**
332
- * Creates a template .nornenv file
333
- */
334
- async function createEnvFileTemplate() {
335
- const workspaceFolders = vscode.workspace.workspaceFolders;
336
- if (!workspaceFolders) {
337
- vscode.window.showErrorMessage('No workspace folder open');
338
- return;
339
- }
340
- const template = `# Norn Environment Configuration
341
- # Common variables are available in all environments
342
-
343
- var timeout = 30000
344
- var version = v1
345
-
346
- # Development environment
347
- [env:dev]
348
- var baseUrl = http://localhost:3000
349
- var apiKey = dev-key-123
350
-
351
- # Staging environment
352
- [env:staging]
353
- var baseUrl = https://staging.api.example.com
354
- var apiKey = staging-key-456
355
-
356
- # Production environment
357
- [env:prod]
358
- var baseUrl = https://api.example.com
359
- var apiKey = prod-key-789
360
- `;
361
- const envPath = path.join(workspaceFolders[0].uri.fsPath, ENV_FILENAME);
362
- fs.writeFileSync(envPath, template, 'utf-8');
363
- const doc = await vscode.workspace.openTextDocument(envPath);
364
- await vscode.window.showTextDocument(doc);
365
- updateStatusBar();
366
- vscode.window.showInformationMessage('Created .nornenv file');
367
- }
368
- /**
369
- * Disposes the status bar item
370
- */
371
- function disposeStatusBar() {
372
- if (statusBarItem) {
373
- statusBarItem.dispose();
374
- statusBarItem = undefined;
375
- }
376
- if (coverageStatusBarItem) {
377
- coverageStatusBarItem.dispose();
378
- coverageStatusBarItem = undefined;
379
- }
380
- }
381
- /**
382
- * Creates the coverage status bar item
383
- */
384
- function createCoverageStatusBarItem() {
385
- coverageStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 99);
386
- coverageStatusBarItem.command = 'norn.showCoverage';
387
- coverageStatusBarItem.hide(); // Hidden until we know there's swagger
388
- return coverageStatusBarItem;
389
- }
390
- function getActiveNornapiPath() {
391
- const activeEditor = vscode.window.activeTextEditor;
392
- if (!activeEditor) {
393
- return undefined;
394
- }
395
- return activeEditor.document.languageId === 'nornapi'
396
- ? activeEditor.document.uri.fsPath
397
- : undefined;
398
- }
399
- /**
400
- * Refresh coverage status bar command context for the current active editor.
401
- */
402
- function refreshCoverageStatusBarContext() {
403
- if (!coverageStatusBarItem || !hasCoverageData) {
404
- return;
405
- }
406
- const activeNornapiPath = getActiveNornapiPath();
407
- coverageStatusBarItem.command = {
408
- command: 'norn.showCoverage',
409
- title: 'Show Coverage',
410
- arguments: activeNornapiPath ? [activeNornapiPath] : []
411
- };
412
- coverageStatusBarItem.text = '$(graph) Coverage';
413
- coverageStatusBarItem.tooltip = activeNornapiPath
414
- ? 'Show API coverage for this .nornapi file (includes this folder and subfolders only).'
415
- : 'Show API coverage';
416
- coverageStatusBarItem.show();
417
- }
418
- /**
419
- * Updates the coverage status bar display
420
- */
421
- function updateCoverageStatusBar(hasSwagger, percentage, total, covered) {
422
- if (!coverageStatusBarItem) {
423
- return;
424
- }
425
- if (!hasSwagger) {
426
- hasCoverageData = false;
427
- coverageStatusBarItem.hide();
428
- return;
429
- }
430
- hasCoverageData = true;
431
- void percentage;
432
- void total;
433
- void covered;
434
- refreshCoverageStatusBarContext();
435
- }
436
- /**
437
- * Get the coverage status bar item (for external updates)
438
- */
439
- function getCoverageStatusBarItem() {
440
- return coverageStatusBarItem;
441
- }
442
- //# sourceMappingURL=environmentProvider.js.map