{"_id":"@andydavid-dev/mock-lobster","_rev":"3-799d7c5c4eabdf0165748e0ee335533c","name":"@andydavid-dev/mock-lobster","dist-tags":{"latest":"1.0.1"},"versions":{"0.1.0":{"name":"@andydavid-dev/mock-lobster","version":"0.1.0","keywords":["salesforce","api","testing","mock","oauth","integration","rest","webhook"],"author":{"name":"Andy Thomas","email":"andy.thomas@ziipline.com"},"license":"MIT","_id":"@andydavid-dev/mock-lobster@0.1.0","maintainers":[{"name":"andydavid-dev","email":"andy.thomas@hey.com"}],"homepage":"https://github.com/andydavid-dev/mock-lobster#readme","bugs":{"url":"https://github.com/andydavid-dev/mock-lobster/issues"},"bin":{"mock-lobster":"bin/mock-lobster.js"},"dist":{"shasum":"c04cc1c8b7db3e2164a0a81fc2b6c134660d5f43","tarball":"https://registry.npmjs.org/@andydavid-dev/mock-lobster/-/mock-lobster-0.1.0.tgz","fileCount":10,"integrity":"sha512-ZjNTcDC62hqP95vkp9HNuirmU35JP7ah4zB1pRUby+KGVUfPI4bsg78O85temXmTrT/UbKywGcpI/V5xYxccnw==","signatures":[{"sig":"MEUCIQCmgoNhvfHwzwHSV99TYk+6gQlzrRPfPYqeg2NUsV9NUgIgPCqRso2swl92U1SHaGyZhgrhaW9+g6I/Fx91zW17DAg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":47141},"main":"lib/index.js","engines":{"node":">=14.0.0"},"gitHead":"8f7e5ebe747f43b29a2c9cac9a699ee4b6a45394","scripts":{"dev":"nodemon lib/index.js","lint":"eslint lib/","test":"jest","clean":"rm -rf node_modules/","debug":"node --inspect lib/index.js","start":"node lib/index.js","prepare":"npm run test","version":"git add -A lib","reinstall":"npm run clean && npm install","docker:run":"docker run -p 3000:3000 mock-lobster","postversion":"git push && git push --tags","docker:build":"docker build -t mock-lobster .","prepublishOnly":"npm run lint"},"_npmUser":{"name":"andydavid-dev","email":"andy.thomas@hey.com"},"repository":{"url":"git+https://github.com/andydavid-dev/mock-lobster.git","type":"git"},"_npmVersion":"10.9.0","description":"A friendly API testing tool for Salesforce integrations","directories":{},"_nodeVersion":"23.3.0","dependencies":{"uuid":"^9.0.1","morgan":"^1.10.0","express":"^4.18.2","body-parser":"^1.20.2","jsonwebtoken":"^9.0.2"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","globals":"^15.14.0","nodemon":"^3.0.2","eslint-plugin-react":"^7.37.3","eslint-plugin-import":"^2.29.1","eslint-config-airbnb-base":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mock-lobster_0.1.0_1735918350166_0.5998602145687275","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@andydavid-dev/mock-lobster","version":"0.2.0","keywords":["salesforce","api","testing","mock","oauth","integration","rest","webhook"],"author":{"name":"Andy Thomas","email":"andy.thomas@ziipline.com"},"license":"MIT","_id":"@andydavid-dev/mock-lobster@0.2.0","maintainers":[{"name":"andydavid-dev","email":"andy.thomas@hey.com"}],"homepage":"https://github.com/andydavid-dev/mock-lobster#readme","bugs":{"url":"https://github.com/andydavid-dev/mock-lobster/issues"},"bin":{"mock-lobster":"bin/mock-lobster.js"},"dist":{"shasum":"ef5367aa040c83516a48d480386f7c941c8e9a68","tarball":"https://registry.npmjs.org/@andydavid-dev/mock-lobster/-/mock-lobster-0.2.0.tgz","fileCount":11,"integrity":"sha512-Cz1hAP+aLNaMiJXS5+Hfjp4K7Jxpcp6rljl/c9p11xSwwhWdWiVO7sM0SmLFmBS+DZ1i+7ihdfbYeinmL8Ku+A==","signatures":[{"sig":"MEYCIQCUubuFTFqH3MXE/EADUKDxKXzhf+km7ANr/GjhXiQyzAIhALboK04VbZs6Iqg+pX9CSO+RBgkYG4E11WSYZSU8Ez94","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":62571},"main":"lib/index.js","engines":{"node":">=14.0.0"},"gitHead":"23f384b9ecc3bade27009b6830a34078053625e7","scripts":{"dev":"nodemon lib/index.js","lint":"eslint lib/","test":"jest","clean":"rm -rf node_modules/","debug":"node --inspect lib/index.js","start":"node lib/index.js","prepare":"npm run test","version":"git add -A lib","reinstall":"npm run clean && npm install","docker:run":"docker run -p 3000:3000 mock-lobster","postversion":"git push && git push --tags","docker:build":"docker build -t mock-lobster .","prepublishOnly":"npm run lint"},"_npmUser":{"name":"andydavid-dev","email":"andy.thomas@hey.com"},"repository":{"url":"git+https://github.com/andydavid-dev/mock-lobster.git","type":"git"},"_npmVersion":"10.9.0","description":"A friendly API testing tool for Salesforce integrations","directories":{},"_nodeVersion":"23.3.0","dependencies":{"uuid":"^9.0.1","morgan":"^1.10.0","express":"^4.18.2","body-parser":"^1.20.2","jsonwebtoken":"^9.0.2","salesforce-pubsub-api-client":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.1","globals":"^15.14.0","nodemon":"^3.0.2","eslint-plugin-react":"^7.37.3","eslint-plugin-import":"^2.29.1","eslint-config-airbnb-base":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mock-lobster_0.2.0_1735927847861_0.03691709254546249","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@andydavid-dev/mock-lobster","version":"1.0.0","keywords":["salesforce","api","testing","mock","oauth","integration","rest","webhook"],"author":{"name":"Andy Thomas","email":"andy.thomas@hey.com"},"license":"MIT","_id":"@andydavid-dev/mock-lobster@1.0.0","maintainers":[{"name":"andydavid-dev","email":"andy.thomas@hey.com"}],"homepage":"https://github.com/andydavid-dev/mock-lobster#readme","bugs":{"url":"https://github.com/andydavid-dev/mock-lobster/issues"},"bin":{"mock-lobster":"bin/mock-lobster.js"},"dist":{"shasum":"6821edfd0db70f58921379a7bed0b31e50ee2fe2","tarball":"https://registry.npmjs.org/@andydavid-dev/mock-lobster/-/mock-lobster-1.0.0.tgz","fileCount":20,"integrity":"sha512-OMeI0Fa41Yvo3rTjJTgXYNZ5Ooa1OMAjM94KYJpctAmZKbelByFrrrDbmfg6YSElO/Mhha/aB63stsMXUXkzOg==","signatures":[{"sig":"MEYCIQC064v9kcaJPIexF/anXVpvAW5G6BSdvQQhp+RCUmHGtAIhALAmwLfi1u1UqGvo8nDM9hUR9a4xKxbcMrP2xKv8uLXc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":151632},"main":"index.js","engines":{"node":">=14.0.0"},"gitHead":"9a23e20d598f0531a25343040624f62aaf890daf","scripts":{"dev":"nodemon index.js","lint":"eslint lib/ tests/integration/ tests/unit/services/","test":"jest --maxWorkers=50% --detectOpenHandles --silent --colors","clean":"rm -rf node_modules/","debug":"node --inspect lib/index.js","start":"node index.js","test:ci":"jest --ci --bail --runInBand --forceExit --detectOpenHandles --reporters=default --reporters=jest-junit","test:all":"jest","validate":"npm run lint && npm run test:ci","reinstall":"npm run clean && npm install","test:unit":"jest \"tests/unit/.*\\.test\\.js$\"","docker:run":"docker run -p 3003:3003 mock-lobster","test:watch":"jest --watch","postversion":"git push && git push --tags","docker:build":"docker build -t mock-lobster .","test:all:log":"npm run test:all > test-output.log 2>&1","test:backend":"jest --selectProjects unit integration","test:coverage":"jest --coverage","test:frontend":"jest --selectProjects frontend","test:unit:log":"npm run test:unit > test-output.log 2>&1","prepublishOnly":"npm run validate","test:integration":"jest --selectProjects integration","test:frontend:log":"npm run test:frontend > test-output.log 2>&1","test:integration:log":"npm run test:integration > test-output.log 2>&1","test:coverage:detailed":"npx jest --coverage --verbose --coverageDetail=all --coverageReporters=\"text-summary\" --coverageReporters=\"text\" > coverage-report.txt"},"_npmUser":{"name":"andydavid-dev","email":"andy.thomas@hey.com"},"repository":{"url":"git+https://github.com/andydavid-dev/mock-lobster.git","type":"git"},"_npmVersion":"10.8.2","description":"A mock server for testing webhook integrations","directories":{},"_nodeVersion":"18.20.5","dependencies":{"uuid":"^9.0.1","chalk":"^4.1.2","morgan":"^1.10.0","express":"^4.18.2","body-parser":"^1.20.2","jsonwebtoken":"^9.0.2","salesforce-pubsub-api-client":"^5.2.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","nock":"^13.5.6","jsdom":"^24.1.3","eslint":"^8.57.1","globals":"^15.14.0","nodemon":"^3.1.9","cross-env":"^7.0.3","supertest":"^7.0.0","jest-junit":"^16.0.0","@babel/core":"^7.26.0","eventsource":"^3.0.2","concurrently":"^8.2.2","@babel/preset-env":"^7.26.0","@babel/preset-react":"^7.26.3","eslint-plugin-react":"^7.37.4","@babel/eslint-parser":"^7.26.5","eslint-plugin-import":"^2.31.0","@testing-library/react":"^14.3.1","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-config-airbnb-base":"^15.0.0","@testing-library/user-event":"^14.5.2"},"_npmOperationalInternal":{"tmp":"tmp/mock-lobster_1.0.0_1737668262785_0.7210975214477033","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@andydavid-dev/mock-lobster","version":"1.0.1","description":"A mock server for testing webhook integrations","main":"index.js","bin":{"mock-lobster":"bin/mock-lobster.js"},"scripts":{"start":"node index.js","test":"jest --maxWorkers=50% --detectOpenHandles --silent --colors","test:coverage":"jest --coverage","test:ci":"jest --ci --bail --runInBand --forceExit --detectOpenHandles --reporters=default --reporters=jest-junit","dev":"nodemon index.js","lint":"eslint lib/ tests/integration/ tests/unit/services/","debug":"node --inspect lib/index.js","test:frontend":"jest --selectProjects frontend","test:unit":"jest \"tests/unit/.*\\.test\\.js$\"","test:integration":"jest --selectProjects integration","test:backend":"jest --selectProjects unit integration","test:all":"jest","test:watch":"jest --watch","test:coverage:detailed":"npx jest --coverage --verbose --coverageDetail=all --coverageReporters=\"text-summary\" --coverageReporters=\"text\" > coverage-report.txt","test:frontend:log":"npm run test:frontend > test-output.log 2>&1","test:unit:log":"npm run test:unit > test-output.log 2>&1","test:integration:log":"npm run test:integration > test-output.log 2>&1","test:all:log":"npm run test:all > test-output.log 2>&1","clean":"rm -rf node_modules/","reinstall":"npm run clean && npm install","docker:build":"docker build -t mock-lobster .","docker:run":"docker run -p 3003:3003 mock-lobster","prepublishOnly":"npm run validate","validate":"npm run lint && npm run test:ci","postversion":"git push && git push --tags"},"keywords":["salesforce","api","testing","mock","oauth","integration","rest","webhook"],"author":{"name":"Andy Thomas","email":"andy.thomas@hey.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/andydavid-dev/mock-lobster.git"},"bugs":{"url":"https://github.com/andydavid-dev/mock-lobster/issues"},"homepage":"https://github.com/andydavid-dev/mock-lobster#readme","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"dependencies":{"body-parser":"^1.20.2","chalk":"^4.1.2","express":"^4.18.2","jsonwebtoken":"^9.0.2","morgan":"^1.10.0","salesforce-pubsub-api-client":"^5.2.0","uuid":"^9.0.1"},"devDependencies":{"@babel/core":"^7.26.0","@babel/eslint-parser":"^7.26.5","@babel/preset-env":"^7.26.0","@babel/preset-react":"^7.26.3","@testing-library/jest-dom":"^6.6.3","@testing-library/react":"^14.3.1","@testing-library/user-event":"^14.5.2","concurrently":"^8.2.2","cross-env":"^7.0.3","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-plugin-import":"^2.31.0","eslint-plugin-react":"^7.37.4","eventsource":"^3.0.2","globals":"^15.14.0","jest":"^29.7.0","jest-environment-jsdom":"^29.7.0","jest-junit":"^16.0.0","jsdom":"^24.1.3","nock":"^13.5.6","nodemon":"^3.1.9","supertest":"^7.0.0"},"engines":{"node":">=14.0.0"},"_id":"@andydavid-dev/mock-lobster@1.0.1","gitHead":"c40fd4baa96e820cef8587a4da538f4669cd21c8","_nodeVersion":"18.20.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-Y6K1zrm1PBOPGYTx2e9q/bBTXBOl5Qc2EBb+2iNPJpMdhE2HRUg4zNLRMBO7oN6uesRRE6mVxtYlWi1CwvccQg==","shasum":"9e70efce27bee4a97ce0740a0a0ada6a05bca1f0","tarball":"https://registry.npmjs.org/@andydavid-dev/mock-lobster/-/mock-lobster-1.0.1.tgz","fileCount":20,"unpackedSize":153513,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDxeU5TiLBFZQqvnp1xp3U4Wm5DDk7iL8TSKkGdTRhwcgIgB3Kjhn/NqtppGjwrCWD2in/L0tQdOPZrqKXXNMpXMe0="}]},"_npmUser":{"name":"andydavid-dev","email":"andy.thomas@hey.com"},"directories":{},"maintainers":[{"name":"andydavid-dev","email":"andy.thomas@hey.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mock-lobster_1.0.1_1738013391993_0.43786447059736866"},"_hasShrinkwrap":false}},"time":{"created":"2025-01-03T15:32:29.997Z","modified":"2025-01-27T21:29:52.354Z","0.1.0":"2025-01-03T15:32:30.386Z","0.2.0":"2025-01-03T18:10:48.062Z","1.0.0":"2025-01-23T21:37:43.027Z","1.0.1":"2025-01-27T21:29:52.174Z"},"bugs":{"url":"https://github.com/andydavid-dev/mock-lobster/issues"},"author":{"name":"Andy Thomas","email":"andy.thomas@hey.com"},"license":"MIT","homepage":"https://github.com/andydavid-dev/mock-lobster#readme","keywords":["salesforce","api","testing","mock","oauth","integration","rest","webhook"],"repository":{"type":"git","url":"git+https://github.com/andydavid-dev/mock-lobster.git"},"description":"A mock server for testing webhook integrations","maintainers":[{"name":"andydavid-dev","email":"andy.thomas@hey.com"}],"readme":"# 🦞 Mock Lobster\n\nMock Lobster is a developer-friendly local testing tool designed for Salesforce integrations, providing a lightweight, zero-configuration environment for testing your Salesforce outbound REST calls and Pub/Sub API integrations without the complexity of setting up remote endpoints.\n\n## Why Mock Lobster?\n\nTraditional integration testing often requires setting up and maintaining remote test environments, managing test data, and dealing with network-related issues. Mock Lobster simplifies this process by providing:\n\n- A local testing environment that mimics your production endpoints\n- Real-time inspection of incoming requests for quick debugging\n- Support for multiple authentication methods to match your production setup\n- Seamless integration with Salesforce Named Credentials\n- Zero configuration needed to get started\n\n## Features\n\n- **Dynamic Endpoint Creation**: Create test endpoints on demand with unique URLs\n- **Authentication Support**:\n   - OAuth 2.0 (Client Credentials Flow) with automatic token management\n   - No Authentication for simple testing scenarios\n- **Request Inspection**: View detailed information about incoming requests, including headers, body content, and authentication details\n- **Salesforce Integration**: Built-in support for Named Credentials configuration\n- **Modern Web Interface**: Clean, responsive design with real-time updates\n- **Request History**: Maintains a history of recent requests for debugging\n- **Local Development**: Runs completely locally, perfect for development and testing\n- **Pub/Sub Testing**: Built-in support for testing Salesforce Pub/Sub API integrations\n   - Real-time event monitoring\n   - Topic subscription management\n   - Event replay and history\n\n## Prerequisites\n\nBefore starting, ensure you have:\n- Node.js version 14 or higher installed\n- npm (comes with Node.js)\n- ngrok (required for Salesforce integration)\n   - macOS (using Homebrew): `brew install ngrok`\n   - Other platforms: Download from https://ngrok.com/download\n\n# Quick Start Guide\n\nThere are two ways to get started with Mock Lobster:\n1. Clone the repository (recommended for development and contributing)\n2. Install as an npm package (recommended for using Mock Lobster in your projects)\n\n## Option 1: Using Mock Lobster from Source\n\n### 1. Clone and Install\n\n```bash\n# Clone the repository\ngit clone https://github.com/yourusername/mock-lobster.git\ncd mock-lobster\n\n# Install dependencies\nnpm install\n```\n\n### 2. Start the Development Server\n\nMock Lobster will try to use port 3003 by default. If that port is unavailable, it will automatically search for the next available port in sequence (3004, 3005, etc.). The selected port will be displayed in the console when the server starts.\n\n```bash\n# If you want to free port 3003 specifically (Unix/Linux/macOS)\nkill $(lsof -t -i:3003)\n\n# Start the development server\nnpm run dev\n```\n\nYou can also specify a custom port:\n```bash\n# Use a specific port\nPORT=3456 npm run dev\n```\n\n## Option 2: Using Mock Lobster as a CLI Tool\n\n### 1. Install the Package\n\n```bash\n# Install globally to use the CLI command\nnpm install -g @andydavid-dev/mock-lobster\n```\n\n### 2. Start Mock Lobster\n\nStart Mock Lobster directly from your terminal:\n\n```bash\n# Start Mock Lobster with default settings (port 3003)\nmock-lobster\n\n# Start on a specific port\nmock-lobster --port 3456\n\n# Start with a custom static files path\nmock-lobster --static-path ./my-static-files\n```\n\n## Setting Up ngrok (Required for Both Options)\n\nMock Lobster runs locally on your machine, but Salesforce requires HTTPS endpoints for all outbound callouts. This is where ngrok comes in - it creates a secure tunnel to your local Mock Lobster instance, making it accessible to Salesforce with a public HTTPS URL.\n\n#### Why ngrok?\n- Salesforce enforces HTTPS for security reasons and won't make callouts to http://localhost\n- ngrok provides a secure HTTPS endpoint that forwards traffic to your local instance\n- Enables real-time inspection of all HTTP traffic\n- No need to deploy Mock Lobster to a public server\n- Perfect for local development and testing\n\n#### Important Notes About ngrok\n- Free tier URLs change every time you restart ngrok (e.g., `https://xxxx-xxxx.ngrok-free.app`)\n- If your ngrok URL changes, you'll need to update your Salesforce configurations\n- Consider a paid ngrok account for persistent URLs in team environments\n- The free tier has usage limits but is sufficient for most development needs\n\n#### Set Up Steps\n\n1. Install ngrok:\n   ```bash\n   # macOS (using Homebrew)\n   brew install ngrok\n   \n   # Other platforms\n   Download from https://ngrok.com/download\n   ```\n\n2. Get your authtoken:\n   - Sign up at https://ngrok.com (free)\n   - Find your authtoken in your ngrok dashboard\n   - You only need to do this once\n\n3. Configure ngrok:\n   ```bash\n   # One-time setup\n   ngrok config add-authtoken YOUR_AUTH_TOKEN\n   ```\n\n4. Start the tunnel:\n   ```bash\n   ngrok http 3003\n   ```\n\n5. Save your ngrok URL:\n   - Look for the 'Forwarding' line in the ngrok output\n   - Save the HTTPS URL (e.g., `https://xxxx-xxxx.ngrok-free.app`)\n   - You'll need this URL for Salesforce configuration\n\n#### Monitoring Traffic\nThe ngrok inspector automatically launches at http://localhost:4040 and provides:\n- Real-time traffic monitoring\n- Request/response inspection\n- Replay capabilities\n- Detailed timing information\n- Network error detection\n\nKeep both the Mock Lobster interface and ngrok inspector open while debugging for complete visibility into your integration.\n\n### 4. Configure Salesforce\n\n1. Add Remote Site Setting:\n   - Navigate to Setup > Security > Remote Site Settings\n   - Click \"New Remote Site\"\n   - Name: `MockLobster_Ngrok`\n   - URL: Your ngrok URL\n   - Check \"Active\"\n   - Save\n\n2. Access Mock Lobster at http://localhost:3003 and create your first endpoint\n\n# Monitoring and Debugging\n\nMock Lobster provides comprehensive tools for monitoring and debugging your integrations:\n\n## Real-Time Request Monitoring\n\nThe main interface shows all incoming requests in real-time:\n- Request timestamp and method\n- Endpoint URL\n- Authentication status\n- Response status code\n- Request and response details\n\n## Request Inspection\n\nClick on any request to view detailed information:\n- Complete request headers\n- Query parameters\n- Request body (formatted JSON)\n- Response headers and body\n- Timing information\n\n## Using the ngrok Inspector\n\nThe ngrok inspector (http://localhost:4040) provides additional insights:\n- Network-level request/response details\n- Detailed timing information\n- Request replay capabilities\n- TLS/SSL verification status\n\n## Debugging Tips\n\n1. Keep both interfaces open while testing:\n   - Mock Lobster UI for application-level monitoring\n   - ngrok Inspector for network-level details\n\n2. Use the filter options to focus on specific endpoints or request types\n\n3. Check the terminal output when running in development mode (`npm run dev`) for server-side logs\n\n4. Common issues to check:\n   - Correct ngrok URL in Salesforce configuration\n   - Valid authentication credentials\n   - Proper request headers and body format\n   - Network connectivity and TLS/SSL status\n\n# Creating and Managing Endpoints\n\n## Using the Mock Lobster Interface\n\nMock Lobster provides a modern, intuitive web interface for creating and managing your test endpoints. Here's how to use it:\n\n### Creating Your First Endpoint\n\n1. Access Mock Lobster at http://localhost:3003\n2. Click the \"+\" button to create a new endpoint\n3. Configure your endpoint:\n   - Choose \"No Auth\" for simple testing\n   - Choose \"OAuth\" to set up OAuth 2.0 client credentials flow\n4. Click \"Create\"\n\nYour new endpoint will appear in the list with its unique URL and configuration details.\n\n### Managing Endpoints\n\nThe interface provides several features:\n- **Endpoint List**: View all your created endpoints with their URLs and auth details\n- **Request History**: See all incoming requests in real-time\n- **Request Details**: Click on any request to view:\n  - Headers\n  - Query parameters\n  - Request body\n  - Response details\n- **Filter Options**: Filter endpoints by type (All, OAuth, No Auth)\n- **View Options**: Toggle between different view layouts\n\n### Testing Your Endpoints\n\n#### Simple Test (No Auth)\n\nThe simplest way to start is with an unauthenticated endpoint. Copy this code to Salesforce's Developer Console and execute it in Anonymous Apex:\n\n```apex\n// Create a descriptive payload\nMap<String, Object> requestBody = new Map<String, Object>{\n    'message' => 'Hello from Salesforce!',\n    'timestamp' => System.now()\n};\n\n// Make the callout\nHttp http = new Http();\nHttpRequest request = new HttpRequest();\nrequest.setEndpoint('https://xxxx-xxxx.ngrok-free.app/webhook/your-endpoint-id');\nrequest.setMethod('POST');\nrequest.setHeader('Content-Type', 'application/json');\nrequest.setBody(JSON.serialize(requestBody));\n\nHttpResponse response = http.send(request);\nSystem.debug('Response Status: ' + response.getStatusCode());\nSystem.debug('Response Body: ' + response.getBody());\n```\n\n## Authentication Methods\n\n## No Authentication\nPerfect for initial testing and simple integrations. Create an endpoint and start sending requests immediately.\n\n## OAuth 2.0 Configuration\n\nOAuth provides a more secure and flexible authentication method. Follow these steps to configure Salesforce for OAuth integration:\n\n### Step 1: Set Up External Credential\n\n1. Navigate to Setup → Security → External Credentials\n2. Click \"New External Credential\"\n3. Fill in these details:\n   - Label: Mock_Lobster_Auth\n   - Name: Mock_Lobster_Auth\n   - Authentication Protocol: OAuth 2.0\n   - Authentication Flow Type: Client Credentials Flow\n   - Token URL: Your ngrok URL + /oauth2/token (e.g., https://your-ngrok-url/oauth2/token)\n   - Scope: Leave empty\n   - Pass client credentials in request body: ✓ Checked (Important for Mock Lobster)\n\n4. Create a Principal:\n   - Click \"New Principal\" after saving the External Credential\n   - Parameter Name: Mock_Lobster_Principal\n   - Sequence Number: 1\n   - Client ID: (from Mock Lobster interface)\n   - Client Secret: (from Mock Lobster interface)\n\n### Step 2: Set Up Named Credential\n\n1. Navigate to Setup → Security → Named Credentials\n2. Click \"New Named Credential\"\n3. Fill in these details:\n   - Label: Mock_Lobster_Integration\n   - Name: Mock_Lobster_Integration\n   - URL: Your ngrok URL (e.g., https://your-ngrok-url)\n   - External Credential: Select Mock_Lobster_Auth\n   - Generate Authorization Header: ✓ Checked\n\n### Step 3: Set Up Permission Set\n\n1. Navigate to Setup → Users → Permission Sets\n2. Click \"New\"\n3. Create Permission Set:\n   - Label: Mock_Lobster_Access\n   - Name: Mock_Lobster_Access\n4. After saving, click \"External Credential Principal Access\"\n5. Add access to Mock_Lobster_Auth credential\n6. Assign the Permission Set to your user\n\n# Validating Your Setup\n\nAfter setting up Mock Lobster and configuring Salesforce, you should validate your endpoints using Salesforce's Anonymous Apex. Below are examples for each authentication type.\n\n## Testing No Authentication Endpoints\n\nThe simplest way to start is with an unauthenticated endpoint. Copy this code to Salesforce's Developer Console and execute it in Anonymous Apex:\n\n```apex\n// Create a descriptive payload\nMap<String, Object> requestBody = new Map<String, Object>{\n    'message' => 'Hello Mock Lobster!',\n    'timestamp' => DateTime.now().format('yyyy-MM-dd HH:mm:ss'),\n    'org' => UserInfo.getOrganizationName()\n};\n\n// Initialize HTTP objects\nHttp http = new Http();\nHttpRequest request = new HttpRequest();\n\n// Use your specific ngrok URL and endpoint ID\nrequest.setEndpoint('https://xxxx-xxxx.ngrok-free.app/webhook/your-endpoint-id');\nrequest.setMethod('POST');\nrequest.setHeader('Content-Type', 'application/json');\nrequest.setBody(JSON.serialize(requestBody));\n\n// Log what we're about to send\nSystem.debug('Preparing to send request to Mock Lobster...');\nSystem.debug('Request Body: ' + JSON.serializePretty(requestBody));\n\ntry {\n    // Send the request and capture the response\n    HttpResponse response = http.send(request);\n    \n    // Log detailed information about what happened\n    System.debug('Request completed');\n    System.debug('Status Code: ' + response.getStatusCode());\n    System.debug('Response Body: ' + response.getBody());\n    \n    // Provide meaningful feedback\n    if (response.getStatusCode() == 200) {\n        System.debug('SUCCESS: Mock Lobster received and processed the request');\n    } else {\n        System.debug('WARNING: Unexpected response from Mock Lobster');\n        System.debug('Full Response Details: ' + response);\n    }\n} catch (Exception e) {\n    System.debug('ERROR: Failed to communicate with Mock Lobster');\n    System.debug('Error Type: ' + e.getTypeName());\n    System.debug('Error Message: ' + e.getMessage());\n}\n```\n\n## Testing OAuth Endpoints\n\nOAuth endpoints require more setup but provide better security. First ensure you've completed the OAuth setup steps, then use this code:\n\n```apex\n// Create a descriptive payload\nMap<String, Object> payload = new Map<String, Object>{\n    'message' => 'Testing OAuth integration',\n    'timestamp' => DateTime.now().format('yyyy-MM-dd HH:mm:ss'),\n    'org' => UserInfo.getOrganizationName()\n};\n\n// Initialize HTTP objects\nHttp http = new Http();\nHttpRequest request = new HttpRequest();\n\n// Use the Named Credential format for the endpoint\n// Format: callout:NamedCredentialName/webhook/endpointID\nrequest.setEndpoint('callout:Mock_Lobster_Integration/webhook/your-endpoint-id');\n\n// Set up the request\nrequest.setMethod('POST');\nrequest.setHeader('Content-Type', 'application/json');\nrequest.setBody(JSON.serialize(payload));\n\ntry {\n    HttpResponse response = http.send(request);\n    \n    System.debug('Request completed');\n    System.debug('Status Code: ' + response.getStatusCode());\n    System.debug('Response Body: ' + response.getBody());\n    \n    if (response.getStatusCode() == 200) {\n        System.debug('SUCCESS: Request processed by Mock Lobster');\n    } else {\n        System.debug('WARNING: Unexpected status code');\n        System.debug('Response Headers: ' + response.getHeaderKeys());\n    }\n} catch (Exception e) {\n    System.debug('ERROR: Failed to send request');\n    System.debug('Error Message: ' + e.getMessage());\n}\n```\n\n### Common Debug Log Messages\n\n#### Success Scenario\n```\nRequest completed\nStatus Code: 200\nResponse Body: {\"message\":\"Request received successfully\",\"requestId\":\"...\"}\nSUCCESS: Request processed by Mock Lobster\n```\n\n#### OAuth Error\n```\nWARNING: Unexpected status code\nStatus Code: 401\nResponse Body: {\"error\":\"invalid_token\",\"error_description\":\"Invalid or expired token\"}\n```\n\n#### Permission Error\n```\nERROR: Failed to send request\nError Message: User does not have access to external credential principal\n```\n\n### Verifying Requests in Mock Lobster\n\nAfter sending either type of request:\n\n1. Check the Mock Lobster interface:\n   - Click \"View Requests\" on your endpoint\n   - Verify the request was received\n   - Check that all headers and payload data are correct\n\n2. Check the ngrok inspector (http://localhost:4040):\n   - Look for your request in the traffic log\n   - For OAuth requests, verify token requests and usage\n   - Check for any SSL/TLS issues\n\nIf you encounter issues:\n- Verify your ngrok URL is current (it changes in free tier)\n- Confirm Remote Site Settings are up to date\n- For OAuth, verify Named Credential configuration\n- Check server logs for any errors\n\n## Debug Tools\n\nMock Lobster provides two debugging interfaces:\n\n### Debug Interfaces\n\nMock Lobster provides two complementary interfaces for debugging your integrations:\n\n#### Mock Lobster Interface (http://localhost:3003)\n- Shows configured endpoints and their settings\n- Displays received requests with parsed data\n- Provides authentication configuration details\n- Offers a high-level view of your integration\n\n#### ngrok Inspector (http://localhost:4040/inspect/http)\nThe inspection interface provides real-time inspection of all HTTP traffic flowing through your ngrok tunnel, which is invaluable for debugging. You can:\n- View complete request and response details\n- Inspect headers, query parameters, and body content\n- Replay requests with modifications for testing\n- Monitor connection latency and timing\n- Export request/response pairs for documentation\n- Debug authentication issues by examining token flows\n\nWhen debugging integration issues, it's helpful to arrange these interfaces side by side in your browser. The ngrok inspector shows you exactly what's being sent over the wire, while the Mock Lobster interface shows you how that data is being processed and interpreted.\n\n### Debugging OAuth Flows\n\nOAuth integrations can be particularly complex to debug. Here's how to use both interfaces effectively:\n\n1. In the ngrok inspector:\n   - Look for the initial token request (POST to /oauth2/token)\n   - Verify the client credentials are being sent correctly\n   - Check the token response format\n   - Follow subsequent requests using the token\n   - Monitor token expiration and renewal\n\n2. In the Mock Lobster interface:\n   - Confirm endpoint configuration is correct\n   - Verify OAuth credentials are recognized\n   - Check if requests are being authenticated\n   - Monitor for authentication errors\n\n## Testing Pub/Sub Integration\n\nMock Lobster provides built-in support for testing Salesforce Pub/Sub API integrations. Here's how to use it:\n\n### Setting Up Pub/Sub Testing\n\n1. Navigate to the Pub/Sub tab in the Mock Lobster UI\n2. Click \"Connect\" and enter your Salesforce Pub/Sub credentials:\n   - Username\n   - Instance URL\n   - Client ID\n   - Client Secret\n\n### Subscribe to Topics\n\n1. Once connected, enter the topic name you want to subscribe to\n2. Click \"Subscribe\" to start receiving events\n3. All received events will be displayed in real-time in the events panel\n\n### Monitoring Events\n\n- View event payloads and metadata in real-time\n- Events are preserved across page refreshes\n- Filter and search through received events\n- Clear event history as needed\n\n### Example Apex Code\n\nHere's an example of publishing an event from Salesforce that Mock Lobster can receive:\n\n```apex\n// Create a descriptive event payload\nMap<String, Object> eventData = new Map<String, Object>{\n    'message' => 'Test Event',\n    'timestamp' => DateTime.now().format('yyyy-MM-dd HH:mm:ss'),\n    'org' => UserInfo.getOrganizationName()\n};\n\n// Publish the event\nEventBus.publish(new Custom_Event__e(\n    Payload__c = JSON.serialize(eventData)\n));\n```\n\n### Troubleshooting Pub/Sub\n\nIf you encounter issues:\n1. Verify your credentials are correct\n2. Ensure the topic exists in your Salesforce org\n3. Check that your user has the necessary permissions\n4. Verify the event schema matches your expectations\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Port Selection**\n   - Default port is 3003\n   - Automatically finds next available port if 3003 is in use\n   - Port selection sequence: 3003, 3004, 3005, ...\n   - Selected port is shown in console on startup\n   - Override with PORT environment variable\n\n2. **Port Conflicts (`EADDRINUSE`)**\n   ```bash\n   # Option 1: Free the specific port\n   kill $(lsof -t -i:3003)\n   \n   # Option 2: Use different port\n   PORT=3456 npm run dev\n   \n   # Option 3: Let Mock Lobster find an available port automatically\n   npm run dev\n   ```\n\n3. **Salesforce Connection Issues**\n   - Verify Remote Site Setting matches ngrok URL exactly\n   - Ensure ngrok URL uses HTTPS\n   - Check if ngrok URL has changed (free tier)\n\n4. **Authentication Failures**\n   - Verify credentials match Mock Lobster configuration\n   - Check OAuth token endpoint URL\n   - Confirm Named Credential setup\n\n## Server Logging\n\nMock Lobster includes built-in logging to help monitor and troubleshoot your API testing:\n\n### HTTP Request Logging\n- All incoming HTTP requests are automatically logged using Morgan middleware\n- Logs include request method, path, status code, and response time\n- Example log format:\n  ```\n  GET /api/endpoints 200 2.676 ms\n  POST /webhook/endpoint-1 200 0.878 ms\n  GET /error 500 1.190 ms\n  ```\n\n### Configuration\nLogging can be enabled/disabled through server options:\n```javascript\nconst server = new Server({\n    enableLogging: true,  // Enable detailed request logging\n    logFormat: 'combined' // Use combined log format\n});\n```\n\n### What's Logged\n1. **Server Events**\n   - Server startup and configuration\n   - Port binding and listening status\n   - Shutdown events\n\n2. **Request Details**\n   - HTTP method and URL\n   - Response status codes\n   - Request processing time\n   - Error conditions\n\n3. **OAuth Operations**\n   - Token generation events\n   - Authentication failures\n   - Client validation results\n\n4. **PubSub Events**\n   - Connection status\n   - Subscription events\n   - Stream errors\n\n### Viewing Logs\n- When running in development mode (`npm run dev`), logs appear in your terminal\n- Test logs can be captured using:\n  ```bash\n  npm run test:coverage:detailed > test-logs.txt\n  ```\n\nRemember: For detailed request/response inspection beyond server logs, use the ngrok inspector at http://localhost:4040.\n\n## Development\n\n### Project Structure\n```\nmock-lobster/\n├── src/                    # Source code\n│   ├── server.js          # Main application entry point\n│   ├── endpoint-service.js # Endpoint handling and management\n│   └── oauth-service.js    # OAuth authentication logic\n├── public/                 # Static assets\n│   ├── app.html           # Main application interface\n│   ├── styles/            # CSS stylesheets\n│   └── scripts/           # Frontend JavaScript\n└── package.json           # Project configuration\n```\n\n### Contributing\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make changes and test (`npm test`)\n4. Commit changes (`git commit -m 'Add amazing feature'`)\n5. Create Pull Request\n\n## License\n\nThis project is licensed under the MIT License. See the LICENSE file for details.\n\n## Why \"Mock Lobster\"?\n\nIn the vast ocean of API testing tools, Mock Lobster stands out with its distinctive approach to handling integration challenges. Just as a lobster's powerful claws help it navigate and manipulate its environment with precision, Mock Lobster helps developers grasp and manage their integration testing needs with ease. And yes, it's absolutely a B-52's reference! 🎸\n\n---\n\nMade with 🦞 by developers who love good tools and better puns","readmeFilename":"README.md"}