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.
Files changed (40) hide show
  1. package/AGENTS.md +9 -1
  2. package/CHANGELOG.md +12 -0
  3. package/dist/cli.js +161 -59
  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,393 +0,0 @@
1
- "use strict";
2
- /**
3
- * Schema Generator - Generates JSON Schema from response bodies
4
- * and validates data against JSON Schema
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
- var __importDefault = (this && this.__importDefault) || function (mod) {
40
- return (mod && mod.__esModule) ? mod : { "default": mod };
41
- };
42
- Object.defineProperty(exports, "__esModule", { value: true });
43
- exports.resolveSchemaPath = resolveSchemaPath;
44
- exports.generateJsonSchema = generateJsonSchema;
45
- exports.validateAgainstSchemaDetailed = validateAgainstSchemaDetailed;
46
- exports.validateAgainstSchema = validateAgainstSchema;
47
- exports.generateSchemaFileName = generateSchemaFileName;
48
- exports.saveSchema = saveSchema;
49
- const ajv_1 = __importDefault(require("ajv"));
50
- const fs = __importStar(require("fs"));
51
- const path = __importStar(require("path"));
52
- const ajv = new ajv_1.default({ allErrors: true, strict: false });
53
- /**
54
- * Path alias prefix - @/ resolves to contracts/ folder
55
- */
56
- const PATH_ALIAS_PREFIX = '@/';
57
- const DEFAULT_CONTRACTS_FOLDER = 'contracts';
58
- /**
59
- * Resolve a schema path, handling the @/ alias for contracts folder
60
- * @param schemaPath The original schema path (may have @/ prefix)
61
- * @param basePath Base path for relative paths (usually the source file's directory)
62
- * @param workspaceRoot Optional workspace root for @/ alias resolution
63
- * @returns Resolved absolute path
64
- */
65
- function resolveSchemaPath(schemaPath, basePath, workspaceRoot) {
66
- // Handle @/ alias
67
- if (schemaPath.startsWith(PATH_ALIAS_PREFIX)) {
68
- const relativePath = schemaPath.slice(PATH_ALIAS_PREFIX.length);
69
- // First try workspace root, then fall back to basePath traversal
70
- if (workspaceRoot) {
71
- return path.resolve(workspaceRoot, DEFAULT_CONTRACTS_FOLDER, relativePath);
72
- }
73
- // If no workspace root, try to find contracts folder by walking up
74
- if (basePath) {
75
- let currentDir = basePath;
76
- let attempts = 0;
77
- while (attempts < 10) {
78
- const contractsPath = path.join(currentDir, DEFAULT_CONTRACTS_FOLDER, relativePath);
79
- if (fs.existsSync(path.dirname(contractsPath))) {
80
- return contractsPath;
81
- }
82
- const parentDir = path.dirname(currentDir);
83
- if (parentDir === currentDir)
84
- break;
85
- currentDir = parentDir;
86
- attempts++;
87
- }
88
- }
89
- // Fallback: just use contracts/ relative to basePath
90
- if (basePath) {
91
- return path.resolve(basePath, DEFAULT_CONTRACTS_FOLDER, relativePath);
92
- }
93
- return schemaPath; // Can't resolve
94
- }
95
- // Regular relative/absolute path handling
96
- if (path.isAbsolute(schemaPath)) {
97
- return schemaPath;
98
- }
99
- if (basePath) {
100
- return path.resolve(basePath, schemaPath);
101
- }
102
- return schemaPath;
103
- }
104
- /**
105
- * Generate a JSON Schema (draft-07) from a sample value
106
- */
107
- function generateJsonSchema(value, title) {
108
- const schema = {
109
- $schema: 'http://json-schema.org/draft-07/schema#',
110
- };
111
- if (title) {
112
- schema.title = title;
113
- }
114
- const typeSchema = inferType(value);
115
- Object.assign(schema, typeSchema);
116
- return schema;
117
- }
118
- /**
119
- * Infer JSON Schema type information from a value
120
- */
121
- function inferType(value) {
122
- if (value === null) {
123
- return { type: 'null' };
124
- }
125
- if (Array.isArray(value)) {
126
- if (value.length === 0) {
127
- return { type: 'array', items: {} };
128
- }
129
- // Infer from first item (could be enhanced to merge schemas)
130
- return {
131
- type: 'array',
132
- items: inferType(value[0])
133
- };
134
- }
135
- if (typeof value === 'object') {
136
- const properties = {};
137
- const required = [];
138
- for (const key of Object.keys(value)) {
139
- properties[key] = inferType(value[key]);
140
- // Mark all properties as required by default
141
- required.push(key);
142
- }
143
- return {
144
- type: 'object',
145
- properties,
146
- required: required.length > 0 ? required : undefined,
147
- additionalProperties: true
148
- };
149
- }
150
- if (typeof value === 'string') {
151
- return { type: 'string' };
152
- }
153
- if (typeof value === 'number') {
154
- return Number.isInteger(value) ? { type: 'integer' } : { type: 'number' };
155
- }
156
- if (typeof value === 'boolean') {
157
- return { type: 'boolean' };
158
- }
159
- return {};
160
- }
161
- /**
162
- * Convert Ajv ErrorObject to rich SchemaValidationError
163
- */
164
- function convertAjvError(err, value) {
165
- const instancePath = err.instancePath || '(root)';
166
- // Determine expected value based on keyword
167
- let expected;
168
- let actual = undefined;
169
- switch (err.keyword) {
170
- case 'type':
171
- expected = err.params.type;
172
- actual = getValueAtPath(value, instancePath);
173
- break;
174
- case 'required':
175
- expected = `property "${err.params.missingProperty}" to exist`;
176
- break;
177
- case 'enum':
178
- expected = `one of: ${err.params.allowedValues?.join(', ')}`;
179
- actual = getValueAtPath(value, instancePath);
180
- break;
181
- case 'pattern':
182
- expected = `to match pattern "${err.params.pattern}"`;
183
- actual = getValueAtPath(value, instancePath);
184
- break;
185
- case 'minLength':
186
- expected = `length >= ${err.params.limit}`;
187
- actual = getValueAtPath(value, instancePath);
188
- break;
189
- case 'maxLength':
190
- expected = `length <= ${err.params.limit}`;
191
- actual = getValueAtPath(value, instancePath);
192
- break;
193
- case 'minimum':
194
- case 'exclusiveMinimum':
195
- expected = `>= ${err.params.limit}`;
196
- actual = getValueAtPath(value, instancePath);
197
- break;
198
- case 'maximum':
199
- case 'exclusiveMaximum':
200
- expected = `<= ${err.params.limit}`;
201
- actual = getValueAtPath(value, instancePath);
202
- break;
203
- case 'additionalProperties':
204
- expected = `no additional property "${err.params.additionalProperty}"`;
205
- break;
206
- case 'format':
207
- expected = `format "${err.params.format}"`;
208
- actual = getValueAtPath(value, instancePath);
209
- break;
210
- default:
211
- if (err.params) {
212
- expected = JSON.stringify(err.params);
213
- }
214
- actual = getValueAtPath(value, instancePath);
215
- }
216
- // Determine severity based on keyword
217
- let severity = 'error';
218
- if (err.keyword === 'additionalProperties') {
219
- severity = 'warning'; // Extra properties are often okay
220
- }
221
- return {
222
- instancePath,
223
- schemaPath: err.schemaPath,
224
- keyword: err.keyword,
225
- message: err.message || 'Validation failed',
226
- params: err.params,
227
- expected,
228
- actual,
229
- severity
230
- };
231
- }
232
- /**
233
- * Get value at a JSON pointer path
234
- */
235
- function getValueAtPath(obj, jsonPointer) {
236
- if (jsonPointer === '(root)' || jsonPointer === '' || jsonPointer === '/') {
237
- return obj;
238
- }
239
- // Remove leading slash and split
240
- const parts = jsonPointer.replace(/^\//, '').split('/');
241
- let current = obj;
242
- for (const part of parts) {
243
- if (current === null || current === undefined) {
244
- return undefined;
245
- }
246
- // Decode JSON Pointer escapes
247
- const key = part.replace(/~1/g, '/').replace(/~0/g, '~');
248
- current = current[key];
249
- }
250
- return current;
251
- }
252
- /**
253
- * Validate a value against a JSON Schema file with detailed error information
254
- * @param value The value to validate
255
- * @param schemaPath Absolute or relative path to the schema file (supports @/ alias for contracts/)
256
- * @param basePath Base path for resolving relative schema paths
257
- * @param workspaceRoot Optional workspace root for @/ alias resolution
258
- * @returns Detailed result with rich error objects for Contract View
259
- */
260
- function validateAgainstSchemaDetailed(value, schemaPath, basePath, workspaceRoot) {
261
- try {
262
- // Resolve schema path (handles @/ alias for contracts folder)
263
- const resolvedPath = resolveSchemaPath(schemaPath, basePath, workspaceRoot);
264
- // Check if file exists
265
- if (!fs.existsSync(resolvedPath)) {
266
- return {
267
- valid: false,
268
- errors: [{
269
- instancePath: '(root)',
270
- schemaPath: '',
271
- keyword: 'file',
272
- message: `Schema file not found: ${schemaPath}`,
273
- params: { path: schemaPath },
274
- severity: 'error'
275
- }],
276
- errorStrings: [`Schema file not found: ${schemaPath}`],
277
- resolvedSchemaPath: resolvedPath
278
- };
279
- }
280
- // Load and parse schema
281
- const schemaContent = fs.readFileSync(resolvedPath, 'utf-8');
282
- let schema;
283
- try {
284
- schema = JSON.parse(schemaContent);
285
- }
286
- catch (e) {
287
- return {
288
- valid: false,
289
- errors: [{
290
- instancePath: '(root)',
291
- schemaPath: '',
292
- keyword: 'parse',
293
- message: `Invalid JSON in schema file: ${schemaPath}`,
294
- params: { path: schemaPath },
295
- severity: 'error'
296
- }],
297
- errorStrings: [`Invalid JSON in schema file: ${schemaPath}`],
298
- resolvedSchemaPath: resolvedPath
299
- };
300
- }
301
- // Validate
302
- const validate = ajv.compile(schema);
303
- const valid = validate(value);
304
- if (!valid && validate.errors) {
305
- const errors = validate.errors.map(err => convertAjvError(err, value));
306
- const errorStrings = validate.errors.map(err => {
307
- const path = err.instancePath || '(root)';
308
- return `${path}: ${err.message}`;
309
- });
310
- return {
311
- valid: false,
312
- errors,
313
- errorStrings,
314
- resolvedSchemaPath: resolvedPath,
315
- schema
316
- };
317
- }
318
- return {
319
- valid: true,
320
- resolvedSchemaPath: resolvedPath,
321
- schema
322
- };
323
- }
324
- catch (e) {
325
- const error = e instanceof Error ? e.message : String(e);
326
- return {
327
- valid: false,
328
- errors: [{
329
- instancePath: '(root)',
330
- schemaPath: '',
331
- keyword: 'exception',
332
- message: `Schema validation error: ${error}`,
333
- params: {},
334
- severity: 'error'
335
- }],
336
- errorStrings: [`Schema validation error: ${error}`]
337
- };
338
- }
339
- }
340
- /**
341
- * Validate a value against a JSON Schema file
342
- * @param value The value to validate
343
- * @param schemaPath Absolute or relative path to the schema file
344
- * @param basePath Base path for resolving relative schema paths
345
- * @returns Object with valid flag and optional errors (backward compatible)
346
- */
347
- function validateAgainstSchema(value, schemaPath, basePath) {
348
- const result = validateAgainstSchemaDetailed(value, schemaPath, basePath);
349
- return {
350
- valid: result.valid,
351
- errors: result.errorStrings
352
- };
353
- }
354
- /**
355
- * Generate a schema file name from an endpoint URL
356
- * Example: "GET /api/users/{id}" => "GET-api-users-id"
357
- */
358
- function generateSchemaFileName(method, url) {
359
- // Extract path from URL (remove protocol, host, query string)
360
- let urlPath = url;
361
- try {
362
- const parsed = new URL(url);
363
- urlPath = parsed.pathname;
364
- }
365
- catch {
366
- // URL might be a relative path, try to extract just the path part
367
- const queryIndex = url.indexOf('?');
368
- if (queryIndex > -1) {
369
- urlPath = url.substring(0, queryIndex);
370
- }
371
- }
372
- // Clean up the path
373
- const cleanPath = urlPath
374
- .replace(/^\/+|\/+$/g, '') // Remove leading/trailing slashes
375
- .replace(/\{[^}]+\}/g, 'param') // {id} => param
376
- .replace(/[^a-zA-Z0-9-]/g, '-') // Replace non-alphanumeric with dash
377
- .replace(/-+/g, '-') // Collapse multiple dashes
378
- .replace(/^-|-$/g, ''); // Remove leading/trailing dashes
379
- return `${method.toUpperCase()}-${cleanPath || 'root'}.schema.json`;
380
- }
381
- /**
382
- * Save a schema to a file
383
- * @param schema The JSON Schema object
384
- * @param filePath Absolute path to save the schema
385
- */
386
- function saveSchema(schema, filePath) {
387
- const dir = path.dirname(filePath);
388
- if (!fs.existsSync(dir)) {
389
- fs.mkdirSync(dir, { recursive: true });
390
- }
391
- fs.writeFileSync(filePath, JSON.stringify(schema, null, 2), 'utf-8');
392
- }
393
- //# sourceMappingURL=schemaGenerator.js.map