3.0 KiB
3.0 KiB
Implementation Hints and Learnings
SmartProxy Usage
Direct Component Usage
- Use SmartProxy components directly instead of creating your own wrappers
- SmartProxy already includes Port80Handler and NetworkProxy functionality
- When using SmartProxy, configure it directly rather than instantiating Port80Handler or NetworkProxy separately
// PREFERRED: Use SmartProxy with built-in ACME support
const smartProxy = new plugins.smartproxy.SmartProxy({
fromPort: 443,
toPort: targetPort,
targetIP: targetServer,
sniEnabled: true,
acme: {
port: 80,
enabled: true,
autoRenew: true,
useProduction: true,
renewThresholdDays: 30,
accountEmail: contactEmail
},
globalPortRanges: [{ from: 443, to: 443 }],
domainConfigs: [/* domain configurations */]
});
Certificate Management
- SmartProxy has built-in ACME certificate management
- Configure it in the
acme
property of SmartProxy options - Use
accountEmail
(notemail
) for the ACME contact email - SmartProxy handles both HTTP-01 challenges and certificate application automatically
qenv Usage
Direct Usage
- Use qenv directly instead of creating environment variable wrappers
- Instantiate qenv with appropriate basePath and nogitPath:
const qenv = new plugins.qenv.Qenv('./', '.nogit/');
const value = await qenv.getEnvVarOnDemand('ENV_VAR_NAME');
TypeScript Interfaces
SmartProxy Interfaces
- Always check the interfaces from the node_modules to ensure correct property names
- Important interfaces:
ISmartProxyOptions
: Main configuration for SmartProxyIAcmeOptions
: ACME certificate configurationIDomainConfig
: Domain-specific configuration
Required Properties
- Remember to include all required properties in your interface implementations
- For
ISmartProxyOptions
,globalPortRanges
is required - For
IAcmeOptions
, useaccountEmail
for the contact email
Testing
Test Structure
- Follow the project's test structure, using
@push.rocks/tapbundle
- Use
expect(value).toEqual(expected)
for equality checks - Use
expect(value).toBeTruthy()
for boolean assertions
tap.test('test description', async () => {
const result = someFunction();
expect(result.property).toEqual('expected value');
expect(result.valid).toBeTruthy();
});
Cleanup
- Include a cleanup test to ensure proper test resource handling
- Add a
stop
test to forcefully end the test when needed:
tap.test('stop', async () => {
await tap.stopForcefully();
});
Architecture Principles
Simplicity
- Prefer direct usage of libraries instead of creating wrappers
- Don't reinvent functionality that already exists in dependencies
- Keep interfaces clean and focused, avoiding unnecessary abstraction layers
Component Integration
- Leverage built-in integrations between components (like SmartProxy's ACME handling)
- Use parallel operations for performance (like in the
stop()
method) - Separate concerns clearly (HTTP handling vs. SMTP handling)