Skip to content

Commit

Permalink
functional for demo
Browse files Browse the repository at this point in the history
  • Loading branch information
williamsyang-work committed Dec 2, 2024
1 parent 0caf057 commit 44596dc
Show file tree
Hide file tree
Showing 10 changed files with 1,025 additions and 8 deletions.
10 changes: 9 additions & 1 deletion vscode-trace-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
"command": "yourExtension.openJsonEditor",
"title": "Open JSON Configuration"
},
{
"command": "yourExtension.openJsonEditorFromFile",
"title": "Open JSON Configuration from File"
},
{
"command": "outputs.reset",
"title": "Reset",
Expand Down Expand Up @@ -200,7 +204,11 @@
{
"command": "yourExtension.openJsonEditor",
"group": "navigation@41"
}
},
{
"command": "yourExtension.openJsonEditorFromFile",
"group": "navigation@42"
}
],
"editor/title": [
{
Expand Down
57 changes: 50 additions & 7 deletions vscode-trace-extension/src/exploration/json-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class JsonConfigEditor {
private readonly ajv: Ajv;
private tempFilePath: string;
private isEditing: boolean = false;
private baseUrl: string = 'http://localhost:3069';
private baseUrl: string = 'http://localhost:3002';
private trackedEditor?: vscode.TextEditor;
private closeSubscription?: vscode.Disposable;

Expand Down Expand Up @@ -53,7 +53,29 @@ export class JsonConfigEditor {
});
}

public async openJsonEditor(useDefaults: boolean = true) {
private async validateJsonFile(filePath: string, schema: any): Promise<{ isValid: boolean; content?: any; errors?: string[] }> {
try {
const fileContent = fs.readFileSync(filePath, 'utf-8');
const jsonContent = JSON.parse(fileContent);

const validate = this.ajv.compile(schema);
if (validate(jsonContent)) {
return { isValid: true, content: jsonContent };
} else {
const errors = validate.errors?.map(error =>
`${error.instancePath} ${error.message}`
) || [];
return { isValid: false, errors };
}
} catch (error) {
if (error instanceof Error) {
return { isValid: false, errors: [error.message] };
}
return { isValid: false, errors: ['Unknown error occurred while validating JSON file'] };
}
}

public async openJsonEditor(options: { useDefaults?: boolean; sourceFile?: vscode.Uri } = {}) {
if (this.isEditing) {
vscode.window.showInformationMessage('A config editing session is already active');
return;
Expand All @@ -70,9 +92,32 @@ export class JsonConfigEditor {
// Always fetch schema
const schema = await this.fetchSchema();

// Get configuration based on useDefaults parameter
let config;
if (useDefaults) {
// Determine the configuration source
let config: any;

if (options.sourceFile) {
// Validate the source file against the schema
const validation = await this.validateJsonFile(options.sourceFile.fsPath, schema);

if (!validation.isValid) {
const viewDetails = 'View Details';
const response = await vscode.window.showErrorMessage(
'The selected file has validation errors and cannot be loaded.',
viewDetails
);

if (response === viewDetails) {
const errorDoc = await vscode.workspace.openTextDocument({
content: `Validation Errors:\n\n${validation.errors?.join('\n')}`,
language: 'text'
});
await vscode.window.showTextDocument(errorDoc);
}
return;
}

config = validation.content;
} else if (options.useDefaults) {
config = extractSchemaDefaults(schema);
} else {
config = await this.fetchConfig();
Expand All @@ -90,10 +135,8 @@ export class JsonConfigEditor {

await this.setJsonSchema(uri, schema);

// Improved editor close detection
this.closeSubscription = vscode.window.onDidChangeVisibleTextEditors(async (editors) => {
if (this.trackedEditor && !editors.some(e => e.document.uri.fsPath === this.tempFilePath)) {
// Editor was closed
if (this.closeSubscription) {
this.closeSubscription.dispose();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
10 changes: 10 additions & 0 deletions vscode-trace-extension/src/exploration/test-server/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"serverUrl": "localhost:8080",
"maxConnections": 100,
"timeout": 5000,
"features": {
"enableLogging": false,
"enableCache": false
},
"wildcard": "I sent you this in an email."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ignore": ["data/*"]
}
18 changes: 18 additions & 0 deletions vscode-trace-extension/src/exploration/test-server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "node-server",
"version": "1.0.0",
"description": "Mock server for VS Code config editor testing",
"main": "server.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.2",
"body-parser": "^1.20.2"
},
"devDependencies": {
"nodemon": "^3.0.2"
}
}
58 changes: 58 additions & 0 deletions vscode-trace-extension/src/exploration/test-server/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"serverUrl": {
"enum": [
"localhost:3000",
"localhost:3002",
"localhost:8080"
],
"description": "The server URL for the application \n Type: string \n [ 'localhost:3000' 'localhost:8080' ]",
"default": "localhost:3000"
},
"maxConnections": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"description": "Maximum number of concurrent connections",
"default": 10
},
"timeout": {
"type": "integer",
"minimum": 0,
"description": "Timeout in milliseconds",
"default": 5000
},
"features": {
"type": "object",
"properties": {
"enableLogging": {
"type": "boolean",
"description": "Enable detailed logging",
"default": false
},
"enableCache": {
"type": "boolean",
"description": "Enable response caching",
"default": false
}
},
"required": [
"enableLogging",
"enableCache"
]
},
"wildcard": {
"type": "string",
"description": "Anything you want.",
"default": "Good Hearted Woman - Waylon Jennings"
}
},
"required": [
"serverUrl",
"maxConnections",
"timeout",
"features"
]
}
177 changes: 177 additions & 0 deletions vscode-trace-extension/src/exploration/test-server/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
const express = require('express');
const cors = require('cors');
const { json } = require('body-parser');
const { writeFileSync, readFileSync, unlinkSync, existsSync } = require('fs');
const { join } = require('path');

const app = express();
const PORT = 3002;

// Enable CORS and JSON parsing
app.use(cors());
app.use(json());

// Initialize storage
const DATA_DIR = join(__dirname, 'data');
const CONFIG_PATH = join(DATA_DIR, 'config.json');
const SCHEMA_PATH = join(DATA_DIR, 'schema.json');

// Default schema
const defaultSchema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"serverUrl": {
"enum": [
"localhost:3000",
"localhost:3002",
"localhost:8080"
],
"description": "The server URL for the application \n Type: string \n [ 'localhost:3000' 'localhost:8080' ]",
"default": "localhost:3000",
},
"maxConnections": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"description": "Maximum number of concurrent connections",
"default": 10
},
"timeout": {
"type": "integer",
"minimum": 0,
"description": "Timeout in milliseconds",
"default": 5000
},
"features": {
"type": "object",
"properties": {
"enableLogging": {
"type": "boolean",
"description": "Enable detailed logging",
"default": false,
},
"enableCache": {
"type": "boolean",
"description": "Enable response caching",
"default": false
}
},
"required": ["enableLogging", "enableCache"]
},
"wildcard": {
"type": "string",
"description": "Anything you want."
}
},
"required": ["serverUrl", "maxConnections", "timeout", "features"]
};

// Default config
const defaultConfig = {
"serverUrl": "localhost:3000",
"maxConnections": 10,
"timeout": 5000,
"features": {
"enableLogging": false,
"enableCache": false
}
};

// Delete existing files and reset them on startup
console.log('Resetting configuration files...');

// Delete existing files if they exist
if (existsSync(CONFIG_PATH)) {
try {
unlinkSync(CONFIG_PATH);
console.log('Deleted existing config.json');
} catch (error) {
console.error('Error deleting config.json:', error);
}
}

if (existsSync(SCHEMA_PATH)) {
try {
unlinkSync(SCHEMA_PATH);
console.log('Deleted existing schema.json');
} catch (error) {
console.error('Error deleting schema.json:', error);
}
}

// Write new files with default values
try {
writeFileSync(SCHEMA_PATH, JSON.stringify(defaultSchema, null, 2));
console.log('Created new schema.json with default values');
} catch (error) {
console.error('Error creating schema.json:', error);
}

try {
writeFileSync(CONFIG_PATH, JSON.stringify(defaultConfig, null, 2));
console.log('Created new config.json with default values');
} catch (error) {
console.error('Error creating config.json:', error);
}

// Endpoints
app.get('/schema', (req, res) => {
try {
const schema = JSON.parse(readFileSync(SCHEMA_PATH, 'utf-8'));
res.json(schema);
} catch (error) {
res.status(500).json({ error: 'Failed to read schema' });
}
});

app.get('/config', (req, res) => {
try {
const config = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
res.json(config);
} catch (error) {
res.status(500).json({ error: 'Failed to read config' });
}
});

app.post('/config', (req, res) => {
try {
// Optional: Add validation here if you want server-side validation
console.log(req.body);
writeFileSync(CONFIG_PATH, JSON.stringify(req.body, null, 2));
res.json({ message: 'Config saved successfully' });
} catch (error) {
res.status(500).json({ error: 'Failed to save config' });
}
});

// Add some debugging endpoints
app.post('/schema', (req, res) => {
try {
writeFileSync(SCHEMA_PATH, JSON.stringify(req.body, null, 2));
res.json({ message: 'Schema updated successfully' });
} catch (error) {
res.status(500).json({ error: 'Failed to update schema' });
}
});

app.get('/reset', (req, res) => {
try {
writeFileSync(SCHEMA_PATH, JSON.stringify(defaultSchema, null, 2));
writeFileSync(CONFIG_PATH, JSON.stringify(defaultConfig, null, 2));
res.json({ message: 'Reset successful' });
} catch (error) {
res.status(500).json({ error: 'Failed to reset' });
}
});

// Start server
app.listen(PORT, () => {
console.log(`Mock config server running at http://localhost:${PORT}`);
console.log('\nAvailable endpoints:');
console.log(' GET /schema - Get JSON schema');
console.log(' GET /config - Get current config');
console.log(' POST /config - Save new config');
console.log(' POST /schema - Update schema (for testing)');
console.log(' GET /reset - Reset to default values');
});
Loading

0 comments on commit 44596dc

Please sign in to comment.