UNPKG

freshroute-server

Version:

Local development server for FreshRoute extension with API mocking and extended functionality

1 lines โ€ข 26 kB
<!doctype html><html><head><meta charset="utf-8"><title>FreshRoute - Settings</title><link rel="stylesheet" href="options.css"></head><body><div class="container"><div class="header"><div class="header-content"><div class="header-left"><h1><span class="header-logo"><img src="icons/icon128.png" alt="FreshRoute Logo"> </span>FreshRoute</h1><p>Configure URL rewrite rules and header modifications</p></div><div class="header-right"><div class="tab-navigation"><div class="nav-tabs"><button class="nav-tab active" id="rulesTab">Rules ๐Ÿ”ง</button> <button class="nav-tab" id="settingsTab">Settings โš™๏ธ</button></div><div class="nav-actions"><button class="btn btn-secondary" id="networkRecorderBtn"><span>๐ŸŽฌ</span> <span>Network Recorder <span style="font-size:.75em;color:#6366f1;font-weight:600;background:rgba(99,102,241,.1);padding:2px 6px;border-radius:4px;margin-left:4px">BETA</span></span></button> <button class="btn btn-secondary" id="dashboardBtn"><span>๐Ÿ“Š</span> <span>Dashboard <span style="font-size:.75em;color:#6366f1;font-weight:600;background:rgba(99,102,241,.1);padding:2px 6px;border-radius:4px;margin-left:4px">BETA</span></span></button></div></div></div></div></div><div class="content"><div id="rulesView" class="main-view active"><div class="section"><div class="section-header"><div class="section-title">Rules & Groups</div><div class="section-actions"><div class="import-export-section"><input type="file" id="importFile" class="hidden-file-input" accept=".json"> <button class="import-btn" id="importBtn">Import</button></div><button class="manage-files-btn" id="manageFilesMainBtn">๐Ÿ“ Manage Files <span style="font-size:.75em;color:#6366f1;font-weight:600;background:rgba(99,102,241,.1);padding:2px 6px;border-radius:4px;margin-left:4px">BETA</span></button> <button class="add-preset-btn" id="addPresetGroupBtn">Add Preset Group</button> <button class="add-group-btn" id="addGroupBtn">Add Group</button></div></div><div id="allGroups"></div></div></div><div id="settingsView" class="main-view"><div class="settings-header"><button class="back-to-rules-btn" id="backToRulesBtn"><span class="back-icon">โ†</span> <span class="back-text">Back to Rules</span></button><h2>Extension Settings</h2></div><div class="section"><div class="section-header"><div class="section-title">Environment Variables</div><div class="section-actions"><button class="add-rule-btn" id="addEnvironmentVariableBtn">Add Variable</button></div></div><div class="settings-card"><div class="settings-row"><div class="settings-description"><div class="settings-title">๐Ÿ“‹ Environment Variables</div><div class="settings-subtitle">Define reusable variables to avoid repetition. Use <code>{{variableName}}</code> in any input field to reference these variables.<br>๐Ÿ’ก Start typing <code>{{</code> to see inline suggestions, or press <code>Ctrl+Tab</code> for manual suggestions.<br>๐Ÿ’ก Example: Create <code>LOCAL_DOMAIN</code> = <code>localhost.freshservice-dev.com</code>, then use <code>{{LOCAL_DOMAIN}}</code> in URL patterns.</div></div></div></div><div id="environmentVariables"></div></div><div class="section"><div class="section-header"><div class="section-title">FreshRoute Server Configuration</div></div><div class="settings-card"><div class="settings-row"><div class="settings-description"><div class="settings-title">๐Ÿ“ก FreshRoute Server URLs</div><div class="settings-subtitle">Configure the URLs for your local FreshRoute development server. The HTTP URL is used for API requests and file management, while the WebSocket URL is used for real-time communication.<br>๐Ÿ’ก <strong>Start the server:</strong> <code>cd mock-server && npm start</code></div></div></div><div class="settings-row"><div class="form-group"><label class="form-label">HTTP Server URL</label> <input id="mockServerHttpUrl" class="form-input" placeholder="http://localhost:3001"><div class="small-text">URL for API requests and file management (default: http://localhost:3001)</div></div></div><div class="settings-row"><div class="form-group"><label class="form-label">WebSocket Server URL</label> <input id="mockServerWsUrl" class="form-input" placeholder="ws://localhost:3002"><div class="small-text">URL for real-time communication (default: ws://localhost:3002)</div></div></div><div class="settings-row"><div class="settings-description"><div class="settings-title">๐Ÿ“ Response Files Directory</div><div class="settings-subtitle">Files are stored in the <code>mock-server/responses/</code> directory. Use the "Manage Files" button in the main rules section to upload and manage response files.</div></div></div><div class="settings-row"><div class="api-mock-status"><span id="mockServerStatus" class="connection-status disconnected">Disconnected</span> <button class="btn btn-secondary" id="refreshApiMockFilesBtn">๐Ÿ”„ Refresh Files</button> <button class="btn btn-primary" id="saveMockServerSettingsBtn">๐Ÿ’พ Save Settings</button></div></div></div></div><div class="section"><div class="section-header"><div class="section-title">Extension Settings</div></div><div class="settings-card"><div class="settings-row"><div class="settings-description"><div class="settings-title">Show Rule Notifications</div><div class="settings-subtitle">Display toast notifications when rules are applied to web pages. Notifications auto-hide after 5 seconds and won't duplicate for the same rule.</div></div><label class="toggle-switch"><input type="checkbox" id="notificationsEnabledToggle"> <span class="slider"></span></label></div></div><div class="settings-card"><div class="settings-row"><div class="settings-description"><div class="settings-title">Compact View for Notifications</div><div class="settings-subtitle">Show only one notification at a time with navigation arrows (โ† โ†’) to move between them. The latest notification is shown by default. Requires notifications to be enabled.</div></div><label class="toggle-switch"><input type="checkbox" id="compactNotificationsToggle" checked="checked"> <span class="slider"></span></label></div></div><div class="settings-card"><div class="settings-row"><div class="settings-description"><div class="settings-title">Export Environment Variables with Rules</div><div class="settings-subtitle">When enabled, environment variables will be included in exported JSON files. During import, environment variables will be created if they don't already exist with the same name.</div></div><label class="toggle-switch"><input type="checkbox" id="exportEnvironmentVariablesToggle"> <span class="slider"></span></label></div></div><div class="settings-card"><div class="settings-row"><div class="settings-description"><div class="settings-title">Unified Rule Groups</div><div class="settings-subtitle">โœ… Mixed Rule Types: Each group can contain URL rewrite, header modification, and mock response rules<br>๐Ÿ”ง Flexible Organization: Organize rules by project, environment, or purpose<br>๐Ÿ“‹ Easy Management: Add, edit, enable/disable rules within groups</div></div></div></div><div class="settings-card"><div class="settings-row"><div class="settings-description"><div class="settings-title">Export & Import Rules</div><div class="settings-subtitle">๐Ÿ“ค Export groups as JSON files for backup or sharing<br>๐Ÿ“ฅ Import rules from JSON files<br>๐Ÿ—‚๏ธ Groups can contain URL rewrite, header modification, and mock response rules</div></div></div></div></div></div></div><div class="footer">FreshRoute v1.0.0 - Built for productivity</div></div><div id="urlRuleModal" class="modal"><div class="modal-content"><div class="modal-header"><div class="modal-title">Add/Edit URL Rewrite Rule</div><span class="close" id="closeUrlModal">&times;</span></div><div class="domain-restriction-notice"><strong>๐Ÿ”’ Domain Restrictions:</strong> Target URLs are restricted to development domains only to prevent accidental production redirects. Only URLs pointing to allowed development/staging domains will be accepted.</div><div class="form-group"><label class="form-label">Matching Type</label> <select id="matchingType" class="form-select"><option value="regex">Regular Expression (Advanced)</option><option value="contains">URL Contains Text</option><option value="equals">URL Equals Exactly</option><option value="startsWith">URL Starts With</option><option value="endsWith">URL Ends With</option><option value="wildcard">Wildcard Pattern (Simple)</option></select><div class="small-text">Choose how to match the source URL. Use "Contains" or "Equals" for simple cases, or "Regular Expression" for advanced patterns.</div></div><div class="form-group"><label class="form-label" id="sourceUrlLabel">Source URL Pattern</label> <input id="sourceUrl" class="form-input" placeholder="e.g., http://localhost.freshservice-dev.com:8080/(.*)"><div class="small-text" id="sourceUrlHelp">Use regex patterns. Use (.*) or $1, $2 for capture groups. Use {{VARIABLE_NAME}} for environment variables. Press Ctrl+Tab for variable suggestions.</div><button type="button" class="btn-test-toggle" id="toggleSourceUrlTest"><span class="toggle-text">Show Test</span> ๐Ÿงช</button><div class="regex-test-section" id="sourceUrlTestSection" style="display:none"><label class="form-label">Test Your Regex Pattern</label><div class="regex-test-row"><input id="sourceUrlTest" class="form-input regex-test-input" placeholder="Enter a URL to test against your pattern"> <button type="button" class="btn btn-secondary regex-test-btn" id="testSourceUrlBtn">Test</button></div><div class="regex-result" id="sourceUrlResult"></div><div class="regex-examples"><label class="form-label">Common Patterns:</label><div class="example-buttons"><button type="button" class="btn-example" data-target="sourceUrl" data-pattern="https?://localhost:(\d+)/(.*)">Localhost with port</button> <button type="button" class="btn-example" data-target="sourceUrl" data-pattern="https?://([^.]+)\.example\.com/(.*)">Subdomain capture</button> <button type="button" class="btn-example" data-target="sourceUrl" data-pattern="https?://api\.([^.]+)\.com/v(\d+)/(.*)">API versioning</button> <button type="button" class="btn-example" data-target="sourceUrl" data-pattern="https?://([^/]+)/api/(.*)">Domain + API path</button> <button type="button" class="btn-example" data-target="sourceUrl" data-pattern="http://localhost:*/api/*">Wildcard port + path</button> <button type="button" class="btn-example" data-target="sourceUrl" data-pattern="https://*.example.com/*">Wildcard subdomain</button></div></div></div></div><div class="form-group"><label class="form-label">Target URL</label> <input id="targetUrl" class="form-input" placeholder="e.g., https://share-freshgladiators-m4008.freshgladiators.com/$1"><div class="small-text" id="targetUrlHelp">Use $1, $2, etc. to reference capture groups from source pattern. Use {{VARIABLE_NAME}} for environment variables.</div><div class="domain-validation" id="targetUrlDomainValidation" style="display:none"><div class="validation-message" id="domainValidationMessage"></div><div class="allowed-domains" id="allowedDomainsList" style="display:none"><div class="allowed-domains-title">๐Ÿ“‹ Allowed Development Domains:</div><div class="allowed-domains-list" id="allowedDomainsContent"></div></div></div><div class="regex-examples" id="targetUrlExamples" style="display:none"><label class="form-label">Target URL Examples:</label><div class="example-buttons"><button type="button" class="btn-example" data-target="targetUrl" data-pattern="https://production.example.com:$1/$2">Port + path mapping</button> <button type="button" class="btn-example" data-target="targetUrl" data-pattern="https://$1-prod.example.com/$2">Subdomain to prod</button> <button type="button" class="btn-example" data-target="targetUrl" data-pattern="https://api.prod.com/v$2/$3">API version mapping</button> <button type="button" class="btn-example" data-target="targetUrl" data-pattern="https://$1.myservice.com/api/$2">Domain transformation</button> <button type="button" class="btn-example" data-target="targetUrl" data-pattern="https://prod.example.com:$1/api/$2">Wildcard mapping</button> <button type="button" class="btn-example" data-target="targetUrl" data-pattern="https://$1.production.com/$2">Wildcard subdomain mapping</button></div></div><div class="regex-preview-section" id="targetUrlPreview"></div></div><div class="modal-actions"><button class="btn btn-secondary" id="cancelUrlRuleBtn">Cancel</button> <button class="btn btn-success" id="saveUrlRuleBtn">Save Rule</button></div></div></div><div id="headerRuleModal" class="modal"><div class="modal-content"><div class="modal-header"><div class="modal-title">Add/Edit Header Modification Rule <span style="font-size:.7em;color:#6366f1;font-weight:600;background:rgba(99,102,241,.1);padding:2px 6px;border-radius:4px;margin-left:6px">BETA</span></div><span class="close" id="closeHeaderModal">&times;</span></div><div class="domain-restriction-notice"><strong>๐Ÿ”’ Domain Restrictions:</strong> Header modifications are restricted to development domains only to prevent accidental modifications on production websites. Only URLs matching allowed development/staging domains will be accepted.</div><div class="form-group"><label class="form-label">Matching Type</label> <select id="headerMatchingType" class="form-select"><option value="regex">Regular Expression (Advanced)</option><option value="contains">URL Contains Text</option><option value="equals">URL Equals Exactly</option><option value="startsWith">URL Starts With</option><option value="endsWith">URL Ends With</option><option value="wildcard">Wildcard Pattern (Simple)</option></select><div class="small-text">Choose how to match URLs where headers should be modified. Use "Contains" or "Equals" for simple cases, or "Regular Expression" for advanced patterns.</div></div><div class="form-group"><label class="form-label" id="headerUrlLabel">URL Pattern</label> <input id="headerUrlPattern" class="form-input" placeholder="e.g., https://api\\.example\\.com/.*"><div class="small-text" id="headerUrlHelp">Regex pattern to match URLs where headers should be modified. Use {{VARIABLE_NAME}} for environment variables.</div><div class="domain-validation" id="headerUrlDomainValidation" style="display:none"><div class="validation-message" id="headerDomainValidationMessage"></div><div class="allowed-domains" id="headerAllowedDomainsList" style="display:none"><div class="allowed-domains-label">Allowed domains:</div><div class="allowed-domains-content" id="headerAllowedDomainsContent"></div></div></div><button type="button" class="btn-test-toggle" id="toggleHeaderUrlTest"><span class="toggle-text">Show Test</span> ๐Ÿงช</button><div class="regex-test-section" id="headerUrlTestSection" style="display:none"><label class="form-label">Test Your URL Pattern</label><div class="regex-test-row"><input id="headerUrlTest" class="form-input regex-test-input" placeholder="Enter a URL to test against your pattern"> <button type="button" class="btn btn-secondary regex-test-btn" id="testHeaderUrlBtn">Test</button></div><div class="regex-result" id="headerUrlResult"></div><div class="regex-examples"><label class="form-label">Common Patterns:</label><div class="example-buttons"><button type="button" class="btn-example" data-target="headerUrlPattern" data-pattern="https?://api\..*">Any API domain</button> <button type="button" class="btn-example" data-target="headerUrlPattern" data-pattern="https?://.*\.googleapis\.com/.*">Google APIs</button> <button type="button" class="btn-example" data-target="headerUrlPattern" data-pattern="https?://([^.]+\.)?example\.com/.*">Example.com domains</button> <button type="button" class="btn-example" data-target="headerUrlPattern" data-pattern="https?://.*\.(jpg|png|gif|svg)$">Image files</button></div></div></div></div><div class="headers-section"><label class="form-label">Headers to Modify</label><div class="headers-list" id="headersList"></div><button class="add-header-btn" id="addHeaderFieldBtn">Add Header</button></div><div class="modal-actions"><button class="btn btn-secondary" id="cancelHeaderRuleBtn">Cancel</button> <button class="btn btn-success" id="saveHeaderRuleBtn">Save Rule</button></div></div></div><div id="groupModal" class="modal"><div class="modal-content"><div class="modal-header"><div class="modal-title">Add/Edit Group</div><span class="close" id="closeGroupModal">&times;</span></div><div class="form-group"><label class="form-label">Group Name</label> <input id="groupName" class="form-input" placeholder="e.g., Development Environment"><div class="small-text">Choose a descriptive name for your group</div></div><div class="modal-actions"><button class="btn btn-secondary" id="cancelGroupBtn">Cancel</button> <button class="btn btn-success" id="saveGroupBtn">Save Group</button></div></div></div><div id="presetModal" class="modal"><div class="modal-content preset-modal-content"><div class="modal-header"><div class="modal-title">Create Preset Group</div><span class="close" id="closePresetModal">&times;</span></div><div id="presetSelection"><div class="preset-intro"><p>Choose a preset template to quickly set up a group with predefined rules. You can customize the variables to match your environment.</p></div><div class="presets-container" id="presetsList"></div></div><div id="presetConfiguration" style="display:none"><div class="preset-config-header"><button class="btn btn-text preset-back-btn" id="presetBackBtn">โ† Back to Templates</button><h3 id="presetConfigTitle">Configure Preset</h3></div><div class="preset-config-form" id="presetConfigForm"></div><div class="modal-actions"><button class="btn btn-secondary" id="cancelPresetBtn">Cancel</button> <button class="btn btn-success" id="createPresetGroupBtn">Create Group</button></div></div></div></div><div id="environmentVariableModal" class="modal"><div class="modal-content"><div class="modal-header"><div class="modal-title">Add/Edit Environment Variable</div><span class="close" id="closeEnvironmentVariableModal">&times;</span></div><div class="form-group"><label class="form-label">Variable Name</label> <input id="environmentVariableName" class="form-input" placeholder="e.g., LOCAL_DOMAIN, API_KEY, BASE_URL"><div class="small-text">Use uppercase letters, numbers, and underscores only. No spaces or special characters.</div></div><div class="form-group"><label class="form-label">Variable Value</label> <input id="environmentVariableValue" class="form-input" placeholder="e.g., localhost.freshservice-dev.com, your-api-key"><div class="small-text">The value that will replace <code>{{variableName}}</code> in your rules.</div></div><div class="form-group"><label class="form-label">Description (Optional)</label> <input id="environmentVariableDescription" class="form-input" placeholder="Brief description of what this variable is used for"><div class="small-text">Optional description to help remember what this variable is for.</div></div><div class="modal-actions"><button class="btn btn-secondary" id="cancelEnvironmentVariableBtn">Cancel</button> <button class="btn btn-success" id="saveEnvironmentVariableBtn">Save Variable</button></div></div></div><div id="fileManagementModal" class="modal"><div class="modal-content large-modal"><div class="modal-header"><div class="modal-title">FreshRoute Server File Management</div><span class="close" id="closeFileManagementModal">&times;</span></div><div class="file-management-content"><div class="file-upload-section"><div class="section-header"><div class="section-title">Upload New File</div></div><div class="upload-area" id="fileUploadArea"><div class="upload-drop-zone" id="dropZone"><div class="upload-icon">๐Ÿ“</div><div class="upload-text"><div class="upload-primary">Drop files here or click to browse</div><div class="upload-secondary">Supports JSON, XML, TXT files (max 5MB each)</div></div><input type="file" id="fileInput" multiple="multiple" accept=".json,.xml,.txt,.html,.css,.js" style="display:none"></div><div class="upload-progress" id="uploadProgress" style="display:none"><div class="progress-bar"><div class="progress-fill" id="progressFill"></div></div><div class="progress-text" id="progressText">Uploading...</div></div></div></div><div class="file-list-section"><div class="section-header"><div class="section-title">Available Files</div><div class="section-actions"><button class="btn btn-secondary" id="refreshFileListBtn">๐Ÿ”„ Refresh</button></div></div><div class="file-list" id="fileList"><div class="loading-files"><div class="loading-spinner"></div><div>Loading files...</div></div></div></div></div><div class="modal-actions"><button class="btn btn-secondary" id="closeFileManagementBtn">Close</button></div></div></div><div id="apiMockModal" class="modal"><div class="modal-content large-modal"><div class="modal-header"><div class="modal-title">Add/Edit API Mock Rule</div><span class="close" id="closeApiMockModal">&times;</span></div><div class="form-group"><label class="form-label">HTTP Method</label> <select id="mockMethod" class="form-select"><option value="ANY">Any Method</option><option value="GET">GET</option><option value="POST">POST</option><option value="PUT">PUT</option><option value="DELETE">DELETE</option><option value="PATCH">PATCH</option></select></div><div class="form-group"><label class="form-label">Matching Type</label> <select id="mockMatchingType" class="form-select"><option value="regex">Regular Expression (Advanced)</option><option value="contains">URL Contains Text</option><option value="equals">URL Equals Exactly</option><option value="startsWith">URL Starts With</option><option value="endsWith">URL Ends With</option><option value="wildcard">Wildcard Pattern (Simple)</option></select><div class="small-text">Choose how to match request URLs. Use "Contains" or "Equals" for simple cases, or "Regular Expression" for advanced patterns.</div></div><div class="form-group"><label class="form-label">URL Pattern</label> <input id="mockUrlPattern" class="form-input" placeholder="e.g., https://api.example.com/users.*"><div class="small-text">Regular expression or string to match request URLs. Use {{VARIABLE_NAME}} for environment variables.</div><div class="test-section"><button type="button" class="btn-test-toggle" id="toggleMockUrlTest"><span class="toggle-text">Show URL Test</span> <span class="toggle-icon">โ–ผ</span></button><div class="test-content" id="mockUrlTestSection" style="display:none"><div class="test-input-group"><label class="test-label">Test URL:</label> <input id="mockUrlTest" class="test-input" placeholder="e.g., https://api.example.com/users/123"> <button type="button" class="btn btn-test" id="testMockUrlBtn">Test Pattern</button></div><div class="test-result" id="mockUrlResult"></div></div></div></div><div class="form-group"><label class="form-label">Response Type</label> <select id="mockResponseType" class="form-select"><option value="json">JSON Response</option><option value="text">Text Response</option><option value="file">File Response</option></select></div><div class="form-group" id="mockResponseBodyGroup"><label class="form-label">Response Body (JSON)</label><div class="response-body-controls"><button type="button" class="btn-format" id="formatJsonBtn" title="Format JSON">๐ŸŽจ Format JSON</button> <button type="button" class="btn-validate" id="validateJsonBtn" title="Validate JSON">โœ“ Validate JSON</button> <button type="button" class="btn-clear" id="clearResponseBodyBtn" title="Clear content">๐Ÿ—‘๏ธ Clear</button> <span class="response-body-status" id="responseBodyStatus"></span></div><textarea id="mockResponseBody" class="form-textarea response-body-editor" rows="10" placeholder='{"message": "Hello World", "data": {"users": [{"id": 1, "name": "John Doe"}]}}'></textarea><div class="small-text">JSON object to return as response. Leave empty for no response body. Use the format button to beautify JSON.</div><div class="response-body-info"><div class="character-count"><span id="responseBodyCharCount">0</span> characters</div><div class="response-body-examples"><label class="examples-label">Quick Examples:</label><div class="example-buttons"><button type="button" class="btn-example-small" data-example="success">โœ… Success</button> <button type="button" class="btn-example-small" data-example="error">โŒ Error</button> <button type="button" class="btn-example-small" data-example="list">๐Ÿ“‹ List</button> <button type="button" class="btn-example-small" data-example="user">๐Ÿ‘ค User</button> <button type="button" class="btn-example-small" data-example="empty">๐Ÿ”„ Empty</button></div></div></div></div><div class="form-group" id="mockResponseFileGroup" style="display:none"><label class="form-label">Response File</label> <select id="mockResponseFile" class="form-select"><option value="">Select a file...</option></select><div class="small-text">Choose a file from the FreshRoute server's responses directory</div></div><div class="form-row"><div class="form-group"><label class="form-label">Status Code</label> <input type="number" id="mockStatusCode" class="form-input" value="200" min="100" max="599"></div><div class="form-group"><label class="form-label">Delay (ms)</label> <input type="number" id="mockDelay" class="form-input" value="0" min="0" max="10000"></div></div><div class="form-group"><label class="form-label">Custom Headers (Optional)</label><div class="headers-list" id="mockHeadersList"></div><button type="button" class="add-header-btn" id="addMockHeaderBtn">Add Header</button></div><div class="form-group"><label class="form-label">Description (Optional)</label> <input id="mockDescription" class="form-input" placeholder="Brief description of this mock rule"></div><div class="modal-actions"><button class="btn btn-secondary" id="cancelMockRuleBtn">Cancel</button> <button class="btn btn-success" id="saveMockRuleBtn">Save Mock Rule</button></div></div></div><script src="allowed-domains.js"></script><script src="mock-client.js"></script><script src="api-mock-manager.js"></script><script src="options.js"></script></body></html>