norn-cli 1.6.1 → 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.
- package/AGENTS.md +9 -1
- package/CHANGELOG.md +12 -0
- package/dist/cli.js +161 -59
- package/package.json +1 -1
- package/out/assertionRunner.js +0 -537
- package/out/chatParticipant.js +0 -722
- package/out/cli/colors.js +0 -129
- package/out/cli/formatters/assertion.js +0 -75
- package/out/cli/formatters/index.js +0 -23
- package/out/cli/formatters/response.js +0 -106
- package/out/cli/formatters/summary.js +0 -187
- package/out/cli/redaction.js +0 -237
- package/out/cli/reporters/html.js +0 -634
- package/out/cli/reporters/index.js +0 -22
- package/out/cli/reporters/junit.js +0 -211
- package/out/cli.js +0 -989
- package/out/codeLensProvider.js +0 -248
- package/out/compareContentProvider.js +0 -85
- package/out/completionProvider.js +0 -2404
- package/out/contractDecorationProvider.js +0 -243
- package/out/coverageCalculator.js +0 -837
- package/out/coveragePanel.js +0 -545
- package/out/diagnosticProvider.js +0 -1113
- package/out/environmentProvider.js +0 -442
- package/out/extension.js +0 -1114
- package/out/httpClient.js +0 -269
- package/out/jsonFileReader.js +0 -320
- package/out/nornPrompt.js +0 -580
- package/out/nornapiParser.js +0 -326
- package/out/parser.js +0 -725
- package/out/responsePanel.js +0 -4674
- package/out/schemaGenerator.js +0 -393
- package/out/scriptRunner.js +0 -419
- package/out/sequenceRunner.js +0 -3046
- package/out/swaggerBodyIntellisenseCache.js +0 -147
- package/out/swaggerParser.js +0 -419
- package/out/test/coverageCalculator.test.js +0 -100
- package/out/test/extension.test.js +0 -48
- package/out/testProvider.js +0 -658
- package/out/validationCache.js +0 -245
package/out/codeLensProvider.js
DELETED
|
@@ -1,248 +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.HttpCodeLensProvider = void 0;
|
|
37
|
-
exports.updateCodeLensCoverage = updateCodeLensCoverage;
|
|
38
|
-
const vscode = __importStar(require("vscode"));
|
|
39
|
-
const environmentProvider_1 = require("./environmentProvider");
|
|
40
|
-
// Cached coverage percentage for CodeLens display
|
|
41
|
-
/**
|
|
42
|
-
* Update the cached coverage for CodeLens display
|
|
43
|
-
*/
|
|
44
|
-
function updateCodeLensCoverage(percentage, total, covered) {
|
|
45
|
-
void percentage;
|
|
46
|
-
void total;
|
|
47
|
-
void covered;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Checks if a sequence declaration has only optional parameters (all have defaults).
|
|
51
|
-
* Returns true if no parameters or all parameters have defaults.
|
|
52
|
-
*/
|
|
53
|
-
function canRunSequenceWithoutArgs(line) {
|
|
54
|
-
// Check if there are parameters
|
|
55
|
-
const parenMatch = line.match(/\(([^)]*)\)/);
|
|
56
|
-
if (!parenMatch) {
|
|
57
|
-
// No parameters - can run
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
const paramsStr = parenMatch[1].trim();
|
|
61
|
-
if (!paramsStr) {
|
|
62
|
-
// Empty parens - can run
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
// Split by comma (simple split, not handling quoted strings with commas)
|
|
66
|
-
const params = paramsStr.split(',');
|
|
67
|
-
// Check each parameter has a default (contains =)
|
|
68
|
-
for (const param of params) {
|
|
69
|
-
const trimmed = param.trim();
|
|
70
|
-
if (!trimmed)
|
|
71
|
-
continue;
|
|
72
|
-
// Must contain = for a default value
|
|
73
|
-
if (!trimmed.includes('=')) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Checks for @data(...) or @theory(...) annotations directly above a sequence declaration.
|
|
81
|
-
* This allows CodeLens execution for parameterized sequences with required parameters.
|
|
82
|
-
*/
|
|
83
|
-
function hasTheoryAnnotationsAbove(document, sequenceLine) {
|
|
84
|
-
const dataOrTheoryPattern = /^@(data|theory)\s*\(/;
|
|
85
|
-
const decoratorPattern = /^@/;
|
|
86
|
-
for (let i = sequenceLine - 1; i >= 0; i--) {
|
|
87
|
-
const line = document.lineAt(i).text.trim();
|
|
88
|
-
// Allow blank lines between decorators and sequence declaration
|
|
89
|
-
if (!line) {
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
// Stop as soon as the decorator block ends
|
|
93
|
-
if (!decoratorPattern.test(line)) {
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
if (dataOrTheoryPattern.test(line)) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
class HttpCodeLensProvider {
|
|
103
|
-
_onDidChangeCodeLenses = new vscode.EventEmitter();
|
|
104
|
-
onDidChangeCodeLenses = this._onDidChangeCodeLenses.event;
|
|
105
|
-
constructor() {
|
|
106
|
-
// Refresh code lenses when environment changes
|
|
107
|
-
vscode.commands.registerCommand('norn.refreshCodeLenses', () => {
|
|
108
|
-
this._onDidChangeCodeLenses.fire();
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Gets the environment display text for CodeLens
|
|
113
|
-
* Returns 'add' if no env file exists, environment name if it does
|
|
114
|
-
*/
|
|
115
|
-
getEnvDisplay(documentPath) {
|
|
116
|
-
const envFile = (0, environmentProvider_1.findEnvFileFromPath)(documentPath);
|
|
117
|
-
if (!envFile) {
|
|
118
|
-
return { text: '+ Add env file', hasEnvFile: false };
|
|
119
|
-
}
|
|
120
|
-
const activeEnv = (0, environmentProvider_1.getActiveEnvironment)();
|
|
121
|
-
const availableEnvs = (0, environmentProvider_1.getAvailableEnvironments)(envFile);
|
|
122
|
-
if (availableEnvs.length === 0) {
|
|
123
|
-
return { text: 'env: (empty)', hasEnvFile: true };
|
|
124
|
-
}
|
|
125
|
-
return { text: activeEnv ? `env: ${activeEnv}` : 'env: none', hasEnvFile: true };
|
|
126
|
-
}
|
|
127
|
-
provideCodeLenses(document) {
|
|
128
|
-
const codeLenses = [];
|
|
129
|
-
const methodRegex = /^(GET|POST|PUT|DELETE|PATCH|HEAD|OPTIONS)\s+/;
|
|
130
|
-
// Match sequence (with optional test keyword) and optional parameters
|
|
131
|
-
const sequenceRegex = /^(?:test\s+)?sequence\s+([a-zA-Z_][a-zA-Z0-9_-]*)(?:\s*\([^)]*\))?$/;
|
|
132
|
-
// Match swagger statement with optional quotes around URL (only in .nornapi files)
|
|
133
|
-
const swaggerRegex = /^swagger\s+["']?(https?:\/\/[^\s"']+)["']?\s*$/;
|
|
134
|
-
// Match matchesSchema assertions: assert $1.body matchesSchema "./schema.json"
|
|
135
|
-
// Note: .+? is non-greedy to not consume matchesSchema
|
|
136
|
-
const matchesSchemaRegex = /^\s*assert\s+.+?\s+matchesSchema\s+["']?([^"']+)["']?/i;
|
|
137
|
-
const envInfo = this.getEnvDisplay(document.uri.fsPath);
|
|
138
|
-
const isNornApiFile = document.languageId === 'nornapi';
|
|
139
|
-
const isNornFile = document.languageId === 'norn';
|
|
140
|
-
// Track if we're inside a sequence
|
|
141
|
-
let insideSequence = false;
|
|
142
|
-
for (let i = 0; i < document.lineCount; i++) {
|
|
143
|
-
const line = document.lineAt(i);
|
|
144
|
-
const trimmedText = line.text.trim();
|
|
145
|
-
// Check for swagger statement (only in .nornapi files)
|
|
146
|
-
if (isNornApiFile) {
|
|
147
|
-
const swaggerMatch = trimmedText.match(swaggerRegex);
|
|
148
|
-
if (swaggerMatch) {
|
|
149
|
-
const range = new vscode.Range(i, 0, i, line.text.length);
|
|
150
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
151
|
-
title: '$(debug-start) Import Endpoints',
|
|
152
|
-
command: 'norn.importSwagger',
|
|
153
|
-
arguments: [swaggerMatch[1], i],
|
|
154
|
-
tooltip: `Parse OpenAPI spec and generate endpoints`
|
|
155
|
-
}));
|
|
156
|
-
// Add Generate Schemas CodeLens
|
|
157
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
158
|
-
title: '$(file-code) Generate Schemas',
|
|
159
|
-
command: 'norn.generateSchemasFromSwagger',
|
|
160
|
-
arguments: [swaggerMatch[1], document.uri.fsPath],
|
|
161
|
-
tooltip: 'Generate JSON Schema files from OpenAPI response definitions'
|
|
162
|
-
}));
|
|
163
|
-
// Add file-scoped coverage CodeLens
|
|
164
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
165
|
-
title: '$(graph) Show Coverage',
|
|
166
|
-
command: 'norn.showCoverage',
|
|
167
|
-
arguments: [document.uri.fsPath],
|
|
168
|
-
tooltip: 'Show API coverage for this .nornapi file (includes this folder and subfolders only).'
|
|
169
|
-
}));
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// Check for matchesSchema assertions (in .norn files)
|
|
174
|
-
if (isNornFile) {
|
|
175
|
-
const schemaMatch = trimmedText.match(matchesSchemaRegex);
|
|
176
|
-
if (schemaMatch) {
|
|
177
|
-
const schemaPath = schemaMatch[1];
|
|
178
|
-
const range = new vscode.Range(i, 0, i, line.text.length);
|
|
179
|
-
// Open Contract lens
|
|
180
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
181
|
-
title: '$(file-code) Open Contract',
|
|
182
|
-
command: 'norn.openSchemaFile',
|
|
183
|
-
arguments: [schemaPath, document.uri.fsPath],
|
|
184
|
-
tooltip: `Open schema file: ${schemaPath}`
|
|
185
|
-
}));
|
|
186
|
-
// View Contract Report lens
|
|
187
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
188
|
-
title: '$(checklist) View Contract',
|
|
189
|
-
command: 'norn.viewContractReport',
|
|
190
|
-
arguments: [i, document.uri.fsPath, schemaPath],
|
|
191
|
-
tooltip: 'Run validation and show contract comparison report'
|
|
192
|
-
}));
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
// Check for sequence start
|
|
197
|
-
const sequenceMatch = trimmedText.match(sequenceRegex);
|
|
198
|
-
if (sequenceMatch) {
|
|
199
|
-
insideSequence = true;
|
|
200
|
-
const range = new vscode.Range(i, 0, i, line.text.length);
|
|
201
|
-
// Show Run Sequence if parameters are all optional, or values are provided via @data/@theory.
|
|
202
|
-
const canRunWithoutArgs = canRunSequenceWithoutArgs(trimmedText);
|
|
203
|
-
const hasTheoryAnnotations = hasTheoryAnnotationsAbove(document, i);
|
|
204
|
-
if (canRunWithoutArgs || hasTheoryAnnotations) {
|
|
205
|
-
// Run Sequence lens
|
|
206
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
207
|
-
title: '▶ Run Sequence',
|
|
208
|
-
command: 'norn.runSequence',
|
|
209
|
-
arguments: [i],
|
|
210
|
-
tooltip: `Run all requests in sequence "${sequenceMatch[1]}"`
|
|
211
|
-
}));
|
|
212
|
-
// Environment lens
|
|
213
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
214
|
-
title: envInfo.text,
|
|
215
|
-
command: envInfo.hasEnvFile ? 'norn.selectEnvironmentAndRefresh' : 'norn.createEnvFile',
|
|
216
|
-
tooltip: envInfo.hasEnvFile ? 'Click to change environment' : 'Click to create .nornenv file'
|
|
217
|
-
}));
|
|
218
|
-
}
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
// Check for sequence end
|
|
222
|
-
if (trimmedText === 'end sequence') {
|
|
223
|
-
insideSequence = false;
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
// Only show "Send Request" for requests OUTSIDE of sequences
|
|
227
|
-
if (!insideSequence && methodRegex.test(line.text)) {
|
|
228
|
-
const range = new vscode.Range(i, 0, i, line.text.length);
|
|
229
|
-
// Send Request lens
|
|
230
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
231
|
-
title: '▶ Send Request',
|
|
232
|
-
command: 'norn.sendRequest',
|
|
233
|
-
arguments: [i],
|
|
234
|
-
tooltip: 'Send this HTTP request'
|
|
235
|
-
}));
|
|
236
|
-
// Environment lens
|
|
237
|
-
codeLenses.push(new vscode.CodeLens(range, {
|
|
238
|
-
title: envInfo.text,
|
|
239
|
-
command: envInfo.hasEnvFile ? 'norn.selectEnvironmentAndRefresh' : 'norn.createEnvFile',
|
|
240
|
-
tooltip: envInfo.hasEnvFile ? 'Click to change environment' : 'Click to create .nornenv file'
|
|
241
|
-
}));
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
return codeLenses;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
exports.HttpCodeLensProvider = HttpCodeLensProvider;
|
|
248
|
-
//# sourceMappingURL=codeLensProvider.js.map
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Content provider for response comparison diff view
|
|
4
|
-
* Provides in-memory content for VS Code's built-in diff editor
|
|
5
|
-
*/
|
|
6
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
-
if (k2 === undefined) k2 = k;
|
|
8
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
-
}
|
|
12
|
-
Object.defineProperty(o, k2, desc);
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
-
}) : function(o, v) {
|
|
20
|
-
o["default"] = v;
|
|
21
|
-
});
|
|
22
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
-
var ownKeys = function(o) {
|
|
24
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
-
var ar = [];
|
|
26
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
-
return ar;
|
|
28
|
-
};
|
|
29
|
-
return ownKeys(o);
|
|
30
|
-
};
|
|
31
|
-
return function (mod) {
|
|
32
|
-
if (mod && mod.__esModule) return mod;
|
|
33
|
-
var result = {};
|
|
34
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
-
__setModuleDefault(result, mod);
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
})();
|
|
39
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
exports.CompareContentProvider = void 0;
|
|
41
|
-
exports.getCompareContentProvider = getCompareContentProvider;
|
|
42
|
-
exports.registerCompareContentProvider = registerCompareContentProvider;
|
|
43
|
-
const vscode = __importStar(require("vscode"));
|
|
44
|
-
class CompareContentProvider {
|
|
45
|
-
static scheme = 'norn-compare';
|
|
46
|
-
_content = new Map();
|
|
47
|
-
_onDidChange = new vscode.EventEmitter();
|
|
48
|
-
onDidChange = this._onDidChange.event;
|
|
49
|
-
/**
|
|
50
|
-
* Set content for a given path (e.g., 'baseline.json' or 'current.json')
|
|
51
|
-
*/
|
|
52
|
-
setContent(path, content) {
|
|
53
|
-
this._content.set(path, content);
|
|
54
|
-
const uri = vscode.Uri.parse(`${CompareContentProvider.scheme}:${path}`);
|
|
55
|
-
this._onDidChange.fire(uri);
|
|
56
|
-
return uri;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Clear all stored content
|
|
60
|
-
*/
|
|
61
|
-
clear() {
|
|
62
|
-
this._content.clear();
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Provider implementation - returns content for the given URI
|
|
66
|
-
*/
|
|
67
|
-
provideTextDocumentContent(uri) {
|
|
68
|
-
return this._content.get(uri.path) || '';
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
exports.CompareContentProvider = CompareContentProvider;
|
|
72
|
-
// Singleton instance for use across the extension
|
|
73
|
-
let _instance;
|
|
74
|
-
function getCompareContentProvider() {
|
|
75
|
-
if (!_instance) {
|
|
76
|
-
_instance = new CompareContentProvider();
|
|
77
|
-
}
|
|
78
|
-
return _instance;
|
|
79
|
-
}
|
|
80
|
-
function registerCompareContentProvider(context) {
|
|
81
|
-
const provider = getCompareContentProvider();
|
|
82
|
-
const registration = vscode.workspace.registerTextDocumentContentProvider(CompareContentProvider.scheme, provider);
|
|
83
|
-
context.subscriptions.push(registration);
|
|
84
|
-
}
|
|
85
|
-
//# sourceMappingURL=compareContentProvider.js.map
|