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,562 +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.validateAgainstSchemaObjectDetailed = validateAgainstSchemaObjectDetailed;
47
- exports.validateAgainstSchema = validateAgainstSchema;
48
- exports.generateSchemaFileName = generateSchemaFileName;
49
- exports.saveSchema = saveSchema;
50
- const ajv_1 = __importDefault(require("ajv"));
51
- const fs = __importStar(require("fs"));
52
- const path = __importStar(require("path"));
53
- const ajv = new ajv_1.default({ allErrors: true, strict: false });
54
- for (const formatName of ['int32', 'int64', 'float', 'double']) {
55
- ajv.addFormat(formatName, {
56
- type: 'number',
57
- validate: () => true
58
- });
59
- }
60
- /**
61
- * Path alias prefix - @/ resolves to contracts/ folder
62
- */
63
- const PATH_ALIAS_PREFIX = '@/';
64
- const DEFAULT_CONTRACTS_FOLDER = 'contracts';
65
- /**
66
- * Resolve a schema path, handling the @/ alias for contracts folder
67
- * @param schemaPath The original schema path (may have @/ prefix)
68
- * @param basePath Base path for relative paths (usually the source file's directory)
69
- * @param workspaceRoot Optional workspace root for @/ alias resolution
70
- * @returns Resolved absolute path
71
- */
72
- function resolveSchemaPath(schemaPath, basePath, workspaceRoot) {
73
- // Handle @/ alias
74
- if (schemaPath.startsWith(PATH_ALIAS_PREFIX)) {
75
- const relativePath = schemaPath.slice(PATH_ALIAS_PREFIX.length);
76
- // First try workspace root, then fall back to basePath traversal
77
- if (workspaceRoot) {
78
- return path.resolve(workspaceRoot, DEFAULT_CONTRACTS_FOLDER, relativePath);
79
- }
80
- // If no workspace root, try to find contracts folder by walking up
81
- if (basePath) {
82
- let currentDir = basePath;
83
- let attempts = 0;
84
- while (attempts < 10) {
85
- const contractsPath = path.join(currentDir, DEFAULT_CONTRACTS_FOLDER, relativePath);
86
- if (fs.existsSync(path.dirname(contractsPath))) {
87
- return contractsPath;
88
- }
89
- const parentDir = path.dirname(currentDir);
90
- if (parentDir === currentDir) {
91
- break;
92
- }
93
- currentDir = parentDir;
94
- attempts++;
95
- }
96
- }
97
- // Fallback: just use contracts/ relative to basePath
98
- if (basePath) {
99
- return path.resolve(basePath, DEFAULT_CONTRACTS_FOLDER, relativePath);
100
- }
101
- return schemaPath; // Can't resolve
102
- }
103
- // Regular relative/absolute path handling
104
- if (path.isAbsolute(schemaPath)) {
105
- return schemaPath;
106
- }
107
- if (basePath) {
108
- return path.resolve(basePath, schemaPath);
109
- }
110
- return schemaPath;
111
- }
112
- /**
113
- * Generate a JSON Schema (draft-07) from a sample value
114
- */
115
- function generateJsonSchema(value, title) {
116
- const schema = {
117
- $schema: 'http://json-schema.org/draft-07/schema#',
118
- };
119
- if (title) {
120
- schema.title = title;
121
- }
122
- const typeSchema = inferType(value);
123
- Object.assign(schema, typeSchema);
124
- return schema;
125
- }
126
- /**
127
- * Infer JSON Schema type information from a value
128
- */
129
- function inferType(value) {
130
- if (value === null) {
131
- return { type: 'null' };
132
- }
133
- if (Array.isArray(value)) {
134
- if (value.length === 0) {
135
- return { type: 'array', items: {} };
136
- }
137
- // Infer from first item (could be enhanced to merge schemas)
138
- return {
139
- type: 'array',
140
- items: inferType(value[0])
141
- };
142
- }
143
- if (typeof value === 'object') {
144
- const properties = {};
145
- const required = [];
146
- for (const key of Object.keys(value)) {
147
- properties[key] = inferType(value[key]);
148
- // Mark all properties as required by default
149
- required.push(key);
150
- }
151
- return {
152
- type: 'object',
153
- properties,
154
- required: required.length > 0 ? required : undefined,
155
- additionalProperties: true
156
- };
157
- }
158
- if (typeof value === 'string') {
159
- return { type: 'string' };
160
- }
161
- if (typeof value === 'number') {
162
- return Number.isInteger(value) ? { type: 'integer' } : { type: 'number' };
163
- }
164
- if (typeof value === 'boolean') {
165
- return { type: 'boolean' };
166
- }
167
- return {};
168
- }
169
- /**
170
- * Convert Ajv ErrorObject to rich SchemaValidationError
171
- */
172
- function convertAjvError(err, value) {
173
- let instancePath = err.instancePath || '(root)';
174
- // Determine expected value based on keyword
175
- let expected;
176
- let actual = undefined;
177
- switch (err.keyword) {
178
- case 'type':
179
- expected = err.params.type;
180
- actual = getValueAtPath(value, instancePath);
181
- break;
182
- case 'required':
183
- expected = `property "${err.params.missingProperty}" to exist`;
184
- if (typeof err.params.missingProperty === 'string') {
185
- instancePath = appendJsonPointerPath(instancePath, err.params.missingProperty);
186
- }
187
- break;
188
- case 'enum':
189
- expected = `one of: ${err.params.allowedValues?.join(', ')}`;
190
- actual = getValueAtPath(value, instancePath);
191
- break;
192
- case 'pattern':
193
- expected = `to match pattern "${err.params.pattern}"`;
194
- actual = getValueAtPath(value, instancePath);
195
- break;
196
- case 'minLength':
197
- expected = `length >= ${err.params.limit}`;
198
- actual = getValueAtPath(value, instancePath);
199
- break;
200
- case 'maxLength':
201
- expected = `length <= ${err.params.limit}`;
202
- actual = getValueAtPath(value, instancePath);
203
- break;
204
- case 'minimum':
205
- case 'exclusiveMinimum':
206
- expected = `>= ${err.params.limit}`;
207
- actual = getValueAtPath(value, instancePath);
208
- break;
209
- case 'maximum':
210
- case 'exclusiveMaximum':
211
- expected = `<= ${err.params.limit}`;
212
- actual = getValueAtPath(value, instancePath);
213
- break;
214
- case 'additionalProperties':
215
- expected = `no additional property "${err.params.additionalProperty}"`;
216
- if (typeof err.params.additionalProperty === 'string') {
217
- instancePath = appendJsonPointerPath(instancePath, err.params.additionalProperty);
218
- actual = getValueAtPath(value, instancePath);
219
- }
220
- break;
221
- case 'format':
222
- expected = `format "${err.params.format}"`;
223
- actual = getValueAtPath(value, instancePath);
224
- break;
225
- default:
226
- if (err.params) {
227
- expected = JSON.stringify(err.params);
228
- }
229
- actual = getValueAtPath(value, instancePath);
230
- }
231
- // Determine severity based on keyword
232
- let severity = 'error';
233
- if (err.keyword === 'additionalProperties') {
234
- severity = 'warning'; // Extra properties are often okay
235
- }
236
- return {
237
- instancePath,
238
- schemaPath: err.schemaPath,
239
- keyword: err.keyword,
240
- message: err.message || 'Validation failed',
241
- params: err.params,
242
- expected,
243
- actual,
244
- severity
245
- };
246
- }
247
- function appendJsonPointerPath(basePath, propertyName) {
248
- const normalizedBasePath = !basePath || basePath === '(root)' ? '' : basePath;
249
- const escapedPropertyName = propertyName.replace(/~/g, '~0').replace(/\//g, '~1');
250
- return `${normalizedBasePath}/${escapedPropertyName}`;
251
- }
252
- /**
253
- * Get value at a JSON pointer path
254
- */
255
- function getValueAtPath(obj, jsonPointer) {
256
- if (jsonPointer === '(root)' || jsonPointer === '' || jsonPointer === '/') {
257
- return obj;
258
- }
259
- // Remove leading slash and split
260
- const parts = jsonPointer.replace(/^\//, '').split('/');
261
- let current = obj;
262
- for (const part of parts) {
263
- if (current === null || current === undefined) {
264
- return undefined;
265
- }
266
- // Decode JSON Pointer escapes
267
- const key = part.replace(/~1/g, '/').replace(/~0/g, '~');
268
- current = current[key];
269
- }
270
- return current;
271
- }
272
- const SCHEMA_RULE_KEYWORDS = new Set([
273
- 'type',
274
- 'enum',
275
- 'const',
276
- 'multipleOf',
277
- 'maximum',
278
- 'exclusiveMaximum',
279
- 'minimum',
280
- 'exclusiveMinimum',
281
- 'maxLength',
282
- 'minLength',
283
- 'pattern',
284
- 'format',
285
- 'maxItems',
286
- 'minItems',
287
- 'uniqueItems',
288
- 'maxContains',
289
- 'minContains',
290
- 'maxProperties',
291
- 'minProperties',
292
- 'propertyNames',
293
- 'dependentRequired',
294
- ]);
295
- const SCHEMA_MAP_KEYWORDS = new Set([
296
- 'properties',
297
- 'patternProperties',
298
- 'dependentSchemas',
299
- '$defs',
300
- 'definitions',
301
- ]);
302
- const SCHEMA_ARRAY_KEYWORDS = new Set(['allOf', 'anyOf', 'oneOf']);
303
- const SCHEMA_NESTED_SCHEMA_KEYWORDS = new Set(['items', 'prefixItems', 'additionalItems', 'contains', 'not', 'if', 'then', 'else']);
304
- function isRecord(value) {
305
- return typeof value === 'object' && value !== null && !Array.isArray(value);
306
- }
307
- function countSchemaRules(schema) {
308
- if (Array.isArray(schema)) {
309
- return schema.reduce((sum, item) => sum + countSchemaRules(item), 0);
310
- }
311
- if (!isRecord(schema)) {
312
- return 0;
313
- }
314
- let count = 0;
315
- for (const [key, value] of Object.entries(schema)) {
316
- if (key === 'required' && Array.isArray(value)) {
317
- count += value.length;
318
- continue;
319
- }
320
- if (SCHEMA_MAP_KEYWORDS.has(key)) {
321
- if (isRecord(value)) {
322
- for (const childSchema of Object.values(value)) {
323
- count += countSchemaRules(childSchema);
324
- }
325
- }
326
- continue;
327
- }
328
- if (SCHEMA_ARRAY_KEYWORDS.has(key)) {
329
- count += 1;
330
- count += countSchemaRules(value);
331
- continue;
332
- }
333
- if (key === 'additionalProperties' || key === 'unevaluatedProperties') {
334
- if (value !== true) {
335
- count += 1;
336
- }
337
- if (isRecord(value)) {
338
- count += countSchemaRules(value);
339
- }
340
- continue;
341
- }
342
- if (SCHEMA_NESTED_SCHEMA_KEYWORDS.has(key)) {
343
- if (key !== 'items' && key !== 'prefixItems') {
344
- count += 1;
345
- }
346
- count += countSchemaRules(value);
347
- continue;
348
- }
349
- if (SCHEMA_RULE_KEYWORDS.has(key)) {
350
- count += 1;
351
- }
352
- }
353
- return count;
354
- }
355
- function buildValidationSummary(schema, errors, valid) {
356
- const issueCount = errors?.length || 0;
357
- const errorCount = errors?.filter(error => error.severity === 'error').length || 0;
358
- const warningCount = errors?.filter(error => error.severity === 'warning').length || 0;
359
- const totalRules = Math.max(schema ? countSchemaRules(schema) : 0, issueCount);
360
- const failedRules = valid ? 0 : issueCount;
361
- return {
362
- totalRules,
363
- passedRules: Math.max(totalRules - failedRules, 0),
364
- failedRules,
365
- issueCount,
366
- errorCount,
367
- warningCount
368
- };
369
- }
370
- /**
371
- * Validate a value against a JSON Schema file with detailed error information
372
- * @param value The value to validate
373
- * @param schemaPath Absolute or relative path to the schema file (supports @/ alias for contracts/)
374
- * @param basePath Base path for resolving relative schema paths
375
- * @param workspaceRoot Optional workspace root for @/ alias resolution
376
- * @returns Detailed result with rich error objects for Contract View
377
- */
378
- function validateAgainstSchemaDetailed(value, schemaPath, basePath, workspaceRoot) {
379
- try {
380
- // Resolve schema path (handles @/ alias for contracts folder)
381
- const resolvedPath = resolveSchemaPath(schemaPath, basePath, workspaceRoot);
382
- // Check if file exists
383
- if (!fs.existsSync(resolvedPath)) {
384
- const errors = [{
385
- instancePath: '(root)',
386
- schemaPath: '',
387
- keyword: 'file',
388
- message: `Schema file not found: ${schemaPath}`,
389
- params: { path: schemaPath },
390
- severity: 'error'
391
- }];
392
- return {
393
- valid: false,
394
- errors,
395
- errorStrings: [`Schema file not found: ${schemaPath}`],
396
- resolvedSchemaPath: resolvedPath,
397
- summary: buildValidationSummary(undefined, errors, false)
398
- };
399
- }
400
- // Load and parse schema
401
- const schemaContent = fs.readFileSync(resolvedPath, 'utf-8');
402
- let schema;
403
- try {
404
- schema = JSON.parse(schemaContent);
405
- }
406
- catch (e) {
407
- const errors = [{
408
- instancePath: '(root)',
409
- schemaPath: '',
410
- keyword: 'parse',
411
- message: `Invalid JSON in schema file: ${schemaPath}`,
412
- params: { path: schemaPath },
413
- severity: 'error'
414
- }];
415
- return {
416
- valid: false,
417
- errors,
418
- errorStrings: [`Invalid JSON in schema file: ${schemaPath}`],
419
- resolvedSchemaPath: resolvedPath,
420
- summary: buildValidationSummary(undefined, errors, false)
421
- };
422
- }
423
- // Validate
424
- const validate = ajv.compile(schema);
425
- const valid = validate(value);
426
- if (!valid && validate.errors) {
427
- const errors = validate.errors.map(err => convertAjvError(err, value));
428
- const errorStrings = validate.errors.map(err => {
429
- const path = err.instancePath || '(root)';
430
- return `${path}: ${err.message}`;
431
- });
432
- return {
433
- valid: false,
434
- errors,
435
- errorStrings,
436
- resolvedSchemaPath: resolvedPath,
437
- schema,
438
- summary: buildValidationSummary(schema, errors, false)
439
- };
440
- }
441
- return {
442
- valid: true,
443
- resolvedSchemaPath: resolvedPath,
444
- schema,
445
- summary: buildValidationSummary(schema, undefined, true)
446
- };
447
- }
448
- catch (e) {
449
- const error = e instanceof Error ? e.message : String(e);
450
- const errors = [{
451
- instancePath: '(root)',
452
- schemaPath: '',
453
- keyword: 'exception',
454
- message: `Schema validation error: ${error}`,
455
- params: {},
456
- severity: 'error'
457
- }];
458
- return {
459
- valid: false,
460
- errors,
461
- errorStrings: [`Schema validation error: ${error}`],
462
- summary: buildValidationSummary(undefined, errors, false)
463
- };
464
- }
465
- }
466
- function validateAgainstSchemaObjectDetailed(value, schema) {
467
- try {
468
- const validate = ajv.compile(schema);
469
- const valid = validate(value);
470
- if (!valid && validate.errors) {
471
- const errors = validate.errors.map(err => convertAjvError(err, value));
472
- const errorStrings = validate.errors.map(err => {
473
- const path = err.instancePath || '(root)';
474
- return `${path}: ${err.message}`;
475
- });
476
- return {
477
- valid: false,
478
- errors,
479
- errorStrings,
480
- schema,
481
- summary: buildValidationSummary(schema, errors, false)
482
- };
483
- }
484
- return {
485
- valid: true,
486
- schema,
487
- summary: buildValidationSummary(schema, undefined, true)
488
- };
489
- }
490
- catch (e) {
491
- const error = e instanceof Error ? e.message : String(e);
492
- const errors = [{
493
- instancePath: '(root)',
494
- schemaPath: '',
495
- keyword: 'exception',
496
- message: `Schema validation error: ${error}`,
497
- params: {},
498
- severity: 'error'
499
- }];
500
- return {
501
- valid: false,
502
- errors,
503
- errorStrings: [`Schema validation error: ${error}`],
504
- schema,
505
- summary: buildValidationSummary(schema, errors, false)
506
- };
507
- }
508
- }
509
- /**
510
- * Validate a value against a JSON Schema file
511
- * @param value The value to validate
512
- * @param schemaPath Absolute or relative path to the schema file
513
- * @param basePath Base path for resolving relative schema paths
514
- * @returns Object with valid flag and optional errors (backward compatible)
515
- */
516
- function validateAgainstSchema(value, schemaPath, basePath) {
517
- const result = validateAgainstSchemaDetailed(value, schemaPath, basePath);
518
- return {
519
- valid: result.valid,
520
- errors: result.errorStrings
521
- };
522
- }
523
- /**
524
- * Generate a schema file name from an endpoint URL
525
- * Example: "GET /api/users/{id}" => "GET-api-users-id"
526
- */
527
- function generateSchemaFileName(method, url) {
528
- // Extract path from URL (remove protocol, host, query string)
529
- let urlPath = url;
530
- try {
531
- const parsed = new URL(url);
532
- urlPath = parsed.pathname;
533
- }
534
- catch {
535
- // URL might be a relative path, try to extract just the path part
536
- const queryIndex = url.indexOf('?');
537
- if (queryIndex > -1) {
538
- urlPath = url.substring(0, queryIndex);
539
- }
540
- }
541
- // Clean up the path
542
- const cleanPath = urlPath
543
- .replace(/^\/+|\/+$/g, '') // Remove leading/trailing slashes
544
- .replace(/\{[^}]+\}/g, 'param') // {id} => param
545
- .replace(/[^a-zA-Z0-9-]/g, '-') // Replace non-alphanumeric with dash
546
- .replace(/-+/g, '-') // Collapse multiple dashes
547
- .replace(/^-|-$/g, ''); // Remove leading/trailing dashes
548
- return `${method.toUpperCase()}-${cleanPath || 'root'}.schema.json`;
549
- }
550
- /**
551
- * Save a schema to a file
552
- * @param schema The JSON Schema object
553
- * @param filePath Absolute path to save the schema
554
- */
555
- function saveSchema(schema, filePath) {
556
- const dir = path.dirname(filePath);
557
- if (!fs.existsSync(dir)) {
558
- fs.mkdirSync(dir, { recursive: true });
559
- }
560
- fs.writeFileSync(filePath, JSON.stringify(schema, null, 2), 'utf-8');
561
- }
562
- //# sourceMappingURL=schemaGenerator.js.map