* docs: prepare Vendoo 1.41.2 git-ignore boundary hotfix * fix: track native source modules with root-anchored runtime ignores
108 lines
6.3 KiB
JavaScript
108 lines
6.3 KiB
JavaScript
import { readFileSync, mkdtempSync, mkdirSync, rmSync } from 'node:fs';
|
|
import { resolve, join } from 'node:path';
|
|
import { tmpdir } from 'node:os';
|
|
import sharp from 'sharp';
|
|
import { renderImageVersion, normalizeEditorOperations } from '../lib/image-editor.mjs';
|
|
|
|
const root = resolve(import.meta.dirname, '..');
|
|
const read = path => readFileSync(resolve(root, path), 'utf8');
|
|
const assert = (condition, message) => { if (!condition) throw new Error(message); };
|
|
|
|
const index = read('public/index.html');
|
|
const app = read('public/app.js');
|
|
const style = read('public/style.css');
|
|
const server = read('server.mjs');
|
|
const db = read('lib/db.mjs');
|
|
const jobs = read('lib/ai-flux-prompt-jobs.mjs');
|
|
const editor = read('lib/image-editor.mjs');
|
|
const setup = read('setup.ps1');
|
|
const packageJson = JSON.parse(read('package.json'));
|
|
|
|
assert(packageJson.version === '1.24.0', 'Paketversion ist nicht 1.24.0.');
|
|
assert(index.includes('name="vendoo-build" content="1.24.0"'), 'Build-Metadatum fehlt.');
|
|
assert(index.includes('style.css?v=1.24.0'), 'CSS-Cache-Buster fehlt.');
|
|
assert(index.includes('app.js?v=1.24.0'), 'JS-Cache-Buster fehlt.');
|
|
assert(app.includes("VENDOO_UI_BUILD = '1.24.0'"), 'UI-Buildkennung fehlt.');
|
|
assert(setup.includes('/?build=1.24.0'), 'Windows-Start-Cache-Buster fehlt.');
|
|
|
|
assert(index.includes('data-tab="media-library"'), 'Galerie-Navigation fehlt.');
|
|
assert(index.includes('id="media-library"'), 'Galerie-Seite fehlt.');
|
|
assert(index.includes('id="media-grid"'), 'Galerie-Raster fehlt.');
|
|
assert(index.includes('id="media-lightbox"'), 'Galerie-Lightbox fehlt.');
|
|
assert(app.includes('function setupMediaLibrary()'), 'Galerie-Interaktionen fehlen.');
|
|
assert(server.includes("app.get('/api/media-library'"), 'Galerie-API fehlt.');
|
|
assert(server.includes("app.delete('/api/media-library/items'"), 'Galerie-Lösch-API fehlt.');
|
|
assert(db.includes('export function listMediaLibraryItems'), 'Galerie-Datenaggregation fehlt.');
|
|
assert(db.includes('getListingReferencedMediaPaths'), 'Listing-Bildschutz fehlt.');
|
|
|
|
assert(index.includes('id="pe-background-sensitivity"'), 'Regler für Hintergrundentfernung fehlt.');
|
|
assert(index.includes('Niedriger schützt feine Kanten'), 'Erklärung der Hintergrundintensität fehlt.');
|
|
assert(app.includes('background_sensitivity'), 'Vorschau übernimmt Hintergrundintensität nicht.');
|
|
assert(editor.includes('solidThreshold = 24 + level * 2.1'), 'Serverseitige Intensitätslogik fehlt.');
|
|
|
|
assert(index.includes('id="flux-job-view-archive"'), 'FLUX-Archivumschalter fehlt.');
|
|
assert(index.includes('id="flux-job-delete-all-archive"'), 'Komplettes Archivlöschen fehlt.');
|
|
assert(index.includes('id="flux-job-page-size"'), 'Job-Center-Seitengröße fehlt.');
|
|
assert(index.includes('id="flux-job-pagination"'), 'Job-Center-Paginierung fehlt.');
|
|
assert(jobs.includes('archiveFluxPromptJobs'), 'FLUX-Archivfunktion fehlt.');
|
|
assert(jobs.includes('restoreFluxPromptJobs'), 'FLUX-Wiederherstellung fehlt.');
|
|
assert(jobs.includes('deleteArchivedFluxPromptJobs'), 'FLUX-Archivlöschung fehlt.');
|
|
assert(jobs.includes("status NOT IN ('queued','running','cancelling')"), 'Aktive Aufträge sind nicht gegen Archivierung geschützt.');
|
|
assert(db.includes('ALTER TABLE flux_prompt_jobs ADD COLUMN archived_at TEXT'), 'Additive Archivmigration fehlt.');
|
|
assert(server.includes("app.post('/api/flux-prompt/jobs/archive'"), 'Archiv-API fehlt.');
|
|
assert(server.includes("app.delete('/api/flux-prompt/jobs/archive'"), 'Archiv-Lösch-API fehlt.');
|
|
|
|
assert(style.includes('Real responsive listing cards'), 'Responsive Listing-Kartenregeln fehlen.');
|
|
assert(style.includes('@media (max-width: 860px)'), 'Tablet-/Mobil-Breakpoint fehlt.');
|
|
assert(style.includes('.history-table { min-width:0 !important;'), 'Listing-Tabelle bleibt auf Mobilbreite fixiert.');
|
|
assert(style.includes('.media-grid.is-list'), 'Galerie-Listenansicht ist nicht gestylt.');
|
|
assert(style.includes('.media-lightbox-dialog'), 'Galerie-Lightbox ist nicht gestylt.');
|
|
|
|
const extensionFiles = ['extension/content.js', 'extensions/content.js', 'extensions/chrome/content.js', 'extensions/edge/content.js', 'extensions/firefox/content.js'];
|
|
for (const file of extensionFiles) {
|
|
const content = read(file);
|
|
assert(content.includes('function isLikelyTitleField(el)'), `${file}: Vinted-Titelfeldschutz fehlt.`);
|
|
assert(content.includes('if (!trigger || isLikelyTitleField(trigger)) return false;'), `${file}: Auswahlfelder schützen den Titel nicht.`);
|
|
}
|
|
|
|
const temp = mkdtempSync(join(tmpdir(), 'vendoo-124-bg-'));
|
|
try {
|
|
const uploadRoot = join(temp, 'uploads');
|
|
mkdirSync(join(uploadRoot, 'verification'), { recursive: true });
|
|
const source = join(uploadRoot, 'verification', 'source.png');
|
|
const image = Buffer.from('<svg width="360" height="260" xmlns="http://www.w3.org/2000/svg"><rect width="360" height="260" fill="#f2eee8"/><rect x="80" y="45" width="200" height="170" rx="28" fill="#d8c7b4"/><rect x="120" y="75" width="120" height="110" rx="18" fill="#356a5d"/></svg>');
|
|
await sharp(image).png().toFile(source);
|
|
|
|
const render = async sensitivity => renderImageVersion({
|
|
uploadRoot,
|
|
sourcePath: 'verification/source.png',
|
|
rootPath: 'verification/source.png',
|
|
context: 'verification',
|
|
operations: normalizeEditorOperations({ remove_background: true, background_sensitivity: sensitivity, format: 'png' }),
|
|
});
|
|
const low = await render(5);
|
|
const high = await render(90);
|
|
const countTransparent = async filename => {
|
|
const raw = await sharp(join(uploadRoot, filename)).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
let count = 0;
|
|
for (let i = 3; i < raw.data.length; i += raw.info.channels) if (raw.data[i] < 32) count += 1;
|
|
return count;
|
|
};
|
|
const lowTransparent = await countTransparent(low.filename);
|
|
const highTransparent = await countTransparent(high.filename);
|
|
assert(highTransparent > lowTransparent, `Höhere Intensität entfernt nicht mehr Hintergrund (${lowTransparent} vs. ${highTransparent}).`);
|
|
console.log(JSON.stringify({
|
|
ok: true,
|
|
release: '1.24.0',
|
|
responsive_listing_cards: true,
|
|
flux_archive: true,
|
|
flux_pagination: true,
|
|
media_library: true,
|
|
listing_media_delete_protection: true,
|
|
background_sensitivity: { low_transparent_pixels: lowTransparent, high_transparent_pixels: highTransparent },
|
|
vinted_title_guard_preserved: true,
|
|
}, null, 2));
|
|
} finally {
|
|
rmSync(temp, { recursive: true, force: true });
|
|
}
|