@file-viewer/vite-plugin 2.1.28 → 2.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +114 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
2
- import { copyFile, cp, mkdir, rm, stat, writeFile } from 'node:fs/promises';
2
+ import { copyFile, cp, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
3
3
  import { createRequire } from 'node:module';
4
- import { dirname, extname, isAbsolute, join, resolve } from 'node:path';
4
+ import { dirname, extname, isAbsolute, join, resolve, sep } from 'node:path';
5
5
  const virtualModuleId = 'virtual:file-viewer-renderers';
6
6
  const resolvedVirtualModuleId = `\0${virtualModuleId}`;
7
7
  const pluginRequire = createRequire(import.meta.url);
@@ -853,7 +853,8 @@ function resolveWorkspacePackageJson(packageName) {
853
853
  return workspacePackageJsonCache.packages.get(packageName) || null;
854
854
  }
855
855
  function resolvePackageJson(packageName, anchorPackages = []) {
856
- const requireFns = [projectRequire(), pluginRequire];
856
+ const rootRequireFns = [projectRequire(), pluginRequire];
857
+ const requireFns = [...rootRequireFns];
857
858
  const effectiveAnchorPackages = unique([
858
859
  ...Object.values(presetModules).map((preset) => preset.packageName),
859
860
  ...anchorPackages
@@ -874,7 +875,16 @@ function resolvePackageJson(packageName, anchorPackages = []) {
874
875
  }
875
876
  }
876
877
  }
877
- for (const requireFn of requireFns) {
878
+ const preferredAnchorPackageJsons = unique(anchorPackages
879
+ .map((anchorPackage) => requireFns
880
+ .map((requireFn) => tryResolvePackageJson(anchorPackage, requireFn))
881
+ .find(Boolean) || resolveWorkspacePackageJson(anchorPackage))
882
+ .filter((packageJson) => Boolean(packageJson)));
883
+ const targetRequireFns = [
884
+ ...preferredAnchorPackageJsons.map((packageJson) => createRequire(packageJson)),
885
+ ...requireFns
886
+ ];
887
+ for (const requireFn of targetRequireFns) {
878
888
  const packageJson = tryResolvePackageJson(packageName, requireFn);
879
889
  if (packageJson) {
880
890
  return packageJson;
@@ -932,6 +942,37 @@ function resolvePackageRoot(packageName, anchorPackages = []) {
932
942
  const packageJson = resolvePackageJson(packageName, anchorPackages);
933
943
  return packageJson ? dirname(packageJson) : null;
934
944
  }
945
+ function readPackageVersion(packageRoot) {
946
+ if (!packageRoot) {
947
+ return null;
948
+ }
949
+ try {
950
+ const packageJson = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'));
951
+ return packageJson.version || null;
952
+ }
953
+ catch {
954
+ return null;
955
+ }
956
+ }
957
+ function assertOwnedPackageVersion(packageName, packageRoot, ownerPackageName) {
958
+ if (!packageRoot) {
959
+ return null;
960
+ }
961
+ const ownerPackageJsonPath = resolvePackageJson(ownerPackageName);
962
+ if (!ownerPackageJsonPath) {
963
+ return readPackageVersion(packageRoot);
964
+ }
965
+ const ownerPackageJson = JSON.parse(readFileSync(ownerPackageJsonPath, 'utf8'));
966
+ const expectedVersion = ownerPackageJson.dependencies?.[packageName];
967
+ const actualVersion = readPackageVersion(packageRoot);
968
+ if (expectedVersion &&
969
+ /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(expectedVersion) &&
970
+ actualVersion !== expectedVersion) {
971
+ throw new Error(`[file-viewer:vite-plugin] ${ownerPackageName} requires ${packageName}@${expectedVersion}, ` +
972
+ `but renderer assets resolved from ${packageName}@${actualVersion || 'unknown'} (${packageRoot}).`);
973
+ }
974
+ return actualVersion;
975
+ }
935
976
  function resolvePackageEntry(packageName, anchorPackages = []) {
936
977
  const packageJsonPath = resolvePackageJson(packageName, anchorPackages);
937
978
  if (!packageJsonPath) {
@@ -1097,7 +1138,7 @@ async function copyPdfCjkFontAssets(from, to) {
1097
1138
  async function copyKnownRendererAssets(targetRoot, rendererIds) {
1098
1139
  const selected = new Set(rendererIds);
1099
1140
  const results = [];
1100
- const push = async (rendererId, id, to, copyAction, reason) => {
1141
+ const push = async (rendererId, id, to, copyAction, reason, source) => {
1101
1142
  if (!selected.has(rendererId)) {
1102
1143
  return;
1103
1144
  }
@@ -1107,14 +1148,19 @@ async function copyKnownRendererAssets(targetRoot, rendererIds) {
1107
1148
  id,
1108
1149
  to,
1109
1150
  copied,
1110
- reason: copied ? undefined : reason || 'source asset not found'
1151
+ reason: copied ? undefined : reason || 'source asset not found',
1152
+ ...source,
1111
1153
  });
1112
1154
  };
1113
1155
  const pdfRoot = resolvePackageRoot('pdfjs-dist', ['@file-viewer/renderer-pdf']);
1114
- await push('pdf', 'pdf-worker', join(targetRoot, 'vendor/pdf/pdf.worker.mjs'), () => copyFileIfPresent(pdfRoot ? join(pdfRoot, 'legacy/build/pdf.worker.mjs') : null, join(targetRoot, 'vendor/pdf/pdf.worker.mjs')));
1115
- await push('pdf', 'pdf-cmaps', join(targetRoot, 'vendor/pdf/cmaps'), () => copyDirectoryIfPresent(pdfRoot ? join(pdfRoot, 'cmaps') : null, join(targetRoot, 'vendor/pdf/cmaps')));
1116
- await push('pdf', 'pdf-wasm', join(targetRoot, 'vendor/pdf/wasm'), () => copyDirectoryIfPresent(pdfRoot ? join(pdfRoot, 'wasm') : null, join(targetRoot, 'vendor/pdf/wasm')));
1117
- await push('pdf', 'pdf-standard-fonts', join(targetRoot, 'vendor/pdf/standard_fonts'), () => copyDirectoryIfPresent(pdfRoot ? join(pdfRoot, 'standard_fonts') : null, join(targetRoot, 'vendor/pdf/standard_fonts')));
1156
+ const pdfVersion = assertOwnedPackageVersion('pdfjs-dist', pdfRoot, '@file-viewer/renderer-pdf');
1157
+ const pdfSource = pdfRoot
1158
+ ? { sourcePackage: 'pdfjs-dist', sourceVersion: pdfVersion || undefined }
1159
+ : undefined;
1160
+ await push('pdf', 'pdf-worker', join(targetRoot, 'vendor/pdf/pdf.worker.mjs'), () => copyFileIfPresent(pdfRoot ? join(pdfRoot, 'legacy/build/pdf.worker.mjs') : null, join(targetRoot, 'vendor/pdf/pdf.worker.mjs')), undefined, pdfSource);
1161
+ await push('pdf', 'pdf-cmaps', join(targetRoot, 'vendor/pdf/cmaps'), () => copyDirectoryIfPresent(pdfRoot ? join(pdfRoot, 'cmaps') : null, join(targetRoot, 'vendor/pdf/cmaps')), undefined, pdfSource);
1162
+ await push('pdf', 'pdf-wasm', join(targetRoot, 'vendor/pdf/wasm'), () => copyDirectoryIfPresent(pdfRoot ? join(pdfRoot, 'wasm') : null, join(targetRoot, 'vendor/pdf/wasm')), undefined, pdfSource);
1163
+ await push('pdf', 'pdf-standard-fonts', join(targetRoot, 'vendor/pdf/standard_fonts'), () => copyDirectoryIfPresent(pdfRoot ? join(pdfRoot, 'standard_fonts') : null, join(targetRoot, 'vendor/pdf/standard_fonts')), undefined, pdfSource);
1118
1164
  const pdfCjkFontRoot = resolvePackageRoot('@fontsource-variable/noto-sans-sc', [
1119
1165
  '@file-viewer/renderer-pdf'
1120
1166
  ]);
@@ -1153,9 +1199,9 @@ async function copyKnownRendererAssets(targetRoot, rendererIds) {
1153
1199
  }, null, 2)}\n`);
1154
1200
  return results;
1155
1201
  }
1156
- function resolveTargetDir(value, fallback) {
1202
+ function resolveTargetDir(value, fallback, projectRoot) {
1157
1203
  const target = value || fallback;
1158
- return isAbsolute(target) ? target : resolve(process.cwd(), target);
1204
+ return isAbsolute(target) ? target : resolve(projectRoot || process.cwd(), target);
1159
1205
  }
1160
1206
  function copyOptions(value) {
1161
1207
  return typeof value === 'object' ? value : {};
@@ -1290,13 +1336,66 @@ export function fileViewerRenderers(options = {}) {
1290
1336
  }
1291
1337
  }
1292
1338
  },
1293
- async configureServer() {
1339
+ async configureServer(server) {
1294
1340
  if (!options.copyAssets || copyOptions(options.copyAssets).mode === 'build') {
1295
1341
  return;
1296
1342
  }
1297
- const targetRoot = resolveTargetDir(copyOptions(options.copyAssets).publicDir, resolvedConfig?.publicDir || 'public');
1343
+ const targetRoot = resolveTargetDir(copyOptions(options.copyAssets).publicDir, resolvedConfig?.publicDir || 'public', resolvedConfig?.root);
1298
1344
  const results = await copyKnownRendererAssets(targetRoot, collectAssetRendererIds(selection, autoPresetIds));
1299
1345
  reportAssetCopy(results, targetRoot, missingMode);
1346
+ const base = resolvedConfig?.base || '/';
1347
+ if (base.startsWith('/') && base !== '/') {
1348
+ const normalizedBase = base.endsWith('/') ? base : `${base}/`;
1349
+ server.middlewares.use(async (request, response, next) => {
1350
+ const requestUrl = request.url || '';
1351
+ const queryIndex = requestUrl.indexOf('?');
1352
+ const pathname = queryIndex >= 0 ? requestUrl.slice(0, queryIndex) : requestUrl;
1353
+ if (pathname.startsWith(normalizedBase)) {
1354
+ let relativePath = pathname.slice(normalizedBase.length);
1355
+ try {
1356
+ relativePath = decodeURIComponent(relativePath);
1357
+ }
1358
+ catch {
1359
+ next();
1360
+ return;
1361
+ }
1362
+ if (relativePath.startsWith('vendor/') || relativePath.startsWith('wasm/')) {
1363
+ const assetPath = resolve(targetRoot, relativePath);
1364
+ if (assetPath.startsWith(`${targetRoot}${sep}`)) {
1365
+ try {
1366
+ const info = await stat(assetPath);
1367
+ if (info.isFile()) {
1368
+ const contentTypes = {
1369
+ '.bcmap': 'application/octet-stream',
1370
+ '.css': 'text/css; charset=utf-8',
1371
+ '.js': 'text/javascript; charset=utf-8',
1372
+ '.json': 'application/json; charset=utf-8',
1373
+ '.mjs': 'text/javascript; charset=utf-8',
1374
+ '.ttf': 'font/ttf',
1375
+ '.wasm': 'application/wasm',
1376
+ '.woff': 'font/woff',
1377
+ '.woff2': 'font/woff2'
1378
+ };
1379
+ response.statusCode = 200;
1380
+ response.setHeader('Content-Type', contentTypes[extname(assetPath).toLowerCase()] || 'application/octet-stream');
1381
+ if (request.method === 'HEAD') {
1382
+ response.end();
1383
+ }
1384
+ else {
1385
+ response.end(await readFile(assetPath));
1386
+ }
1387
+ return;
1388
+ }
1389
+ }
1390
+ catch {
1391
+ // Let Vite return its normal 404/fallback response.
1392
+ }
1393
+ }
1394
+ }
1395
+ }
1396
+ next();
1397
+ });
1398
+ }
1300
1399
  },
1301
1400
  transformIndexHtml: {
1302
1401
  order: 'pre',
@@ -1341,7 +1440,7 @@ export function fileViewerRenderers(options = {}) {
1341
1440
  return;
1342
1441
  }
1343
1442
  const outDir = resolvedConfig?.build.outDir || 'dist';
1344
- const targetRoot = resolveTargetDir(copyOptions(options.copyAssets).outDir, outDir);
1443
+ const targetRoot = resolveTargetDir(copyOptions(options.copyAssets).outDir, outDir, resolvedConfig?.root);
1345
1444
  const results = await copyKnownRendererAssets(targetRoot, collectAssetRendererIds(selection, autoPresetIds));
1346
1445
  reportAssetCopy(results, targetRoot, missingMode);
1347
1446
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/vite-plugin",
3
- "version": "2.1.28",
3
+ "version": "2.1.29",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Vite plugin for Flyfish File Viewer on-demand renderer assembly, chunk planning, and offline asset deployment.",