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,267 +0,0 @@
1
- "use strict";
2
- /**
3
- * Detects flat `[env:STAGE_REGION]` matrices and suggests a refactor to
4
- * `[template:STAGE]` + `[template:REGION]` + `[env:STAGE_REGION extends STAGE, REGION]`.
5
- *
6
- * The detector is conservative — it only fires when:
7
- * - At least 2 stages × 2 regions
8
- * - At least 3 populated cells (so the matrix is big enough to be worth refactoring)
9
- * - All matrix envs are flat (no existing `extends` clause)
10
- *
11
- * For each variable across the matrix, the axis classifier picks one of:
12
- * - `stage` : value is consistent within each stage, varies between stages
13
- * - `region` : value is consistent within each region, varies between regions
14
- * - `leaf` : value varies across both axes — stays in the leaf env
15
- *
16
- * Connection-string vars (names ending in `_connectionString`) are intentionally
17
- * skipped for lifting in v1 because their reverse-format
18
- * (`connectionString name = ...`) is special. They are preserved in leaf envs.
19
- */
20
- Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.detectRegionPattern = detectRegionPattern;
22
- exports.generateRegionRefactor = generateRegionRefactor;
23
- exports.applyRegionRefactorToText = applyRegionRefactorToText;
24
- const nornenvLanguageModel_1 = require("./nornenvLanguageModel");
25
- const MATRIX_ENV_NAME_REGEX = /^([a-zA-Z][a-zA-Z0-9-]*)_([a-zA-Z][a-zA-Z0-9-]*)$/;
26
- const MIN_STAGES = 2;
27
- const MIN_REGIONS = 2;
28
- const MIN_CELLS = 3;
29
- function isConnectionStringVar(name) {
30
- return name.endsWith('_connectionString');
31
- }
32
- function inferDeclarationKind(name) {
33
- return isConnectionStringVar(name) ? 'connectionString' : 'var';
34
- }
35
- function inferDisplayName(name) {
36
- return isConnectionStringVar(name)
37
- ? name.slice(0, -'_connectionString'.length)
38
- : name;
39
- }
40
- function declarationKind(declaration) {
41
- return declaration.name.endsWith('_connectionString') && declaration.displayName !== declaration.name
42
- ? 'connectionString'
43
- : 'var';
44
- }
45
- function buildDeclarationMap(text) {
46
- const model = (0, nornenvLanguageModel_1.parseNornenvDocumentModel)(text);
47
- const byEnv = new Map();
48
- for (const declaration of model.declarations) {
49
- if (declaration.sectionKind !== 'env' || !declaration.sectionName) {
50
- continue;
51
- }
52
- if (!byEnv.has(declaration.sectionName)) {
53
- byEnv.set(declaration.sectionName, new Map());
54
- }
55
- byEnv.get(declaration.sectionName).set(declaration.name, declaration);
56
- }
57
- return byEnv;
58
- }
59
- function getCellValue(cell, name, declarationsByEnv, config) {
60
- const value = cell.env.variables[name];
61
- if (value === undefined) {
62
- return undefined;
63
- }
64
- const declaration = declarationsByEnv.get(cell.envName)?.get(name);
65
- return {
66
- value,
67
- secret: declaration?.secret ?? config.secretNames.has(name),
68
- kind: declaration ? declarationKind(declaration) : inferDeclarationKind(name),
69
- displayName: declaration?.displayName ?? inferDisplayName(name)
70
- };
71
- }
72
- function classifyByAxis(name, cells, axisKeys, getAxisKey, declarationsByEnv, config) {
73
- const byKey = new Map();
74
- let presentCells = 0;
75
- for (const key of axisKeys) {
76
- const axisCells = cells.filter(cell => getAxisKey(cell) === key);
77
- const presentValues = axisCells
78
- .map(cell => getCellValue(cell, name, declarationsByEnv, config))
79
- .filter((value) => value !== undefined);
80
- if (presentValues.length === 0) {
81
- continue;
82
- }
83
- presentCells += presentValues.length;
84
- // Partial presence would add the value to cells that originally did not have it.
85
- if (presentValues.length !== axisCells.length) {
86
- return undefined;
87
- }
88
- const first = presentValues[0];
89
- if (presentValues.some(value => value.value !== first.value)) {
90
- return undefined;
91
- }
92
- byKey.set(key, {
93
- value: first.value,
94
- secret: presentValues.some(value => value.secret),
95
- kind: first.kind,
96
- displayName: first.displayName
97
- });
98
- }
99
- // A single-cell value is not duplication; keep it leaf-specific.
100
- return byKey.size > 0 && presentCells >= 2 ? byKey : undefined;
101
- }
102
- function detectRegionPattern(config, text) {
103
- const cells = [];
104
- for (const env of config.environments) {
105
- const match = env.name.match(MATRIX_ENV_NAME_REGEX);
106
- if (!match) {
107
- continue;
108
- }
109
- // Flat-only — if any matrix-shaped env already extends, this file is already mixed.
110
- if (env.parents.length > 0) {
111
- return undefined;
112
- }
113
- cells.push({ stage: match[1], region: match[2], envName: env.name, env });
114
- }
115
- const stages = Array.from(new Set(cells.map(c => c.stage)));
116
- const regions = Array.from(new Set(cells.map(c => c.region)));
117
- if (stages.length < MIN_STAGES || regions.length < MIN_REGIONS || cells.length < MIN_CELLS) {
118
- return undefined;
119
- }
120
- if (new Set([...stages, ...regions]).size !== stages.length + regions.length) {
121
- return undefined;
122
- }
123
- const existingTemplates = new Set(config.templates.map(template => template.name));
124
- if ([...stages, ...regions].some(name => existingTemplates.has(name))) {
125
- return undefined;
126
- }
127
- // Collect every variable name that appears in any matrix cell.
128
- const allVarNames = new Set();
129
- for (const cell of cells) {
130
- for (const name of Object.keys(cell.env.variables)) {
131
- allVarNames.add(name);
132
- }
133
- }
134
- let liftedToStage = 0;
135
- let liftedToRegion = 0;
136
- let leafSpecific = 0;
137
- let skippedConnectionStrings = 0;
138
- const assignments = [];
139
- const declarationsByEnv = buildDeclarationMap(text);
140
- for (const name of allVarNames) {
141
- if (isConnectionStringVar(name)) {
142
- skippedConnectionStrings++;
143
- }
144
- const stageValues = isConnectionStringVar(name)
145
- ? undefined
146
- : classifyByAxis(name, cells, stages, cell => cell.stage, declarationsByEnv, config);
147
- const regionValues = isConnectionStringVar(name)
148
- ? undefined
149
- : classifyByAxis(name, cells, regions, cell => cell.region, declarationsByEnv, config);
150
- if (stageValues) {
151
- assignments.push({ name, axis: 'stage', byKey: stageValues });
152
- liftedToStage++;
153
- }
154
- else if (regionValues) {
155
- assignments.push({ name, axis: 'region', byKey: regionValues });
156
- liftedToRegion++;
157
- }
158
- else {
159
- const byKey = new Map();
160
- for (const cell of cells) {
161
- const value = getCellValue(cell, name, declarationsByEnv, config);
162
- if (value !== undefined) {
163
- byKey.set(cell.envName, value);
164
- }
165
- }
166
- if (byKey.size > 0) {
167
- assignments.push({ name, axis: 'leaf', byKey });
168
- leafSpecific++;
169
- }
170
- }
171
- }
172
- // Compute the line range to replace: from the first matrix env header to the line
173
- // just before the next non-matrix section (or EOF).
174
- const model = (0, nornenvLanguageModel_1.parseNornenvDocumentModel)(text);
175
- const matrixNames = new Set(cells.map(c => c.envName));
176
- const matrixSectionLines = model.sections
177
- .filter(s => s.kind === 'env' && matrixNames.has(s.name))
178
- .map(s => s.lineNumber)
179
- .sort((a, b) => a - b);
180
- if (matrixSectionLines.length === 0) {
181
- return undefined;
182
- }
183
- const firstLine = matrixSectionLines[0];
184
- const lastMatrixHeaderLine = matrixSectionLines[matrixSectionLines.length - 1];
185
- const sectionsInReplacementRange = model.sections.filter(section => section.lineNumber >= firstLine && section.lineNumber <= lastMatrixHeaderLine);
186
- if (sectionsInReplacementRange.some(section => section.kind !== 'env' || !matrixNames.has(section.name))) {
187
- return undefined;
188
- }
189
- const lineCount = text.split('\n').length;
190
- const sectionsAfter = model.sections
191
- .filter(s => s.lineNumber > lastMatrixHeaderLine)
192
- .map(s => s.lineNumber)
193
- .sort((a, b) => a - b);
194
- const lastLine = sectionsAfter.length > 0 ? sectionsAfter[0] - 1 : lineCount - 1;
195
- return {
196
- stages,
197
- regions,
198
- cells,
199
- assignments,
200
- replaceRange: { startLine: firstLine, endLine: lastLine },
201
- summary: { liftedToStage, liftedToRegion, leafSpecific, skippedConnectionStrings }
202
- };
203
- }
204
- /**
205
- * Generates the refactored text block: stage templates, then region templates, then
206
- * leaf envs that compose them. Caller replaces `pattern.replaceRange` with this text.
207
- */
208
- function generateRegionRefactor(pattern) {
209
- const blocks = [];
210
- const fmtVar = (assignment, value) => {
211
- if (value.kind === 'connectionString') {
212
- const secretPrefix = value.secret ? 'secret ' : '';
213
- return ` ${secretPrefix}connectionString ${value.displayName} = ${value.value}`;
214
- }
215
- const keyword = value.secret ? 'secret' : 'var';
216
- return ` ${keyword} ${assignment.name} = ${value.value}`;
217
- };
218
- // Stage templates
219
- for (const stage of pattern.stages) {
220
- const stageVars = pattern.assignments.filter(a => a.axis === 'stage' && a.byKey.has(stage));
221
- if (stageVars.length === 0) {
222
- continue;
223
- }
224
- const lines = [`[template:${stage}]`];
225
- for (const v of stageVars) {
226
- lines.push(fmtVar(v, v.byKey.get(stage)));
227
- }
228
- blocks.push(lines.join('\n'));
229
- }
230
- // Region templates
231
- for (const region of pattern.regions) {
232
- const regionVars = pattern.assignments.filter(a => a.axis === 'region' && a.byKey.has(region));
233
- if (regionVars.length === 0) {
234
- continue;
235
- }
236
- const lines = [`[template:${region}]`];
237
- for (const v of regionVars) {
238
- lines.push(fmtVar(v, v.byKey.get(region)));
239
- }
240
- blocks.push(lines.join('\n'));
241
- }
242
- // Leaf envs
243
- for (const cell of pattern.cells) {
244
- const leafVars = pattern.assignments.filter(a => a.axis === 'leaf' && a.byKey.has(cell.envName));
245
- const header = `[env:${cell.envName} extends ${cell.stage}, ${cell.region}]`;
246
- if (leafVars.length === 0) {
247
- blocks.push(header);
248
- continue;
249
- }
250
- const lines = [header];
251
- for (const v of leafVars) {
252
- lines.push(fmtVar(v, v.byKey.get(cell.envName)));
253
- }
254
- blocks.push(lines.join('\n'));
255
- }
256
- return blocks.join('\n\n');
257
- }
258
- function applyRegionRefactorToText(text, pattern) {
259
- const lines = text.split('\n');
260
- const startLine = pattern.replaceRange.startLine;
261
- const endLine = Math.min(pattern.replaceRange.endLine, lines.length - 1);
262
- const replacementLines = generateRegionRefactor(pattern).split('\n');
263
- lines.splice(startLine, endLine - startLine + 1, ...replacementLines);
264
- const result = lines.join('\n');
265
- return text.endsWith('\n') && !result.endsWith('\n') ? `${result}\n` : result;
266
- }
267
- //# sourceMappingURL=nornenvRegionRefactor.js.map
@@ -1,95 +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.NornsqlHoverProvider = void 0;
37
- const vscode = __importStar(require("vscode"));
38
- const environmentProvider_1 = require("./environmentProvider");
39
- const inlayHintResolver_1 = require("./inlayHintResolver");
40
- const nornapiHoverProvider_1 = require("./nornapiHoverProvider");
41
- const CONNECTION_LINE_REGEX = /^(\s*)connection\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*$/;
42
- /**
43
- * Hover for `.nornsql`. Two recognised cursors:
44
- * - On the connection identifier (in a `connection NAME` line) — shows the resolved
45
- * `NAME_connectionString` value from `.nornenv` and where it's defined.
46
- * - On any `{{...}}` token — same resolution-chain markdown the `.nornapi` hover
47
- * builds (env scope).
48
- */
49
- class NornsqlHoverProvider {
50
- provideHover(document, position) {
51
- try {
52
- const filePath = document.uri.scheme === 'file' ? document.uri.fsPath : undefined;
53
- if (!filePath) {
54
- return undefined;
55
- }
56
- const lineText = document.lineAt(position.line).text;
57
- const config = (0, environmentProvider_1.loadEnvironmentConfig)(filePath);
58
- if (!config) {
59
- return undefined;
60
- }
61
- const activeEnvironment = (0, environmentProvider_1.getActiveEnvironment)(filePath);
62
- // Connection identifier hover.
63
- const connectionMatch = lineText.match(CONNECTION_LINE_REGEX);
64
- if (connectionMatch) {
65
- const indent = connectionMatch[1].length;
66
- const keywordEnd = indent + 'connection'.length;
67
- // Identifier starts after the whitespace gap between `connection` and the name.
68
- const identifierStart = lineText.indexOf(connectionMatch[2], keywordEnd);
69
- if (identifierStart >= 0) {
70
- const identifierEnd = identifierStart + connectionMatch[2].length;
71
- if (position.character >= identifierStart && position.character <= identifierEnd) {
72
- const csName = `${connectionMatch[2]}_connectionString`;
73
- const markdown = (0, nornapiHoverProvider_1.renderTemplateReferenceHover)(csName, config, activeEnvironment);
74
- return new vscode.Hover(markdown, new vscode.Range(new vscode.Position(position.line, identifierStart), new vscode.Position(position.line, identifierEnd)));
75
- }
76
- }
77
- }
78
- // {{...}} token hover.
79
- const tokenMatch = (0, nornapiHoverProvider_1.findTemplateTokenAt)(lineText, position.character);
80
- if (tokenMatch) {
81
- const parsed = (0, inlayHintResolver_1.parseInlayReference)(tokenMatch.referenceRaw);
82
- if (parsed) {
83
- const markdown = (0, nornapiHoverProvider_1.renderTemplateReferenceHover)(parsed.name, config, activeEnvironment);
84
- return new vscode.Hover(markdown, new vscode.Range(new vscode.Position(position.line, tokenMatch.tokenStart), new vscode.Position(position.line, tokenMatch.tokenEnd)));
85
- }
86
- }
87
- }
88
- catch {
89
- return undefined;
90
- }
91
- return undefined;
92
- }
93
- }
94
- exports.NornsqlHoverProvider = NornsqlHoverProvider;
95
- //# sourceMappingURL=nornsqlHoverProvider.js.map
@@ -1,114 +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.NornsqlInlayHintsProvider = void 0;
37
- const vscode = __importStar(require("vscode"));
38
- const environmentProvider_1 = require("./environmentProvider");
39
- const inlayHintResolver_1 = require("./inlayHintResolver");
40
- const TEMPLATE_TOKEN_REGEX = /\{\{([^{}]+)\}\}/g;
41
- const CONNECTION_LINE_REGEX = /^(\s*)connection\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*$/;
42
- /**
43
- * Inlay hints for `.nornsql` files. Two payoffs:
44
- * - `connection NAME` line: resolves `NAME_connectionString` from `.nornenv` and shows
45
- * the resolved value as an inlay after the identifier. Secret connection strings
46
- * are masked.
47
- * - Any `{{...}}` token in the file (rare in SQL bodies, but handled for consistency).
48
- */
49
- class NornsqlInlayHintsProvider {
50
- emitter = new vscode.EventEmitter();
51
- environmentSubscription;
52
- onDidChangeInlayHints = this.emitter.event;
53
- constructor() {
54
- this.environmentSubscription = (0, environmentProvider_1.onDidChangeActiveEnvironment)(() => {
55
- this.emitter.fire();
56
- });
57
- }
58
- provideInlayHints(document, range) {
59
- const hints = [];
60
- try {
61
- const filePath = document.uri.scheme === 'file' ? document.uri.fsPath : undefined;
62
- if (!filePath) {
63
- return [];
64
- }
65
- const config = (0, environmentProvider_1.loadEnvironmentConfig)(filePath);
66
- if (!config) {
67
- return [];
68
- }
69
- const variables = (0, environmentProvider_1.getEnvironmentVariables)(filePath);
70
- for (let lineNumber = range.start.line; lineNumber <= range.end.line; lineNumber++) {
71
- const line = document.lineAt(lineNumber).text;
72
- // `connection NAME` — resolve NAME_connectionString from .nornenv.
73
- const connectionMatch = line.match(CONNECTION_LINE_REGEX);
74
- if (connectionMatch) {
75
- const name = connectionMatch[2];
76
- const csVarName = `${name}_connectionString`;
77
- const resolved = (0, inlayHintResolver_1.resolveInlayValueLabel)(csVarName, variables, config.secretNames);
78
- if (resolved) {
79
- const tokenEnd = line.length;
80
- const hint = new vscode.InlayHint(new vscode.Position(lineNumber, tokenEnd), resolved.label, vscode.InlayHintKind.Parameter);
81
- hint.tooltip = resolved.secret
82
- ? `'${name}_connectionString' resolves from a secret connection string.`
83
- : `'${name}_connectionString' resolves to '${resolved.value}'.`;
84
- hints.push(hint);
85
- }
86
- }
87
- // Generic `{{...}}` tokens (rare in SQL bodies but handled for parity).
88
- TEMPLATE_TOKEN_REGEX.lastIndex = 0;
89
- for (const match of line.matchAll(TEMPLATE_TOKEN_REGEX)) {
90
- const resolved = (0, inlayHintResolver_1.resolveInlayValueLabel)(match[1], variables, config.secretNames);
91
- if (!resolved) {
92
- continue;
93
- }
94
- const tokenEnd = (match.index ?? 0) + match[0].length;
95
- const hint = new vscode.InlayHint(new vscode.Position(lineNumber, tokenEnd), resolved.label, vscode.InlayHintKind.Parameter);
96
- hint.tooltip = resolved.secret
97
- ? `'${match[1].trim()}' resolves from a secret value.`
98
- : `'${match[1].trim()}' resolves to '${resolved.value}'.`;
99
- hints.push(hint);
100
- }
101
- }
102
- }
103
- catch {
104
- return [];
105
- }
106
- return hints;
107
- }
108
- dispose() {
109
- this.environmentSubscription.dispose();
110
- this.emitter.dispose();
111
- }
112
- }
113
- exports.NornsqlInlayHintsProvider = NornsqlInlayHintsProvider;
114
- //# sourceMappingURL=nornsqlInlayHintsProvider.js.map