norn-cli 2.3.0 → 2.4.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.
- package/.claude/skills/norn-social-campaign/SKILL.md +70 -0
- package/CHANGELOG.md +6 -0
- package/demos/nornenv-region-refactor/README.md +64 -0
- package/dist/cli.js +360 -1
- package/out/apiResponseIntellisenseCache.js +394 -0
- package/out/assertionRunner.js +567 -0
- package/out/cacheDir.js +136 -0
- package/out/chatParticipant.js +763 -0
- package/out/cli/colors.js +127 -0
- package/out/cli/formatters/assertion.js +102 -0
- package/out/cli/formatters/index.js +23 -0
- package/out/cli/formatters/response.js +106 -0
- package/out/cli/formatters/summary.js +246 -0
- package/out/cli/redaction.js +237 -0
- package/out/cli/reporters/html.js +689 -0
- package/out/cli/reporters/index.js +22 -0
- package/out/cli/reporters/junit.js +226 -0
- package/out/codeLensProvider.js +351 -0
- package/out/compareContentProvider.js +85 -0
- package/out/completionProvider.js +3739 -0
- package/out/contractAssertionSummary.js +225 -0
- package/out/contractDecorationProvider.js +243 -0
- package/out/coverageCalculator.js +879 -0
- package/out/coveragePanel.js +597 -0
- package/out/debug/breakpointResolver.js +84 -0
- package/out/debug/breakpoints.js +52 -0
- package/out/debug/nornDebugAdapter.js +166 -0
- package/out/debug/nornDebugSession.js +613 -0
- package/out/debug/sequenceLocationIndex.js +77 -0
- package/out/debug/types.js +3 -0
- package/out/deepClone.js +21 -0
- package/out/diagnosticProvider.js +2554 -0
- package/out/environmentParser.js +736 -0
- package/out/environmentProvider.js +544 -0
- package/out/environmentTemplates.js +146 -0
- package/out/errors/formatError.js +113 -0
- package/out/errors/nornError.js +29 -0
- package/out/formUrlEncoded.js +89 -0
- package/out/httpClient.js +348 -0
- package/out/httpRuntimeOptions.js +16 -0
- package/out/importErrors.js +31 -0
- package/out/inlayHintResolver.js +70 -0
- package/out/jsonFileReader.js +323 -0
- package/out/mcpClient.js +193 -0
- package/out/mcpConfig.js +184 -0
- package/out/mcpToolIntellisenseCache.js +96 -0
- package/out/mcpToolSchema.js +50 -0
- package/out/nornConfig.js +132 -0
- package/out/nornHoverProvider.js +124 -0
- package/out/nornInlayHintsProvider.js +191 -0
- package/out/nornPrompt.js +755 -0
- package/out/nornSqlParser.js +286 -0
- package/out/nornapiHoverProvider.js +135 -0
- package/out/nornapiInlayHintsProvider.js +94 -0
- package/out/nornapiParser.js +324 -0
- package/out/nornenvCodeActionProvider.js +101 -0
- package/out/nornenvDecorationProvider.js +239 -0
- package/out/nornenvFoldingProvider.js +63 -0
- package/out/nornenvHoverProvider.js +114 -0
- package/out/nornenvInlayHintsProvider.js +99 -0
- package/out/nornenvLanguageModel.js +187 -0
- package/out/nornenvRegionRefactor.js +267 -0
- package/out/nornsqlHoverProvider.js +95 -0
- package/out/nornsqlInlayHintsProvider.js +114 -0
- package/out/parser.js +839 -0
- package/out/pathAccess.js +28 -0
- package/out/postmanImportPanel.js +732 -0
- package/out/postmanImportPlanner.js +1155 -0
- package/out/postmanImportSidebarView.js +532 -0
- package/out/quotedString.js +35 -0
- package/out/requestPreparation.js +179 -0
- package/out/requestValidation.js +146 -0
- package/out/responsePanel.js +7754 -0
- package/out/schemaGenerator.js +562 -0
- package/out/scriptRunner.js +419 -0
- package/out/secrets/cliSecrets.js +415 -0
- package/out/secrets/crypto.js +105 -0
- package/out/secrets/envFileSecrets.js +177 -0
- package/out/secrets/keyStore.js +259 -0
- package/out/sequenceDeclaration.js +15 -0
- package/out/sequenceRunner.js +3590 -0
- package/out/sqlAdapterRunner.js +122 -0
- package/out/sqlBuiltInAdapters.js +604 -0
- package/out/sqlConfig.js +184 -0
- package/out/starterCatalog.js +554 -0
- package/out/stringUtils.js +25 -0
- package/out/swaggerBodyIntellisenseCache.js +114 -0
- package/out/swaggerParser.js +464 -0
- package/out/testProvider.js +767 -0
- package/out/theoryCaseLoader.js +113 -0
- package/out/validationCache.js +211 -0
- package/package.json +6 -1
|
@@ -0,0 +1,225 @@
|
|
|
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.buildContractAssertionDisplay = buildContractAssertionDisplay;
|
|
37
|
+
exports.buildContractValidationList = buildContractValidationList;
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
function buildContractAssertionDisplay(assertion, maxIssues = 3, maxValidatedItems = 24) {
|
|
40
|
+
if (assertion.operator !== 'matchesSchema') {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
const issueCount = assertion.schemaSummary?.issueCount ?? assertion.schemaErrors?.length ?? (assertion.error ? 1 : 0);
|
|
44
|
+
const schemaPath = assertion.schemaPath || (typeof assertion.rightValue === 'string' ? assertion.rightValue : undefined);
|
|
45
|
+
const schemaName = schemaPath ? path.basename(schemaPath) : undefined;
|
|
46
|
+
const issueTexts = (assertion.schemaErrors || [])
|
|
47
|
+
.slice(0, maxIssues)
|
|
48
|
+
.map(formatSchemaIssue);
|
|
49
|
+
const validationList = buildContractValidationList(assertion.schema, assertion.schemaErrors || [], maxValidatedItems);
|
|
50
|
+
const failedValidationCount = validationList.failedCount || (!assertion.passed && issueCount > 0 ? 1 : 0);
|
|
51
|
+
const totalValidations = validationList.totalCount + failedValidationCount;
|
|
52
|
+
const passedValidations = assertion.passed ? totalValidations : validationList.totalCount;
|
|
53
|
+
let summaryText;
|
|
54
|
+
if (totalValidations > 0) {
|
|
55
|
+
summaryText = `${passedValidations}/${totalValidations} validations passed`;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
summaryText = assertion.passed ? 'contract passed' : 'contract validation failed';
|
|
59
|
+
}
|
|
60
|
+
if (issueCount > 0) {
|
|
61
|
+
summaryText += `, ${issueCount} issue${issueCount === 1 ? '' : 's'}`;
|
|
62
|
+
}
|
|
63
|
+
const titleText = schemaName
|
|
64
|
+
? `${schemaName}: ${summaryText}`
|
|
65
|
+
: `Contract: ${summaryText}`;
|
|
66
|
+
const validationText = totalValidations > 0
|
|
67
|
+
? `${passedValidations}/${totalValidations} validations`
|
|
68
|
+
: (assertion.passed ? 'validated' : `${issueCount} issue${issueCount === 1 ? '' : 's'}`);
|
|
69
|
+
const severity = getContractDisplaySeverity(assertion);
|
|
70
|
+
return {
|
|
71
|
+
titleText,
|
|
72
|
+
summaryText,
|
|
73
|
+
validationText,
|
|
74
|
+
severity,
|
|
75
|
+
schemaPath,
|
|
76
|
+
schemaName,
|
|
77
|
+
issueTexts,
|
|
78
|
+
remainingIssueCount: Math.max(issueCount - issueTexts.length, 0),
|
|
79
|
+
validatedItems: validationList.items,
|
|
80
|
+
remainingValidatedCount: validationList.remainingCount,
|
|
81
|
+
totalValidatedCount: validationList.totalCount
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function buildContractValidationList(schema, errors = [], maxItems = 24) {
|
|
85
|
+
const failedPaths = new Set(errors.map(getComparableErrorPath));
|
|
86
|
+
const allItems = collectContractValidationItems(schema)
|
|
87
|
+
.filter(item => !isFailedValidationPath(item.comparablePath, failedPaths));
|
|
88
|
+
const items = allItems.slice(0, maxItems).map(({ comparablePath: _comparablePath, ...item }) => item);
|
|
89
|
+
return {
|
|
90
|
+
items,
|
|
91
|
+
totalCount: allItems.length,
|
|
92
|
+
remainingCount: Math.max(allItems.length - items.length, 0),
|
|
93
|
+
failedCount: failedPaths.size
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const RULE_LABELS = {
|
|
97
|
+
type: value => `type: ${Array.isArray(value) ? value.join(' | ') : String(value)}`,
|
|
98
|
+
format: value => `format: ${String(value)}`,
|
|
99
|
+
enum: () => 'enum',
|
|
100
|
+
const: () => 'const',
|
|
101
|
+
pattern: () => 'pattern',
|
|
102
|
+
minimum: value => `min: ${String(value)}`,
|
|
103
|
+
exclusiveMinimum: value => `exclusive min: ${String(value)}`,
|
|
104
|
+
maximum: value => `max: ${String(value)}`,
|
|
105
|
+
exclusiveMaximum: value => `exclusive max: ${String(value)}`,
|
|
106
|
+
minLength: value => `min length: ${String(value)}`,
|
|
107
|
+
maxLength: value => `max length: ${String(value)}`,
|
|
108
|
+
minItems: value => `min items: ${String(value)}`,
|
|
109
|
+
maxItems: value => `max items: ${String(value)}`,
|
|
110
|
+
uniqueItems: () => 'unique items',
|
|
111
|
+
minProperties: value => `min properties: ${String(value)}`,
|
|
112
|
+
maxProperties: value => `max properties: ${String(value)}`,
|
|
113
|
+
multipleOf: value => `multiple of: ${String(value)}`
|
|
114
|
+
};
|
|
115
|
+
function collectContractValidationItems(schema, comparablePath = '', inheritedRules = []) {
|
|
116
|
+
if (!isRecord(schema)) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
const items = [];
|
|
120
|
+
const ownRules = getSchemaRuleLabels(schema);
|
|
121
|
+
const rules = [...inheritedRules, ...ownRules];
|
|
122
|
+
if (comparablePath && rules.length > 0) {
|
|
123
|
+
items.push({
|
|
124
|
+
comparablePath,
|
|
125
|
+
path: formatComparablePath(comparablePath),
|
|
126
|
+
rules
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
else if (!comparablePath && rules.length > 0 && !schema.properties && !schema.items) {
|
|
130
|
+
items.push({
|
|
131
|
+
comparablePath: '/',
|
|
132
|
+
path: '(root)',
|
|
133
|
+
rules
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (isRecord(schema.properties)) {
|
|
137
|
+
const required = Array.isArray(schema.required) ? new Set(schema.required.map(String)) : new Set();
|
|
138
|
+
for (const [propertyName, propertySchema] of Object.entries(schema.properties)) {
|
|
139
|
+
const childPath = appendPropertyPath(comparablePath, propertyName);
|
|
140
|
+
const childRules = required.has(propertyName) ? ['required'] : [];
|
|
141
|
+
items.push(...collectContractValidationItems(propertySchema, childPath, childRules));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (isRecord(schema.items)) {
|
|
145
|
+
items.push(...collectContractValidationItems(schema.items, appendArrayPath(comparablePath), []));
|
|
146
|
+
}
|
|
147
|
+
return items;
|
|
148
|
+
}
|
|
149
|
+
function getSchemaRuleLabels(schema) {
|
|
150
|
+
const rules = [];
|
|
151
|
+
for (const [keyword, formatter] of Object.entries(RULE_LABELS)) {
|
|
152
|
+
if (schema[keyword] !== undefined) {
|
|
153
|
+
rules.push(formatter(schema[keyword]));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (schema.additionalProperties === false) {
|
|
157
|
+
rules.push('no extra properties');
|
|
158
|
+
}
|
|
159
|
+
return rules;
|
|
160
|
+
}
|
|
161
|
+
function appendPropertyPath(basePath, propertyName) {
|
|
162
|
+
return `${basePath || ''}/${propertyName.replace(/~/g, '~0').replace(/\//g, '~1')}`;
|
|
163
|
+
}
|
|
164
|
+
function appendArrayPath(basePath) {
|
|
165
|
+
return `${basePath || ''}/[]`;
|
|
166
|
+
}
|
|
167
|
+
function formatComparablePath(comparablePath) {
|
|
168
|
+
return comparablePath.replace(/\/\[\]/g, '[]').replace(/~1/g, '/').replace(/~0/g, '~');
|
|
169
|
+
}
|
|
170
|
+
function getComparableErrorPath(error) {
|
|
171
|
+
let instancePath = error.instancePath && error.instancePath !== '(root)'
|
|
172
|
+
? error.instancePath
|
|
173
|
+
: '';
|
|
174
|
+
if (error.keyword === 'required' && typeof error.params?.missingProperty === 'string') {
|
|
175
|
+
instancePath = appendErrorPropertyPath(instancePath, error.params.missingProperty);
|
|
176
|
+
}
|
|
177
|
+
else if (error.keyword === 'additionalProperties' && typeof error.params?.additionalProperty === 'string') {
|
|
178
|
+
instancePath = appendErrorPropertyPath(instancePath, error.params.additionalProperty);
|
|
179
|
+
}
|
|
180
|
+
return normalizeComparablePath(instancePath || '/');
|
|
181
|
+
}
|
|
182
|
+
function appendErrorPropertyPath(instancePath, propertyName) {
|
|
183
|
+
const normalizedPath = instancePath && instancePath !== '(root)' && instancePath !== '/' ? instancePath : '';
|
|
184
|
+
const escapedPropertyName = propertyName.replace(/~/g, '~0').replace(/\//g, '~1');
|
|
185
|
+
const lastSegment = normalizedPath.split('/').pop();
|
|
186
|
+
return lastSegment === escapedPropertyName
|
|
187
|
+
? normalizedPath
|
|
188
|
+
: `${normalizedPath}/${escapedPropertyName}`;
|
|
189
|
+
}
|
|
190
|
+
function normalizeComparablePath(instancePath) {
|
|
191
|
+
if (!instancePath || instancePath === '(root)' || instancePath === '/') {
|
|
192
|
+
return '/';
|
|
193
|
+
}
|
|
194
|
+
return instancePath
|
|
195
|
+
.split('/')
|
|
196
|
+
.map(segment => (/^\d+$/.test(segment) ? '[]' : segment))
|
|
197
|
+
.join('/');
|
|
198
|
+
}
|
|
199
|
+
function isFailedValidationPath(comparablePath, failedPaths) {
|
|
200
|
+
for (const failedPath of failedPaths) {
|
|
201
|
+
if (comparablePath === failedPath || comparablePath.startsWith(`${failedPath}/`)) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
function isRecord(value) {
|
|
208
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
209
|
+
}
|
|
210
|
+
function formatSchemaIssue(error) {
|
|
211
|
+
const location = error.instancePath && error.instancePath !== '(root)'
|
|
212
|
+
? error.instancePath
|
|
213
|
+
: '';
|
|
214
|
+
return location ? `${location}: ${error.message}` : error.message;
|
|
215
|
+
}
|
|
216
|
+
function getContractDisplaySeverity(assertion) {
|
|
217
|
+
if (assertion.passed) {
|
|
218
|
+
return 'success';
|
|
219
|
+
}
|
|
220
|
+
const schemaErrors = assertion.schemaErrors || [];
|
|
221
|
+
return schemaErrors.length > 0 && schemaErrors.every(error => error.severity === 'warning')
|
|
222
|
+
? 'warning'
|
|
223
|
+
: 'error';
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=contractAssertionSummary.js.map
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Contract Decoration Provider - Visual indicators for schema assertion lines
|
|
4
|
+
* Shows pass/fail/stale status as colored decorations in the editor gutter
|
|
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.ContractDecorationProvider = void 0;
|
|
41
|
+
exports.createContractHoverProvider = createContractHoverProvider;
|
|
42
|
+
const vscode = __importStar(require("vscode"));
|
|
43
|
+
const validationCache_1 = require("./validationCache");
|
|
44
|
+
/**
|
|
45
|
+
* Creates decoration types with appropriate colors and icons
|
|
46
|
+
*/
|
|
47
|
+
function createDecorationTypes() {
|
|
48
|
+
return {
|
|
49
|
+
pass: vscode.window.createTextEditorDecorationType({
|
|
50
|
+
gutterIconPath: vscode.Uri.parse('data:image/svg+xml,' + encodeURIComponent(`
|
|
51
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#4ec9b0">
|
|
52
|
+
<path d="M4 2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H4zm1 2h6v1H5V4zm0 2h6v1H5V6zm0 2h4v1H5V8z"/>
|
|
53
|
+
<path d="M10.5 10l-2 2-1-1-.7.7 1.7 1.7 2.7-2.7-.7-.7z"/>
|
|
54
|
+
</svg>
|
|
55
|
+
`)),
|
|
56
|
+
gutterIconSize: 'contain',
|
|
57
|
+
backgroundColor: 'rgba(78, 201, 176, 0.08)',
|
|
58
|
+
isWholeLine: true,
|
|
59
|
+
overviewRulerColor: '#4ec9b0',
|
|
60
|
+
overviewRulerLane: vscode.OverviewRulerLane.Right
|
|
61
|
+
}),
|
|
62
|
+
fail: vscode.window.createTextEditorDecorationType({
|
|
63
|
+
gutterIconPath: vscode.Uri.parse('data:image/svg+xml,' + encodeURIComponent(`
|
|
64
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#f14c4c">
|
|
65
|
+
<path d="M4 2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H4zm1 2h6v1H5V4zm0 2h6v1H5V6zm0 2h4v1H5V8z"/>
|
|
66
|
+
<path d="M9.5 10l1.5 1.5-1 1-1.5-1.5-1.5 1.5-1-1 1.5-1.5-1.5-1.5 1-1 1.5 1.5 1.5-1.5 1 1-1.5 1.5z"/>
|
|
67
|
+
</svg>
|
|
68
|
+
`)),
|
|
69
|
+
gutterIconSize: 'contain',
|
|
70
|
+
backgroundColor: 'rgba(241, 76, 76, 0.1)',
|
|
71
|
+
isWholeLine: true,
|
|
72
|
+
overviewRulerColor: '#f14c4c',
|
|
73
|
+
overviewRulerLane: vscode.OverviewRulerLane.Right
|
|
74
|
+
}),
|
|
75
|
+
warn: vscode.window.createTextEditorDecorationType({
|
|
76
|
+
gutterIconPath: vscode.Uri.parse('data:image/svg+xml,' + encodeURIComponent(`
|
|
77
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#cca700">
|
|
78
|
+
<path d="M4 2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H4zm1 2h6v1H5V4zm0 2h6v1H5V6zm0 2h4v1H5V8z"/>
|
|
79
|
+
<path d="M10.5 10.5a.5.5 0 0 1-1 0v-1a.5.5 0 0 1 1 0v1zm-.5 2a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1z"/>
|
|
80
|
+
</svg>
|
|
81
|
+
`)),
|
|
82
|
+
gutterIconSize: 'contain',
|
|
83
|
+
backgroundColor: 'rgba(204, 167, 0, 0.08)',
|
|
84
|
+
isWholeLine: true,
|
|
85
|
+
overviewRulerColor: '#cca700',
|
|
86
|
+
overviewRulerLane: vscode.OverviewRulerLane.Right
|
|
87
|
+
}),
|
|
88
|
+
stale: vscode.window.createTextEditorDecorationType({
|
|
89
|
+
gutterIconPath: vscode.Uri.parse('data:image/svg+xml,' + encodeURIComponent(`
|
|
90
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#808080">
|
|
91
|
+
<path d="M4 2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H4zm1 2h6v1H5V4zm0 2h6v1H5V6zm0 2h4v1H5V8z"/>
|
|
92
|
+
<path d="M10.5 10.5a.5.5 0 0 1-1 0v-1a.5.5 0 0 1 1 0v1zm-.5 2a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1z"/>
|
|
93
|
+
</svg>
|
|
94
|
+
`)),
|
|
95
|
+
gutterIconSize: 'contain',
|
|
96
|
+
backgroundColor: 'rgba(128, 128, 128, 0.05)',
|
|
97
|
+
isWholeLine: true,
|
|
98
|
+
overviewRulerColor: '#808080',
|
|
99
|
+
overviewRulerLane: vscode.OverviewRulerLane.Right
|
|
100
|
+
}),
|
|
101
|
+
unknown: vscode.window.createTextEditorDecorationType({
|
|
102
|
+
gutterIconPath: vscode.Uri.parse('data:image/svg+xml,' + encodeURIComponent(`
|
|
103
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="#808080" opacity="0.5">
|
|
104
|
+
<path d="M4 2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H4zm1 2h6v1H5V4zm0 2h6v1H5V6zm0 2h4v1H5V8z" stroke="#808080" stroke-dasharray="2,2" fill="none"/>
|
|
105
|
+
</svg>
|
|
106
|
+
`)),
|
|
107
|
+
gutterIconSize: 'contain'
|
|
108
|
+
})
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Pattern to match matchesSchema assertions
|
|
113
|
+
*/
|
|
114
|
+
const MATCHES_SCHEMA_PATTERN = /^\s*assert\s+.+\s+matchesSchema\s+/i;
|
|
115
|
+
/**
|
|
116
|
+
* Find all matchesSchema assertion lines in a document
|
|
117
|
+
*/
|
|
118
|
+
function findSchemaAssertionLines(document) {
|
|
119
|
+
const lines = [];
|
|
120
|
+
for (let i = 0; i < document.lineCount; i++) {
|
|
121
|
+
const lineText = document.lineAt(i).text;
|
|
122
|
+
if (MATCHES_SCHEMA_PATTERN.test(lineText)) {
|
|
123
|
+
lines.push(i);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return lines;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Contract Decoration Provider class
|
|
130
|
+
*/
|
|
131
|
+
class ContractDecorationProvider {
|
|
132
|
+
decorationTypes;
|
|
133
|
+
disposables = [];
|
|
134
|
+
constructor() {
|
|
135
|
+
this.decorationTypes = createDecorationTypes();
|
|
136
|
+
// Update decorations when active editor changes
|
|
137
|
+
this.disposables.push(vscode.window.onDidChangeActiveTextEditor(editor => {
|
|
138
|
+
if (editor?.document.languageId === 'norn') {
|
|
139
|
+
this.updateDecorations(editor);
|
|
140
|
+
}
|
|
141
|
+
}));
|
|
142
|
+
// Update decorations when document changes (with debounce)
|
|
143
|
+
let updateTimeout;
|
|
144
|
+
this.disposables.push(vscode.workspace.onDidChangeTextDocument(event => {
|
|
145
|
+
const editor = vscode.window.activeTextEditor;
|
|
146
|
+
if (editor && event.document === editor.document && editor.document.languageId === 'norn') {
|
|
147
|
+
if (updateTimeout) {
|
|
148
|
+
clearTimeout(updateTimeout);
|
|
149
|
+
}
|
|
150
|
+
updateTimeout = setTimeout(() => {
|
|
151
|
+
this.updateDecorations(editor);
|
|
152
|
+
}, 300);
|
|
153
|
+
}
|
|
154
|
+
}));
|
|
155
|
+
// Initial decoration for active editor
|
|
156
|
+
const activeEditor = vscode.window.activeTextEditor;
|
|
157
|
+
if (activeEditor?.document.languageId === 'norn') {
|
|
158
|
+
this.updateDecorations(activeEditor);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Update decorations for a text editor
|
|
163
|
+
* Disabled - no gutter icons or line highlights for contract assertions
|
|
164
|
+
*/
|
|
165
|
+
updateDecorations(editor) {
|
|
166
|
+
// Contract decorations disabled - user requested clean editor without gutter icons/highlights
|
|
167
|
+
// Clear any existing decorations
|
|
168
|
+
editor.setDecorations(this.decorationTypes.pass, []);
|
|
169
|
+
editor.setDecorations(this.decorationTypes.fail, []);
|
|
170
|
+
editor.setDecorations(this.decorationTypes.warn, []);
|
|
171
|
+
editor.setDecorations(this.decorationTypes.stale, []);
|
|
172
|
+
editor.setDecorations(this.decorationTypes.unknown, []);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Refresh decorations on all visible editors
|
|
176
|
+
*/
|
|
177
|
+
refreshAllDecorations() {
|
|
178
|
+
for (const editor of vscode.window.visibleTextEditors) {
|
|
179
|
+
if (editor.document.languageId === 'norn') {
|
|
180
|
+
this.updateDecorations(editor);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
dispose() {
|
|
185
|
+
// Dispose decoration types
|
|
186
|
+
Object.values(this.decorationTypes).forEach(dt => dt.dispose());
|
|
187
|
+
// Dispose other subscriptions
|
|
188
|
+
this.disposables.forEach(d => d.dispose());
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
exports.ContractDecorationProvider = ContractDecorationProvider;
|
|
192
|
+
/**
|
|
193
|
+
* Create a hover provider for schema assertion decorations
|
|
194
|
+
*/
|
|
195
|
+
function createContractHoverProvider() {
|
|
196
|
+
return {
|
|
197
|
+
provideHover(document, position) {
|
|
198
|
+
const line = document.lineAt(position.line);
|
|
199
|
+
if (!MATCHES_SCHEMA_PATTERN.test(line.text)) {
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
const result = (0, validationCache_1.getResultForAssertion)(document.uri.fsPath, position.line);
|
|
203
|
+
if (!result) {
|
|
204
|
+
return new vscode.Hover([
|
|
205
|
+
new vscode.MarkdownString('**Contract Status:** ⚪ Not validated\n\nRun the sequence to validate this assertion.')
|
|
206
|
+
]);
|
|
207
|
+
}
|
|
208
|
+
const statusIcon = {
|
|
209
|
+
pass: '🟢',
|
|
210
|
+
fail: '🔴',
|
|
211
|
+
warn: '🟡',
|
|
212
|
+
stale: '⚪'
|
|
213
|
+
}[result.status] || '⚪';
|
|
214
|
+
const statusText = {
|
|
215
|
+
pass: 'Passed',
|
|
216
|
+
fail: 'Failed',
|
|
217
|
+
warn: 'Warning',
|
|
218
|
+
stale: 'Stale (re-run to update)'
|
|
219
|
+
}[result.status] || 'Unknown';
|
|
220
|
+
const md = new vscode.MarkdownString();
|
|
221
|
+
md.appendMarkdown(`**Contract Status:** ${statusIcon} ${statusText}\n\n`);
|
|
222
|
+
md.appendMarkdown(`**Schema:** \`${result.schemaPath}\`\n\n`);
|
|
223
|
+
if (result.lastRunTime) {
|
|
224
|
+
const date = new Date(result.lastRunTime);
|
|
225
|
+
md.appendMarkdown(`**Last Run:** ${date.toLocaleString()}\n\n`);
|
|
226
|
+
}
|
|
227
|
+
if (result.environment) {
|
|
228
|
+
md.appendMarkdown(`**Environment:** ${result.environment}\n\n`);
|
|
229
|
+
}
|
|
230
|
+
if (result.status === 'fail' && result.errorCount) {
|
|
231
|
+
md.appendMarkdown(`**Errors:** ${result.errorCount}\n\n`);
|
|
232
|
+
if (result.errorSummary) {
|
|
233
|
+
md.appendMarkdown(`> ${result.errorSummary}\n\n`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Add action link
|
|
237
|
+
md.appendMarkdown(`[Open Contract View](command:norn.openContractView?${encodeURIComponent(JSON.stringify({ schemaPath: result.schemaPath }))})`);
|
|
238
|
+
md.isTrusted = true;
|
|
239
|
+
return new vscode.Hover(md);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=contractDecorationProvider.js.map
|