norn-cli 1.3.16 → 1.3.18

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.
@@ -0,0 +1,373 @@
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.findEnvFile = findEnvFile;
37
+ exports.findEnvFileFromPath = findEnvFileFromPath;
38
+ exports.parseEnvFile = parseEnvFile;
39
+ exports.loadEnvironmentConfig = loadEnvironmentConfig;
40
+ exports.getActiveEnvironment = getActiveEnvironment;
41
+ exports.setActiveEnvironment = setActiveEnvironment;
42
+ exports.getEnvironmentVariables = getEnvironmentVariables;
43
+ exports.getAvailableEnvironments = getAvailableEnvironments;
44
+ exports.createStatusBarItem = createStatusBarItem;
45
+ exports.showEnvironmentPicker = showEnvironmentPicker;
46
+ exports.disposeStatusBar = disposeStatusBar;
47
+ exports.createCoverageStatusBarItem = createCoverageStatusBarItem;
48
+ exports.updateCoverageStatusBar = updateCoverageStatusBar;
49
+ exports.getCoverageStatusBarItem = getCoverageStatusBarItem;
50
+ const vscode = __importStar(require("vscode"));
51
+ const fs = __importStar(require("fs"));
52
+ const path = __importStar(require("path"));
53
+ const ENV_FILENAME = '.nornenv';
54
+ // Current active environment (stored globally)
55
+ let activeEnvironment;
56
+ let statusBarItem;
57
+ let coverageStatusBarItem;
58
+ /**
59
+ * Finds the .nornenv file in the workspace
60
+ */
61
+ function findEnvFile() {
62
+ const workspaceFolders = vscode.workspace.workspaceFolders;
63
+ if (!workspaceFolders) {
64
+ return undefined;
65
+ }
66
+ for (const folder of workspaceFolders) {
67
+ const envPath = path.join(folder.uri.fsPath, ENV_FILENAME);
68
+ if (fs.existsSync(envPath)) {
69
+ return envPath;
70
+ }
71
+ }
72
+ return undefined;
73
+ }
74
+ /**
75
+ * Finds .nornenv file relative to a specific file path (for CLI usage)
76
+ */
77
+ function findEnvFileFromPath(filePath) {
78
+ let dir = path.dirname(filePath);
79
+ const root = path.parse(dir).root;
80
+ while (dir !== root) {
81
+ const envPath = path.join(dir, ENV_FILENAME);
82
+ if (fs.existsSync(envPath)) {
83
+ return envPath;
84
+ }
85
+ dir = path.dirname(dir);
86
+ }
87
+ return undefined;
88
+ }
89
+ /**
90
+ * Parses the .nornenv file content
91
+ */
92
+ function parseEnvFile(content) {
93
+ const lines = content.split('\n');
94
+ const config = {
95
+ common: {},
96
+ environments: [],
97
+ secretNames: new Set(),
98
+ secretValues: new Map()
99
+ };
100
+ let currentEnv = null;
101
+ const envRegex = /^\[env:([a-zA-Z_][a-zA-Z0-9_-]*)\]$/;
102
+ const varRegex = /^var\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
103
+ const secretRegex = /^secret\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$/;
104
+ for (const line of lines) {
105
+ const trimmed = line.trim();
106
+ // Skip empty lines and comments
107
+ if (!trimmed || trimmed.startsWith('#')) {
108
+ continue;
109
+ }
110
+ // Check for environment section
111
+ const envMatch = trimmed.match(envRegex);
112
+ if (envMatch) {
113
+ currentEnv = {
114
+ name: envMatch[1],
115
+ variables: {}
116
+ };
117
+ config.environments.push(currentEnv);
118
+ continue;
119
+ }
120
+ // Check for secret declaration (treated like var but marked for redaction)
121
+ const secretMatch = trimmed.match(secretRegex);
122
+ if (secretMatch) {
123
+ const varName = secretMatch[1];
124
+ const varValue = secretMatch[2].trim();
125
+ // Track as secret
126
+ config.secretNames.add(varName);
127
+ config.secretValues.set(varName, varValue);
128
+ // Also add to variables so it can be used
129
+ if (currentEnv) {
130
+ currentEnv.variables[varName] = varValue;
131
+ }
132
+ else {
133
+ config.common[varName] = varValue;
134
+ }
135
+ continue;
136
+ }
137
+ // Check for variable declaration
138
+ const varMatch = trimmed.match(varRegex);
139
+ if (varMatch) {
140
+ const varName = varMatch[1];
141
+ const varValue = varMatch[2].trim();
142
+ if (currentEnv) {
143
+ currentEnv.variables[varName] = varValue;
144
+ }
145
+ else {
146
+ config.common[varName] = varValue;
147
+ }
148
+ }
149
+ }
150
+ return config;
151
+ }
152
+ /**
153
+ * Reads and parses the .nornenv file
154
+ */
155
+ function loadEnvironmentConfig(envFilePath) {
156
+ const filePath = envFilePath || findEnvFile();
157
+ if (!filePath || !fs.existsSync(filePath)) {
158
+ return undefined;
159
+ }
160
+ try {
161
+ const content = fs.readFileSync(filePath, 'utf-8');
162
+ return parseEnvFile(content);
163
+ }
164
+ catch {
165
+ return undefined;
166
+ }
167
+ }
168
+ /**
169
+ * Gets the currently active environment name
170
+ */
171
+ function getActiveEnvironment() {
172
+ return activeEnvironment;
173
+ }
174
+ /**
175
+ * Sets the active environment
176
+ */
177
+ function setActiveEnvironment(envName) {
178
+ activeEnvironment = envName;
179
+ updateStatusBar();
180
+ }
181
+ /**
182
+ * Gets all variables for the current environment (common + environment-specific)
183
+ */
184
+ function getEnvironmentVariables(envFilePath) {
185
+ const config = loadEnvironmentConfig(envFilePath);
186
+ if (!config) {
187
+ return {};
188
+ }
189
+ // Start with common variables
190
+ const variables = { ...config.common };
191
+ // Override with environment-specific variables if an environment is active
192
+ if (activeEnvironment) {
193
+ const env = config.environments.find(e => e.name === activeEnvironment);
194
+ if (env) {
195
+ Object.assign(variables, env.variables);
196
+ }
197
+ }
198
+ return variables;
199
+ }
200
+ /**
201
+ * Gets available environment names
202
+ */
203
+ function getAvailableEnvironments(envFilePath) {
204
+ const config = loadEnvironmentConfig(envFilePath);
205
+ if (!config) {
206
+ return [];
207
+ }
208
+ return config.environments.map(e => e.name);
209
+ }
210
+ /**
211
+ * Creates and shows the status bar item
212
+ */
213
+ function createStatusBarItem() {
214
+ statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
215
+ statusBarItem.command = 'norn.selectEnvironment';
216
+ updateStatusBar();
217
+ statusBarItem.show();
218
+ return statusBarItem;
219
+ }
220
+ /**
221
+ * Updates the status bar item text
222
+ */
223
+ function updateStatusBar() {
224
+ if (!statusBarItem) {
225
+ return;
226
+ }
227
+ const envFile = findEnvFile();
228
+ if (!envFile) {
229
+ statusBarItem.text = '$(globe) Norn: No Env';
230
+ statusBarItem.tooltip = 'No .nornenv file found';
231
+ return;
232
+ }
233
+ if (activeEnvironment) {
234
+ statusBarItem.text = `$(globe) Norn: ${activeEnvironment}`;
235
+ statusBarItem.tooltip = `Active environment: ${activeEnvironment}\nClick to change`;
236
+ }
237
+ else {
238
+ statusBarItem.text = '$(globe) Norn: Select Env';
239
+ statusBarItem.tooltip = 'Click to select an environment';
240
+ }
241
+ }
242
+ /**
243
+ * Shows the environment picker
244
+ */
245
+ async function showEnvironmentPicker() {
246
+ const environments = getAvailableEnvironments();
247
+ if (environments.length === 0) {
248
+ const createFile = await vscode.window.showInformationMessage('No .nornenv file found. Would you like to create one?', 'Create .nornenv', 'Cancel');
249
+ if (createFile === 'Create .nornenv') {
250
+ await createEnvFileTemplate();
251
+ }
252
+ return;
253
+ }
254
+ const items = [
255
+ {
256
+ label: '$(circle-slash) None',
257
+ description: 'Use only common variables',
258
+ picked: !activeEnvironment
259
+ },
260
+ ...environments.map(env => ({
261
+ label: `$(server-environment) ${env}`,
262
+ description: env === activeEnvironment ? '(active)' : '',
263
+ picked: env === activeEnvironment
264
+ }))
265
+ ];
266
+ const selected = await vscode.window.showQuickPick(items, {
267
+ placeHolder: 'Select environment',
268
+ title: 'Norn Environment'
269
+ });
270
+ if (selected) {
271
+ if (selected.label.includes('None')) {
272
+ setActiveEnvironment(undefined);
273
+ vscode.window.showInformationMessage('Norn: Environment cleared');
274
+ }
275
+ else {
276
+ const envName = selected.label.replace('$(server-environment) ', '');
277
+ setActiveEnvironment(envName);
278
+ vscode.window.showInformationMessage(`Norn: Switched to "${envName}" environment`);
279
+ }
280
+ }
281
+ }
282
+ /**
283
+ * Creates a template .nornenv file
284
+ */
285
+ async function createEnvFileTemplate() {
286
+ const workspaceFolders = vscode.workspace.workspaceFolders;
287
+ if (!workspaceFolders) {
288
+ vscode.window.showErrorMessage('No workspace folder open');
289
+ return;
290
+ }
291
+ const template = `# Norn Environment Configuration
292
+ # Common variables are available in all environments
293
+
294
+ var timeout = 30000
295
+ var version = v1
296
+
297
+ # Development environment
298
+ [env:dev]
299
+ var baseUrl = http://localhost:3000
300
+ var apiKey = dev-key-123
301
+
302
+ # Staging environment
303
+ [env:staging]
304
+ var baseUrl = https://staging.api.example.com
305
+ var apiKey = staging-key-456
306
+
307
+ # Production environment
308
+ [env:prod]
309
+ var baseUrl = https://api.example.com
310
+ var apiKey = prod-key-789
311
+ `;
312
+ const envPath = path.join(workspaceFolders[0].uri.fsPath, ENV_FILENAME);
313
+ fs.writeFileSync(envPath, template, 'utf-8');
314
+ const doc = await vscode.workspace.openTextDocument(envPath);
315
+ await vscode.window.showTextDocument(doc);
316
+ updateStatusBar();
317
+ vscode.window.showInformationMessage('Created .nornenv file');
318
+ }
319
+ /**
320
+ * Disposes the status bar item
321
+ */
322
+ function disposeStatusBar() {
323
+ if (statusBarItem) {
324
+ statusBarItem.dispose();
325
+ statusBarItem = undefined;
326
+ }
327
+ if (coverageStatusBarItem) {
328
+ coverageStatusBarItem.dispose();
329
+ coverageStatusBarItem = undefined;
330
+ }
331
+ }
332
+ /**
333
+ * Creates the coverage status bar item
334
+ */
335
+ function createCoverageStatusBarItem() {
336
+ coverageStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 99);
337
+ coverageStatusBarItem.command = 'norn.showCoverage';
338
+ coverageStatusBarItem.hide(); // Hidden until we know there's swagger
339
+ return coverageStatusBarItem;
340
+ }
341
+ /**
342
+ * Updates the coverage status bar display
343
+ */
344
+ function updateCoverageStatusBar(hasSwagger, percentage, total, covered) {
345
+ if (!coverageStatusBarItem) {
346
+ return;
347
+ }
348
+ if (!hasSwagger) {
349
+ coverageStatusBarItem.hide();
350
+ return;
351
+ }
352
+ // Choose icon based on coverage level
353
+ let icon = '$(graph)';
354
+ if (percentage >= 80) {
355
+ icon = '$(pass)';
356
+ }
357
+ else if (percentage >= 50) {
358
+ icon = '$(warning)';
359
+ }
360
+ else if (percentage > 0) {
361
+ icon = '$(error)';
362
+ }
363
+ coverageStatusBarItem.text = `${icon} ${percentage}%`;
364
+ coverageStatusBarItem.tooltip = `API Coverage: ${covered}/${total} response codes tested\nClick to view details`;
365
+ coverageStatusBarItem.show();
366
+ }
367
+ /**
368
+ * Get the coverage status bar item (for external updates)
369
+ */
370
+ function getCoverageStatusBarItem() {
371
+ return coverageStatusBarItem;
372
+ }
373
+ //# sourceMappingURL=environmentProvider.js.map