8 Commits

Author SHA1 Message Date
fc88555790 v5.2.6
Some checks failed
CI / Type Check & Lint (push) Failing after 4s
CI / Build Test (Current Platform) (push) Failing after 4s
CI / Build All Platforms (push) Failing after 4s
Publish to npm / npm-publish (push) Failing after 5s
Release / build-and-release (push) Failing after 4s
2026-02-26 17:08:29 +00:00
4eb2fe7934 fix(postinstall): remove legacy postinstall binary installer and packaging entry 2026-02-26 17:08:29 +00:00
438242df07 v5.2.5
Some checks failed
CI / Type Check & Lint (push) Failing after 4s
CI / Build Test (Current Platform) (push) Failing after 4s
CI / Build All Platforms (push) Failing after 4s
Publish to npm / npm-publish (push) Failing after 6s
Release / build-and-release (push) Failing after 5s
2026-02-26 17:06:40 +00:00
1bb48b2530 fix(package): remove CLI bin wrapper and exclude bin/ from published files 2026-02-26 17:06:40 +00:00
3e76662933 v5.2.4
Some checks failed
CI / Type Check & Lint (push) Failing after 4s
CI / Build Test (Current Platform) (push) Failing after 4s
CI / Build All Platforms (push) Failing after 4s
Publish to npm / npm-publish (push) Failing after 5s
Release / build-and-release (push) Failing after 4s
2026-02-26 17:02:19 +00:00
efb49b67c6 fix(repo): no changes detected — no version bump required 2026-02-26 17:02:19 +00:00
bbe56247bd v5.2.3
Some checks failed
CI / Type Check & Lint (push) Failing after 7s
CI / Build Test (Current Platform) (push) Failing after 6s
CI / Build All Platforms (push) Failing after 5s
Publish to npm / npm-publish (push) Failing after 7s
Release / build-and-release (push) Failing after 6s
2026-02-26 16:58:06 +00:00
71a0ec3202 fix(delivery): prevent throttle reset timer from firing after stop and avoid scheduling duplicate timers 2026-02-26 16:58:06 +00:00
5 changed files with 42 additions and 239 deletions

View File

@@ -1,5 +1,32 @@
# Changelog
## 2026-02-26 - 5.2.6 - fix(postinstall)
remove legacy postinstall binary installer and packaging entry
- Deleted scripts/install-binary.js (legacy postinstall script that downloaded platform-specific binaries).
- Removed reference to scripts/install-binary.js from package.json "files" array so the installer is no longer included in published packages.
- This prevents automatic binary downloads during npm install and reduces package size; recommend a patch version bump.
## 2026-02-26 - 5.2.5 - fix(package)
remove CLI bin wrapper and exclude bin/ from published files
- Removed "bin" entry from package.json (mailer wrapper)
- Removed "bin/" from files array to prevent including CLI wrapper in published package
## 2026-02-26 - 5.2.4 - fix(repo)
no changes detected — no version bump required
- git diff contains no changes
- package.json version is 5.2.3
- no files modified — no release required
## 2026-02-26 - 5.2.3 - fix(delivery)
prevent throttle reset timer from firing after stop and avoid scheduling duplicate timers
- add throttleResetTimer property to track scheduled throttle-reset timeout
- clear throttleResetTimer when stopping to prevent it firing after shutdown
- clear existing throttleResetTimer before scheduling a new one and null it when fired to avoid duplicate timers and potential leaks
## 2026-02-12 - 5.2.2 - fix(deps)
bump dependencies: @push.rocks/smartrust to ^1.2.1, lru-cache to ^11.2.6

View File

@@ -1,6 +1,6 @@
{
"name": "@push.rocks/smartmta",
"version": "5.2.2",
"version": "5.2.6",
"description": "A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.",
"keywords": [
"mta",
@@ -30,9 +30,6 @@
"exports": {
".": "./dist_ts/index.js"
},
"bin": {
"mailer": "./bin/mailer-wrapper.js"
},
"scripts": {
"test": "tstest test/ --logfile --verbose --timeout 60",
"build": "tsbuild tsfolders && tsrust",
@@ -61,8 +58,6 @@
"files": [
"ts/**/*",
"dist_ts/**/*",
"bin/",
"scripts/install-binary.js",
"dist_rust/**/*",
"readme.md",
"license",

View File

@@ -1,230 +0,0 @@
#!/usr/bin/env node
/**
* MAILER npm postinstall script
* Downloads the appropriate binary for the current platform from GitHub releases
*/
import { platform, arch } from 'os';
import { existsSync, mkdirSync, writeFileSync, chmodSync, unlinkSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import https from 'https';
import { pipeline } from 'stream';
import { promisify } from 'util';
import { createWriteStream } from 'fs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const streamPipeline = promisify(pipeline);
// Configuration
const REPO_BASE = 'https://code.foss.global/serve.zone/mailer';
const VERSION = process.env.npm_package_version || '1.0.0';
function getBinaryInfo() {
const plat = platform();
const architecture = arch();
const platformMap = {
'darwin': 'macos',
'linux': 'linux',
'win32': 'windows'
};
const archMap = {
'x64': 'x64',
'arm64': 'arm64'
};
const mappedPlatform = platformMap[plat];
const mappedArch = archMap[architecture];
if (!mappedPlatform || !mappedArch) {
return { supported: false, platform: plat, arch: architecture };
}
let binaryName = `mailer-${mappedPlatform}-${mappedArch}`;
if (plat === 'win32') {
binaryName += '.exe';
}
return {
supported: true,
platform: mappedPlatform,
arch: mappedArch,
binaryName,
originalPlatform: plat
};
}
function downloadFile(url, destination) {
return new Promise((resolve, reject) => {
console.log(`Downloading from: ${url}`);
// Follow redirects
const download = (url, redirectCount = 0) => {
if (redirectCount > 5) {
reject(new Error('Too many redirects'));
return;
}
https.get(url, (response) => {
if (response.statusCode === 301 || response.statusCode === 302) {
console.log(`Following redirect to: ${response.headers.location}`);
download(response.headers.location, redirectCount + 1);
return;
}
if (response.statusCode !== 200) {
reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
return;
}
const totalSize = parseInt(response.headers['content-length'], 10);
let downloadedSize = 0;
let lastProgress = 0;
response.on('data', (chunk) => {
downloadedSize += chunk.length;
const progress = Math.round((downloadedSize / totalSize) * 100);
// Only log every 10% to reduce noise
if (progress >= lastProgress + 10) {
console.log(`Download progress: ${progress}%`);
lastProgress = progress;
}
});
const file = createWriteStream(destination);
pipeline(response, file, (err) => {
if (err) {
reject(err);
} else {
console.log('Download complete!');
resolve();
}
});
}).on('error', reject);
};
download(url);
});
}
async function main() {
console.log('===========================================');
console.log(' MAILER - Binary Installation');
console.log('===========================================');
console.log('');
const binaryInfo = getBinaryInfo();
if (!binaryInfo.supported) {
console.error(`❌ Error: Unsupported platform/architecture: ${binaryInfo.platform}/${binaryInfo.arch}`);
console.error('');
console.error('Supported platforms:');
console.error(' • Linux (x64, arm64)');
console.error(' • macOS (x64, arm64)');
console.error(' • Windows (x64)');
console.error('');
console.error('If you believe your platform should be supported, please file an issue:');
console.error(' https://code.foss.global/serve.zone/mailer/issues');
process.exit(1);
}
console.log(`Platform: ${binaryInfo.platform} (${binaryInfo.originalPlatform})`);
console.log(`Architecture: ${binaryInfo.arch}`);
console.log(`Binary: ${binaryInfo.binaryName}`);
console.log(`Version: ${VERSION}`);
console.log('');
// Create dist/binaries directory if it doesn't exist
const binariesDir = join(__dirname, '..', 'dist', 'binaries');
if (!existsSync(binariesDir)) {
console.log('Creating binaries directory...');
mkdirSync(binariesDir, { recursive: true });
}
const binaryPath = join(binariesDir, binaryInfo.binaryName);
// Check if binary already exists and skip download
if (existsSync(binaryPath)) {
console.log('✓ Binary already exists, skipping download');
} else {
// Construct download URL
// Try release URL first, fall back to raw branch if needed
const releaseUrl = `${REPO_BASE}/releases/download/v${VERSION}/${binaryInfo.binaryName}`;
const fallbackUrl = `${REPO_BASE}/raw/branch/main/dist/binaries/${binaryInfo.binaryName}`;
console.log('Downloading platform-specific binary...');
console.log('This may take a moment depending on your connection speed.');
console.log('');
try {
// Try downloading from release
await downloadFile(releaseUrl, binaryPath);
} catch (err) {
console.log(`Release download failed: ${err.message}`);
console.log('Trying fallback URL...');
try {
// Try fallback URL
await downloadFile(fallbackUrl, binaryPath);
} catch (fallbackErr) {
console.error(`❌ Error: Failed to download binary`);
console.error(` Primary URL: ${releaseUrl}`);
console.error(` Fallback URL: ${fallbackUrl}`);
console.error('');
console.error('This might be because:');
console.error('1. The release has not been created yet');
console.error('2. Network connectivity issues');
console.error('3. The version specified does not exist');
console.error('');
console.error('You can try:');
console.error('1. Installing from source: https://code.foss.global/serve.zone/mailer');
console.error('2. Downloading the binary manually from the releases page');
// Clean up partial download
if (existsSync(binaryPath)) {
unlinkSync(binaryPath);
}
process.exit(1);
}
}
console.log(`✓ Binary downloaded successfully`);
}
// On Unix-like systems, ensure the binary is executable
if (binaryInfo.originalPlatform !== 'win32') {
try {
console.log('Setting executable permissions...');
chmodSync(binaryPath, 0o755);
console.log('✓ Binary permissions updated');
} catch (err) {
console.error(`⚠️ Warning: Could not set executable permissions: ${err.message}`);
console.error(' You may need to manually run:');
console.error(` chmod +x ${binaryPath}`);
}
}
console.log('');
console.log('✅ MAILER installation completed successfully!');
console.log('');
console.log('You can now use MAILER by running:');
console.log(' mailer --help');
console.log('');
console.log('For initial setup, run:');
console.log(' sudo mailer service enable');
console.log('');
console.log('===========================================');
}
// Run the installation
main().catch(err => {
console.error(`❌ Installation failed: ${err.message}`);
process.exit(1);
});

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartmta',
version: '5.2.2',
version: '5.2.6',
description: 'A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.'
}

View File

@@ -108,6 +108,7 @@ export class MultiModeDeliverySystem extends EventEmitter {
private activeDeliveries: Set<string> = new Set();
private running: boolean = false;
private throttled: boolean = false;
private throttleResetTimer: ReturnType<typeof setTimeout> | null = null;
private rateLimitLastCheck: number = Date.now();
private rateLimitCounter: number = 0;
private emailServer?: UnifiedEmailServer;
@@ -211,7 +212,13 @@ export class MultiModeDeliverySystem extends EventEmitter {
}
this.running = false;
// Clear throttle reset timer to prevent it firing after stop
if (this.throttleResetTimer) {
clearTimeout(this.throttleResetTimer);
this.throttleResetTimer = null;
}
// Wait for active deliveries to complete
if (this.activeDeliveries.size > 0) {
logger.log('info', `Waiting for ${this.activeDeliveries.size} active deliveries to complete`);
@@ -776,7 +783,11 @@ export class MultiModeDeliverySystem extends EventEmitter {
// Schedule throttle reset
const resetDelay = 60000 - elapsed;
setTimeout(() => {
if (this.throttleResetTimer) {
clearTimeout(this.throttleResetTimer);
}
this.throttleResetTimer = setTimeout(() => {
this.throttleResetTimer = null;
this.throttled = false;
this.rateLimitLastCheck = Date.now();
this.rateLimitCounter = 0;