Compare commits

..

No commits in common. "a7ac8c85f322150d159be744addcaffebd44420f" and "c1585ed09a05dce0c3f26b3d173d7062db514906" have entirely different histories.

4 changed files with 10 additions and 78 deletions

View File

@ -75,29 +75,7 @@
return `${base}${ext}`;
}
/**
* Reverse of resolveLogFileName: given a full filename like
* "fileuploader-2026-06-03.log" or
* "fileuploader-session-2026-06-03_18-16-20-8132.log", strip the mode-stamp
* so the bare base ("fileuploader.log") remains. Used when persisting an
* auto-resolved fallback path back into config otherwise the saved path
* would keep growing a new stamp on every reload.
*/
function stripModeStampFromFileName(fileName) {
if (!fileName || typeof fileName !== 'string') return fileName;
// Order matters: session first (longer, more specific) before daily.
// Both regexes are anchored to $ with no nested/ambiguous quantifiers, so
// matching is linear — the eslint security warning is precautionary.
// eslint-disable-next-line security/detect-unsafe-regex
const sessionRe = /-session-\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(?:-\d+)?(\.[^.]+)?$/;
// eslint-disable-next-line security/detect-unsafe-regex
const dailyRe = /-\d{4}-\d{2}-\d{2}(\.[^.]+)?$/;
let out = fileName.replace(sessionRe, (m, ext) => ext || '');
out = out.replace(dailyRe, (m, ext) => ext || '');
return out;
}
const api = { normalizeLogMode, resolveLogFileName, formatDateStamp, formatSessionStamp, stripModeStampFromFileName, VALID_MODES };
const api = { normalizeLogMode, resolveLogFileName, formatDateStamp, formatSessionStamp, VALID_MODES };
if (typeof module !== 'undefined' && module.exports) {
module.exports = api;

18
main.js
View File

@ -245,7 +245,7 @@ function getBaseLogFilePath() {
// given session lands in the same file. A close→reopen of the app starts a new
// main process, so a new SESSION_ID, so a new session file. PID is appended as
// a cheap hedge against same-second restart collisions.
const { resolveLogFileName, formatSessionStamp, formatDateStamp, stripModeStampFromFileName } = require('./lib/log-mode');
const { resolveLogFileName, formatSessionStamp, formatDateStamp } = require('./lib/log-mode');
const SESSION_ID = formatSessionStamp(new Date(), process.pid);
let _activeLogKey = null; // remembers (mode + date-or-session) so cache rolls correctly
let _activeLogPath = null;
@ -398,18 +398,16 @@ function _persistFallbackLogPath(workingPath) {
try {
const cfg = configStore.load();
const gs = cfg.globalSettings || {};
const mode = gs.logMode || 'single';
// Strip the mode-specific suffix so logFilePath stores the BARE base path.
// Otherwise daily would compound into "...-2026-06-03-2026-06-04.log" and
// session would compound a second session-stamp onto the first — which split
// a session's lines across two files (the first few before _persistFallback
// ran, the rest after, into the doubly-stamped path). gated on logMode (the
// legacy `sessionLog` field is no longer the source of truth).
// If daily-log is on, workingPath has a date suffix (fileuploader-YYYY-MM-DD.log).
// Strip that before saving so the base path rolls forward to tomorrow's
// file correctly — otherwise the next day's getLogFilePath would append
// another date onto the already-dated base.
let toSave = workingPath;
if (mode === 'daily' || mode === 'session') {
if (gs.sessionLog) {
const dir = path.dirname(workingPath);
const base = path.basename(workingPath);
toSave = path.join(dir, stripModeStampFromFileName(base));
const stripped = base.replace(/-\d{4}-\d{2}-\d{2}(\.[^.]+)$/, '$1');
toSave = path.join(dir, stripped);
}
if (gs.logFilePath === toSave) return;
gs.logFilePath = toSave;

View File

@ -1,6 +1,6 @@
{
"name": "multi-hoster-uploader",
"version": "3.3.37",
"version": "3.3.36",
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
"main": "main.js",
"scripts": {

View File

@ -78,50 +78,6 @@ test('resolveLogFileName: unknown mode is treated as single', () => {
);
});
// --- stripModeStampFromFileName ---
const { stripModeStampFromFileName } = require('../lib/log-mode');
test('stripModeStampFromFileName: leaves bare names alone', () => {
assert.equal(stripModeStampFromFileName('fileuploader.log'), 'fileuploader.log');
assert.equal(stripModeStampFromFileName('fileuploader'), 'fileuploader');
});
test('stripModeStampFromFileName: strips a daily YYYY-MM-DD suffix', () => {
assert.equal(stripModeStampFromFileName('fileuploader-2026-06-03.log'), 'fileuploader.log');
});
test('stripModeStampFromFileName: strips a session-stamp suffix (with and without pid)', () => {
assert.equal(
stripModeStampFromFileName('fileuploader-session-2026-06-03_18-16-20-8132.log'),
'fileuploader.log'
);
assert.equal(
stripModeStampFromFileName('fileuploader-session-2026-06-03_18-16-20.log'),
'fileuploader.log'
);
});
test('regression: resolveLogFileName(stripModeStampFromFileName(...)) is idempotent — persisting then re-resolving never compounds stamps', () => {
// This is the exact bug shape: persist the resolved path, then on next call
// re-resolve from the saved base — must produce the same file, not a doubled
// session-stamped one. The fix is the strip; this test guards against
// regressing _persistFallbackLogPath into the 3.3.35 bug.
const sessionId = '2026-06-03_18-16-20-8132';
const dailyDate = new Date(2026, 5, 3);
for (const mode of ['daily', 'session']) {
const date = mode === 'daily' ? dailyDate : new Date();
const initial = resolveLogFileName({ baseName: 'fileuploader', ext: '.log', mode, date, sessionId });
const stripped = stripModeStampFromFileName(initial);
// After strip, the base should be back to the bare name.
assert.equal(stripped, 'fileuploader.log', `${mode}: strip should produce bare base`);
// Re-resolving from the bare base gives the same final filename — no doubling.
const reBase = stripped.replace(/\.log$/, '');
const second = resolveLogFileName({ baseName: reBase, ext: '.log', mode, date, sessionId });
assert.equal(second, initial, `${mode}: round-trip must be idempotent`);
}
});
// --- format helpers ---
test('formatDateStamp: zero-pads month and day', () => {