Files
juzi/h5/lib/entry-config.js
T

34 lines
1.7 KiB
JavaScript

'use strict';
const path = require('node:path');
const fs = require('node:fs');
function physical(file) {
if (fs.existsSync(file)) return fs.realpathSync(file);
const parent = path.dirname(file);
return parent === file ? file : path.join(physical(parent), path.basename(file));
}
function inside(file, parent) {
if (process.platform === 'win32') { file = file.toLowerCase(); parent = parent.toLowerCase(); }
return file === parent || file.startsWith(parent + path.sep);
}
// One immutable entry mode per process. Never infer a channel from client input.
module.exports = function entryConfig(env, root) {
const mode = env.JUZI_ENTRY_MODE || 'state';
if (!['state', 'rednote'].includes(mode)) throw Error('Unsupported JUZI_ENTRY_MODE');
const rednote = mode === 'rednote';
const dataRoot = env.JUZI_DATA_ROOT ? path.resolve(env.JUZI_DATA_ROOT) : path.join(root, 'data');
if (rednote) {
const protectedRoots = [root, env.JUZI_PROTECTED_DATA_ROOT].filter(Boolean).map(p => physical(path.resolve(p)));
if (!env.JUZI_DATA_ROOT || protectedRoots.some(p => inside(physical(dataRoot), p))) {
throw Error('Rednote requires its own JUZI_DATA_ROOT outside the shared h5 directory and protected data');
}
const base = new URL(env.PUBLIC_BASE_URL || '');
if (!['http:', 'https:'].includes(base.protocol) || base.pathname !== '/rednote/' || base.search || base.hash || base.username || base.password ||
(env.NODE_ENV === 'production' && base.protocol !== 'https:')) {
throw Error('Rednote PUBLIC_BASE_URL must end with /rednote/');
}
}
return { mode, rednote, dataRoot, channel: rednote ? 'rednote' : 'h5',
client: { mode, persistentBrowser: rednote } };
};