mirror of
https://github.com/koush/scrypted.git
synced 2026-02-16 19:52:15 +00:00
210 lines
6.8 KiB
JavaScript
Executable File
210 lines
6.8 KiB
JavaScript
Executable File
#! /usr/bin/env node
|
|
try {
|
|
require('adm-zip');
|
|
}
|
|
catch (e) {
|
|
throw new Error('Please "npm install" in the "sdk" directory.');
|
|
|
|
}
|
|
const path = require('path');
|
|
const process = require('process');
|
|
const fs = require('fs');
|
|
const cwd = process.cwd();
|
|
const AdmZip = require('adm-zip');
|
|
const os = require('os');
|
|
const rimraf = require('rimraf');
|
|
const webpack = require('webpack');
|
|
const tmp = require('tmp');
|
|
|
|
if (fs.existsSync(path.resolve(cwd, 'src/main.py'))) {
|
|
let out;
|
|
if (process.env.NODE_ENV == 'production')
|
|
out = path.resolve(cwd, 'dist');
|
|
else
|
|
out = path.resolve(cwd, 'out');
|
|
|
|
const resolved = path.resolve(cwd, 'src');
|
|
|
|
const zip = new AdmZip();
|
|
const readme = path.join(cwd, 'README.md');
|
|
if (fs.existsSync(readme)) {
|
|
zip.addLocalFile(readme);
|
|
}
|
|
|
|
zip.addLocalFolder(resolved);
|
|
|
|
const sdk = path.join(__dirname, '../types/scrypted_python/scrypted_sdk');
|
|
zip.addLocalFolder(sdk, 'scrypted_sdk', filename => !filename.endsWith('.pyc'));
|
|
|
|
const zipfs = path.join(cwd, 'fs');
|
|
if (fs.existsSync(zipfs))
|
|
zip.addLocalFolder(zipfs, 'fs');
|
|
zip.writeZip(path.join(out, 'plugin.zip'));
|
|
}
|
|
else {
|
|
const packageJson = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json').toString()));
|
|
const optionalDependencies = Object.keys(packageJson.optionalDependencies || {});
|
|
|
|
if (packageJson.scrypted.babel) {
|
|
process.env.SCRYPTED_WEBPACK_BABEL = 'true';
|
|
}
|
|
|
|
const defaultMainNodeJs = 'main.nodejs.js';
|
|
const entries = [];
|
|
if (packageJson.exports) {
|
|
for (const [key, value] of Object.entries(packageJson.exports)) {
|
|
entries.push({
|
|
filename: key,
|
|
output: value,
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
for (const search of ['src/main.js', 'src/main.ts']) {
|
|
const resolved = path.resolve(cwd, search);
|
|
if (fs.existsSync(resolved)) {
|
|
entries.push({
|
|
filename: search,
|
|
output: defaultMainNodeJs,
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
const nodeWebpackConfig = 'webpack.nodejs.config.js';
|
|
|
|
let out;
|
|
if (process.env.NODE_ENV == 'production')
|
|
out = path.resolve(cwd, 'dist');
|
|
else
|
|
out = path.resolve(cwd, 'out');
|
|
|
|
if (!entries?.length) {
|
|
console.warn('unable to locate src/main.js or src/main.ts');
|
|
console.warn('if a custom webpack config is used, will fall back to an entry configured there');
|
|
entries.push(undefined);
|
|
}
|
|
|
|
let webpackCmd = path.resolve(cwd, 'node_modules/.bin/webpack-cli');
|
|
if (!fs.existsSync(webpackCmd)) {
|
|
webpackCmd = path.resolve(cwd, 'node_modules/@scrypted/sdk/node_modules/.bin/webpack-cli')
|
|
}
|
|
if (os.platform().startsWith('win')) {
|
|
webpackCmd += '.cmd';
|
|
}
|
|
const zip = new AdmZip();
|
|
|
|
const readme = path.join(cwd, 'README.md');
|
|
if (fs.existsSync(readme)) {
|
|
let readmeText = fs.readFileSync(readme).toString();;
|
|
const changelog = path.join(cwd, 'CHANGELOG.md');
|
|
if (fs.existsSync(changelog)) {
|
|
readmeText += '\n\n\n<br/><br/>' + fs.readFileSync(changelog).toString();
|
|
}
|
|
zip.addFile('README.md', Buffer.from(readmeText));
|
|
}
|
|
|
|
const NODE_PATH = path.resolve(__dirname, '..', 'node_modules');
|
|
|
|
// hack to override NODE_PATH dynamically.
|
|
// otherwise webpack plugins are not found.
|
|
process.env.NODE_PATH = NODE_PATH;
|
|
require('module').Module._initPaths();
|
|
|
|
async function pack() {
|
|
if (out)
|
|
rimraf.sync(out);
|
|
|
|
await new Promise((resolve, reject) => {
|
|
let webpackConfig;
|
|
const customWebpackConfig = path.resolve(cwd, nodeWebpackConfig);
|
|
const defaultWebpackConfig = path.resolve(__dirname, '..', nodeWebpackConfig);
|
|
if (fs.existsSync(customWebpackConfig)) {
|
|
webpackConfig = customWebpackConfig;
|
|
}
|
|
else {
|
|
webpackConfig = defaultWebpackConfig;
|
|
}
|
|
|
|
process.env.SCRYPTED_DEFAULT_WEBPACK_CONFIG = defaultWebpackConfig;
|
|
|
|
const webpackEntries = {};
|
|
const config = require(webpackConfig);
|
|
for (let entry of entries) {
|
|
entry ||= {
|
|
filename: config?.entry?.main,
|
|
output: defaultMainNodeJs,
|
|
};
|
|
|
|
if (!entry?.filename) {
|
|
console.error("no main.ts or main.js was found, and webpack config does not supply an entry file.");
|
|
console.error(entry?.filename);
|
|
throw new Error();
|
|
}
|
|
|
|
const main = path.resolve(cwd, entry.filename);
|
|
if (!fs.existsSync(main)) {
|
|
console.error("entry file specified in webpack config does not exist");
|
|
throw new Error();
|
|
}
|
|
|
|
|
|
webpackEntries[entry?.output] = main;
|
|
}
|
|
|
|
|
|
config.entry = webpackEntries;
|
|
config.output.filename = '[name]';
|
|
config.output.path = out;
|
|
for (const opt of optionalDependencies) {
|
|
const t = tmp.tmpNameSync({
|
|
postfix: '.js',
|
|
});
|
|
fs.writeFileSync(t, `
|
|
const e = __non_webpack_require__('${opt}');
|
|
module.exports = e;
|
|
`);
|
|
config.resolve.alias[opt] = t;
|
|
}
|
|
|
|
webpack(config, (err, stats) => {
|
|
if (err)
|
|
return reject(err);
|
|
|
|
if (stats.hasErrors()) {
|
|
console.error(stats.toJson().errors);
|
|
return reject(new Error('webpack failed'));
|
|
}
|
|
|
|
resolve();
|
|
})
|
|
});
|
|
|
|
// create a zip that has a main.nodejs.js in the root, and an fs folder containing a read only virtual file system.
|
|
// todo: read write file system? seems like a potential sandbox and backup nightmare to do a real fs. scripts should
|
|
// use localStorage, etc?
|
|
const jsFiles = fs.readdirSync(out, {
|
|
withFileTypes: true
|
|
}).filter(ft => ft.isFile() && ft.name.endsWith('.js')).map(ft => ft.name);
|
|
for (const js of jsFiles) {
|
|
zip.addLocalFile(path.join(out, js));
|
|
const sourcemap = path.join(out, js + '.map');
|
|
if (fs.existsSync(sourcemap))
|
|
zip.addLocalFile(sourcemap);
|
|
console.log(js);
|
|
}
|
|
|
|
const zipfs = path.join(cwd, 'fs');
|
|
if (fs.existsSync(zipfs))
|
|
zip.addLocalFolder(zipfs, 'fs');
|
|
zip.writeZip(path.join(out, 'plugin.zip'));
|
|
}
|
|
|
|
pack()
|
|
.catch(e => process.nextTick(() => {
|
|
console.error(e);
|
|
throw new Error(e);
|
|
}));
|
|
|
|
} |