移除导入时的缩略图生成
This commit is contained in:
1 parent
bb73cc9227
commit
fe71d2d6ce
32 files changed
+35
-4192
No files matched your search
@@ -38,6 +38,11 @@ for (const [label, files] of [
|
||||
]) {
|
||||
assert.equal(files.some((file) => /\.log$/i.test(file)), false, label + ' must not contain runtime or historical logs');
|
||||
assert.equal(files.some((file) => /(^|\/)\.DS_Store$/i.test(file)), false, label + ' must not contain macOS metadata');
|
||||
assert.equal(files.includes('thumbnail/spine.js'), false, label + ' must not contain an import-time Spine thumbnail handler');
|
||||
assert.equal(files.some((file) => /^node_modules\//.test(file)), false, label + ' must not contain unused native thumbnail dependencies');
|
||||
}
|
||||
|
||||
console.log('PASS: release directory and .eagleplugin contain no logs or .DS_Store files');
|
||||
const manifest = JSON.parse(fs.readFileSync(path.join(releaseDir, 'manifest.json'), 'utf8'));
|
||||
assert.equal(Object.values(manifest.preview || {}).some((entry) => entry && entry.thumbnail), false);
|
||||
|
||||
console.log('PASS: release has no logs, metadata, import thumbnail handler, or unused native thumbnail dependencies');
|
||||
@@ -64,14 +64,16 @@ try {
|
||||
fs.writeFileSync(path.join(maliciousDir, 'evil.atlas'), '../../../secret.png\nsize: 64,64\n');
|
||||
assert.throws(() => utils.discoverAssets(maliciousSkeleton), (error) => error && error.code === 'UNSAFE_ATLAS_PATH');
|
||||
|
||||
const thumbnailSource = fs.readFileSync(path.join(__dirname, '../thumbnail/spine.js'), 'utf8');
|
||||
assert.doesNotMatch(thumbnailSource, /setCustomThumbnail|refreshRelatedThumbnails|spine-reconcile-worker|relatedDataPaths/);
|
||||
const manifest = JSON.parse(fs.readFileSync(path.join(__dirname, '../manifest.json'), 'utf8'));
|
||||
const preview = Object.values(manifest.preview || {});
|
||||
assert.equal(preview.some((entry) => entry && entry.thumbnail), false, 'import-time thumbnail handler must stay disabled');
|
||||
assert.equal(fs.existsSync(path.join(__dirname, '../thumbnail/spine.js')), false);
|
||||
assert.equal(fs.existsSync(path.join(__dirname, '../js/spine-reconcile-worker.js')), false);
|
||||
const viewerSource = fs.readFileSync(path.join(__dirname, '../viewer/spine.html'), 'utf8');
|
||||
assert.match(viewerSource, /currentItem\.data\.customThumbnail === true && !window\.confirm/);
|
||||
assert.match(viewerSource, /path\.join\(os\.tmpdir\(\), 'spineviewer-current-'/);
|
||||
assert.doesNotMatch(viewerSource, /fs\.writeFileSync\(outPath/);
|
||||
console.log('PASS: atlas traversal, absolute paths, symlink escape, validated Eagle pairing, and no automatic cross-item thumbnail writes');
|
||||
console.log('PASS: atlas path boundaries, validated Eagle pairing, no import thumbnail handler, and manual current-item confirmation');
|
||||
} finally {
|
||||
fs.rmSync(root, { recursive: true, force: true });
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
'use strict';
|
||||
const assert = require('assert/strict');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { normalizeItem } = require('../js/eagle-compound');
|
||||
const generate = require('../thumbnail/spine');
|
||||
const { canvasLib } = require('../js/spine-render');
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'spine-compound-thumbnail-'));
|
||||
const fixtures = path.resolve(process.argv[2] || path.join(__dirname, '34-43/3.4/spineboy'));
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
for (const [name, ext, full] of [['lili.atlas', 'txt', 'atlas.txt'], ['lili.skel', 'bytes', 'skel.bytes']]) {
|
||||
const item = { name, ext, text: 'old text' };
|
||||
const source = path.join(root, name + '.' + ext);
|
||||
assert(normalizeItem(source, item));
|
||||
assert.equal(item.name, 'lili'); assert.equal(item.ext, full);
|
||||
assert.equal(path.basename(source), item.name + '.' + item.ext);
|
||||
assert.equal(item.text, undefined); assert.equal(normalizeItem(source, item), false);
|
||||
}
|
||||
for (const text of ['', 'ordinary text\nsecond line']) {
|
||||
const src = path.join(root, 'notes.txt'); fs.writeFileSync(src, text);
|
||||
const result = await generate({ src, dest: path.join(root, 'notes_thumbnail.png'), item: { name: 'notes', ext: 'txt' } });
|
||||
assert.equal(result.text, text); assert.equal(result.ext, 'txt'); assert.equal(result.name, 'notes');
|
||||
}
|
||||
const ordinaryJson = path.join(root, 'config.json');
|
||||
const ordinaryJsonDest = path.join(root, 'config_thumbnail.png');
|
||||
fs.writeFileSync(ordinaryJson, JSON.stringify({ skeleton: { spine: null }, enabled: true }));
|
||||
const ordinaryJsonItem = { name: 'config', ext: 'json' };
|
||||
assert.equal(await generate({ src: ordinaryJson, dest: ordinaryJsonDest, item: ordinaryJsonItem }), ordinaryJsonItem);
|
||||
assert.equal(fs.existsSync(ordinaryJsonDest), false, 'non-Spine JSON must leave thumbnail destination untouched');
|
||||
assert.equal(ordinaryJsonItem.width, undefined); assert.equal(ordinaryJsonItem.height, undefined);
|
||||
for (const [source, target] of [['spineboy-mesh.skel', 'spineboy.skel.bytes'], ['spineboy.atlas', 'spineboy.atlas.txt'], ['spineboy.png', 'spineboy.png']])
|
||||
fs.copyFileSync(path.join(fixtures, source), path.join(root, target));
|
||||
for (const [name, ext] of [['spineboy.atlas', 'txt'], ['spineboy.skel', 'bytes']]) {
|
||||
const src = path.join(root, name + '.' + ext), before = fs.readFileSync(src);
|
||||
const dest = path.join(root, name + '_thumbnail.png');
|
||||
const result = await generate({ src, dest, item: { name, ext } });
|
||||
assert.equal(result.name, 'spineboy'); assert.equal(result.ext, name.split('.')[1] + '.' + ext);
|
||||
assert(before.equals(fs.readFileSync(path.join(root, result.name + '.' + result.ext))));
|
||||
const canonical = path.join(root, 'spineboy_thumbnail.png');
|
||||
assert(fs.existsSync(dest)); assert(fs.existsSync(canonical));
|
||||
assert.equal(fs.readFileSync(canonical).subarray(8,12).toString(), 'WEBP');
|
||||
const image = await canvasLib.loadImage(canonical), canvas = canvasLib.createCanvas(400,400);
|
||||
const ctx = canvas.getContext('2d'); ctx.drawImage(image,0,0);
|
||||
const pixels = ctx.getImageData(12,356,110,32).data;
|
||||
let white = 0; for (let i = 0; i < pixels.length; i += 4) if (pixels[i]>190 && pixels[i+1]>190 && pixels[i+2]>190) white++;
|
||||
assert(white > 50, 'bottom-left version watermark must be visible');
|
||||
}
|
||||
console.log('PASS: ordinary TXT remains visible, compound metadata round-trip, canonical WebP cache and version watermark');
|
||||
} finally { fs.rmSync(root, { recursive: true, force: true }); }
|
||||
})().catch(error => { console.error(error); process.exitCode = 1; });
|
||||
Reference in new issue
Block a user