sdk: switch off axios to @scrypted/auth-fetch

This commit is contained in:
Koushik Dutta
2026-03-31 08:19:48 -07:00
parent b634330ab0
commit 148bd27fd3
11 changed files with 158 additions and 901 deletions

View File

@@ -1,170 +0,0 @@
const https = require('https');
const axios = require('axios').create({
httpsAgent: new https.Agent({
rejectUnauthorized: false
})
});
const process = require('process');
const path = require('path');
const fs = require('fs');
function getUserHome() {
const ret = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
if (!ret)
throw new Error('Neither USERPROFILE or HOME are defined.');
return ret;
}
const scryptedHome = path.join(getUserHome(), '.scrypted');
const loginPath = path.join(scryptedHome, 'login.json');
function getLogin(ip) {
let login;
try {
login = JSON.parse(fs.readFileSync(loginPath).toString());
}
catch (e) {
login = {};
}
login = login[ip];
const ret = {
username: login.username,
password: login.token,
};
return ret;
}
function showLoginError() {
console.error('Authorization required. Please log in with the following:');
console.error(' npx scrypted login [ip]');
}
function toIpAndPort(ip) {
if (ip.indexOf(':') === -1)
ip += ':10443'
console.log(ip);
return ip;
}
exports.deploy = function (debugHost, noRebind) {
debugHost = toIpAndPort(debugHost);
return new Promise((resolve, reject) => {
var out;
if (process.env.NODE_ENV === 'production')
out = path.resolve(process.cwd(), 'dist');
else
out = path.resolve(process.cwd(), 'out');
const outFilename = 'plugin.zip';
const main = path.resolve(out, outFilename);
if (!fs.existsSync(main)) {
console.error('npm run scrypted-webpack to build a webpack bundle for Scrypted.')
reject(new Error(`Missing webpack bundle: ${main}`));
return 3;
}
var packageJson = path.resolve(process.cwd(), 'package.json');
packageJson = JSON.parse(fs.readFileSync(packageJson));
const npmPackage = packageJson.name || '';
var rebindQuery = noRebind ? 'no-rebind' : '';
const deployUrl = `https://${debugHost}/web/component/script/deploy?${rebindQuery}&npmPackage=${npmPackage}`
const setupUrl = `https://${debugHost}/web/component/script/setup?${rebindQuery}&npmPackage=${npmPackage}`
const fileContents = fs.readFileSync(main);
console.log(`deploying to ${debugHost}`);
let auth;
try {
auth = getLogin(debugHost);
}
catch (e) {
console.error(e);
showLoginError();
process.exit(1);
}
axios.post(setupUrl, packageJson,
{
auth,
timeout: 10000,
maxRedirects: 0,
validateStatus: function (status) {
if (status === 401) {
showLoginError();
}
return status >= 200 && status < 300;
},
})
.then(() => {
console.log(`configured ${debugHost}`);
return axios.post(deployUrl, fileContents,
{
auth: getLogin(debugHost),
timeout: 10000,
maxRedirects: 0,
validateStatus: function (status) {
return status >= 200 && status < 300;
},
headers: {
"Content-Type": "application/zip "
}
}
)
})
.then(() => {
console.log(`deployed to ${debugHost}`);
resolve();
})
.catch((err) => {
console.error(err.message);
if (err.response && err.response.data) {
console.log('\x1b[31m%s\x1b[0m', err.response.data);
}
reject(err);
});
});
}
exports.debug = function (debugHost, entryPoint) {
debugHost = toIpAndPort(debugHost);
return new Promise((resolve, reject) => {
var packageJson = path.resolve(process.cwd(), 'package.json');
packageJson = JSON.parse(fs.readFileSync(packageJson));
const npmPackage = packageJson.name || '';
const debugUrl = `https://${debugHost}/web/component/script/debug?npmPackage=${npmPackage}`
console.log(`initiating debugger on ${debugHost}`);
axios.post(debugUrl, undefined, {
auth: getLogin(debugHost),
timeout: 10000,
maxRedirects: 0,
validateStatus: function (status) {
return status >= 200 && status < 300; // default
},
})
.then(response => {
console.log(`debugger ready on ${debugHost}`);
resolve();
})
.catch((err) => {
console.error(err.message);
if (err.response && err.response.data) {
console.log('\x1b[31m%s\x1b[0m', err.response.data);
}
reject(err);
});
})
}
exports.getDefaultWebpackConfig = function (name) {
return require(path.resolve(__dirname, `../${name}`));
}

View File

@@ -1,58 +0,0 @@
#! /usr/bin/env node
const child_process = require('child_process');
const util = require('util');
const fs = require('fs');
const shas = child_process.execSync('git log --format=format:%H .');
const exec = util.promisify(child_process.exec);
const versions = new Map();
const promises = shas.toString().split('\n').map(sha => sha.trim()).map(async sha => {
// console.log(sha);
try {
const result = await exec(`git show ${sha}:./package.json`);
const packageJson = JSON.parse(result.stdout);
const commit = await exec(`git rev-list --format=%B --max-count=1 ${sha}`);
return {
packageJson,
commit: commit.stdout,
};
}
catch (e) {
console.error(e);
}
});
Promise.all(promises).then(pairs => {
// console.log(pairs);
const validPairs = pairs.filter(pair => pair?.packageJson?.version);
for (const valid of validPairs) {
const { packageJson, commit } = valid;
const { version } = packageJson;
let log = versions.get(version) || '';
const firstLine = commit.split('\n')[1];
// filter out some junk commits
if ([version, 'wip', 'logging', 'wiop', 'publish'].includes(firstLine))
continue;
if (!log) {
log = '';
versions.set(version, log);
}
log += `${firstLine}\n`;
versions.set(version, log);
}
let changeLog = '<details>\n<summary>Changelog</summary>\n\n';
for (const [version, log] of versions.entries()) {
changeLog += `### ${version}\n\n${log}\n\n`;
}
changeLog += '</details>\n';
fs.writeFileSync('CHANGELOG.md', changeLog);
});

View File

@@ -1,22 +0,0 @@
#! /usr/bin/env node
const scrypted = require('./index.js');
function report(err) {
process.nextTick(() => {
throw new Error(err);
});
}
if (process.argv.length != 3) {
// the vscode deploy+debug task will provide the main.js and connection string.
// newer plugins will have that set to main.quickjs.js.
// this will
report('Usage: npm run scrypted-debug <ip_address> [main.js]');
return 1;
}
scrypted.debug(process.argv[2], process.argv[3])
.catch((err) => {
console.error(err.message);
report('debug failed');
});

View File

@@ -1,23 +0,0 @@
#! /usr/bin/env node
const scrypted = require('./index.js');
function report(err) {
process.nextTick(() => {
throw new Error(err);
});
}
if (process.argv.length < 3) {
report('Usage: npm run scrypted-deploy-debug <ip_address> [main.js]');
return 1;
}
scrypted.deploy(process.argv[2], true)
.then(() => {
return scrypted.debug(process.argv[2], process.argv[3]);
})
.catch((err) => {
console.error(err.message);
report('deploy + debug failed');
});

View File

@@ -1,20 +0,0 @@
#! /usr/bin/env node
const scrypted = require('./index.js');
function report(err) {
process.nextTick(() => {
throw new Error(err);
});
}
if (process.argv.length != 3) {
report('Usage: npm run scrypted-deploy <ip_address>');
return 1;
}
scrypted.deploy(process.argv[2])
.catch((err) => {
console.error(err.message);
report('deploy failed');
});

View File

@@ -1,19 +0,0 @@
#! /usr/bin/env node
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json'));
pkg.scripts = Object.assign({
"scrypted-setup-project": "scrypted-setup-project",
"prescrypted-setup-project": "scrypted-package-json",
"build": "scrypted-webpack",
"preprepublishOnly": "scrypted-changelog",
"prepublishOnly": "NODE_ENV=production scrypted-webpack",
"prescrypted-vscode-launch": "scrypted-webpack",
"scrypted-vscode-launch": "scrypted-deploy-debug",
"scrypted-deploy-debug": "scrypted-deploy-debug",
"scrypted-debug": "scrypted-debug",
"scrypted-deploy": "scrypted-deploy",
"scrypted-changelog": "scrypted-changelog",
"scrypted-package-json": "scrypted-package-json",
}, pkg.scripts);
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 3) + '\n');

View File

@@ -1,6 +0,0 @@
#! /usr/bin/env node
const ncp = require('ncp');
const path = require('path');
ncp(path.join(__dirname, '../tsconfig.plugin.json'), 'tsconfig.json');

View File

@@ -1,243 +0,0 @@
#! /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');
const child_process = require('child_process');
const { once } = require('events');
let out;
if (process.env.NODE_ENV === 'production')
out = path.resolve(cwd, 'dist');
else
out = path.resolve(cwd, 'out');
if (fs.existsSync(path.resolve(cwd, 'src/main.py'))) {
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'));
return;
}
const packageJson = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json').toString()));
const interfaceDescriptors = packageJson.scrypted?.interfaceDescriptors;
delete packageJson.scrypted?.interfaceDescriptors;
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';
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);
}
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 rollup() {
if (out)
rimraf.sync(out);
let rollupCmd = path.resolve(cwd, 'node_modules/.bin/rollup');
if (!fs.existsSync(rollupCmd)) {
rollupCmd = path.resolve(cwd, 'node_modules/@scrypted/sdk/node_modules/.bin/rollup')
}
if (os.platform().startsWith('win')) {
rollupCmd += '.cmd';
}
const cp = child_process.spawn(rollupCmd, [
'--config', path.resolve(__dirname, '../rollup.nodejs.config.mjs'),
], {
stdio: 'inherit',
});
await once(cp, 'exit');
if (cp.exitCode)
throw new Error('rollup failed');
finishZip();
}
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();
})
});
finishZip();
}
function finishZip() {
// 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 sdkVersion = require(path.join(__dirname, '../package.json')).version;
zip.addFile('sdk.json', Buffer.from(JSON.stringify({
version: sdkVersion,
interfaceDescriptors,
})));
if (packageJson.type === 'module') {
zip.addFile('package.json', Buffer.from(JSON.stringify({
type: 'module'
})));
}
const zipfs = path.join(cwd, 'fs');
if (fs.existsSync(zipfs))
zip.addLocalFolder(zipfs, 'fs');
zip.writeZip(path.join(out, 'plugin.zip'));
}
(packageJson.scrypted.rollup ? rollup : pack)()
.catch(e => process.nextTick(() => {
console.error(e);
throw new Error(e);
}));

294
sdk/package-lock.json generated
View File

@@ -16,8 +16,8 @@
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.3.0",
"@rollup/plugin-virtual": "^3.0.2",
"@scrypted/auth-fetch": "^1.0.3",
"adm-zip": "^0.5.16",
"axios": "^1.10.0",
"babel-loader": "^10.0.0",
"babel-plugin-const-enum": "^1.2.0",
"ncp": "^2.0.0",
@@ -33,16 +33,19 @@
"webpack-bundle-analyzer": "^4.10.2"
},
"bin": {
"scrypted-changelog": "bin/scrypted-changelog.js",
"scrypted-debug": "bin/scrypted-debug.js",
"scrypted-deploy": "bin/scrypted-deploy.js",
"scrypted-deploy-debug": "bin/scrypted-deploy-debug.js",
"scrypted-package-json": "bin/scrypted-package-json.js",
"scrypted-setup-project": "bin/scrypted-setup-project.js",
"scrypted-webpack": "bin/scrypted-webpack.js"
"scrypted-changelog": "dist/src/bin/scrypted-changelog.js",
"scrypted-debug": "dist/src/bin/scrypted-debug.js",
"scrypted-deploy": "dist/src/bin/scrypted-deploy.js",
"scrypted-deploy-debug": "dist/src/bin/scrypted-deploy-debug.js",
"scrypted-package-json": "dist/src/bin/scrypted-package-json.js",
"scrypted-setup-project": "dist/src/bin/scrypted-setup-project.js",
"scrypted-webpack": "dist/src/bin/scrypted-webpack.js"
},
"devDependencies": {
"@types/adm-zip": "^0.5.8",
"@types/ncp": "^2.0.8",
"@types/node": "^24.9.2",
"@types/tmp": "^0.2.6",
"ts-node": "^10.9.2",
"typedoc": "^0.28.14"
}
@@ -1053,6 +1056,16 @@
"win32"
]
},
"node_modules/@scrypted/auth-fetch": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@scrypted/auth-fetch/-/auth-fetch-1.0.3.tgz",
"integrity": "sha512-0Ffi3Y0IpfiTe2SDJtba+REjqTC48Nq9eEqU+KfoYdFOroZlN34nV676xE7YtOpNMVAy71qVIcSLGPvvz1lD6g==",
"license": "ISC",
"dependencies": {
"follow-redirects": "^1.15.4",
"http-auth-utils": "^5.0.1"
}
},
"node_modules/@shikijs/engine-oniguruma": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.14.0.tgz",
@@ -1130,6 +1143,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/adm-zip": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.5.8.tgz",
"integrity": "sha512-RVVH7QvZYbN+ihqZ4kX/dMiowf6o+Jk1fNwiSdx0NahBJLU787zkULhGhJM8mf/obmLGmgdMM0bXsQTmyfbR7Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/eslint": {
"version": "9.6.1",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
@@ -1172,6 +1195,16 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"license": "MIT"
},
"node_modules/@types/ncp": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/@types/ncp/-/ncp-2.0.8.tgz",
"integrity": "sha512-pLNWVLCVWBLVM4F2OPjjK6FWFtByFKD7LhHryF+MbVLws7ENj09mKxRFlhkGPOXfJuaBAG+2iADKJsZwnAbYDw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "24.9.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz",
@@ -1187,6 +1220,13 @@
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
"license": "MIT"
},
"node_modules/@types/tmp": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.6.tgz",
"integrity": "sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@@ -1490,23 +1530,6 @@
"dev": true,
"license": "Python-2.0"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axios": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/babel-loader": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz",
@@ -1613,19 +1636,6 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"license": "MIT"
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001723",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz",
@@ -1689,18 +1699,6 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -1773,15 +1771,6 @@
"node": ">=0.10.0"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -1792,20 +1781,6 @@
"node": ">=0.3.1"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -1865,57 +1840,12 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-module-lexer": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
"integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
"license": "MIT"
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -2101,22 +2031,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/form-data": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -2150,43 +2064,6 @@
"node": ">=6.9.0"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/glob": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
@@ -2225,18 +2102,6 @@
"node": ">=4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -2267,33 +2132,6 @@
"node": ">=8"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -2312,6 +2150,18 @@
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"license": "MIT"
},
"node_modules/http-auth-utils": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/http-auth-utils/-/http-auth-utils-5.0.1.tgz",
"integrity": "sha512-YPiLVYdwpBEWB85iWYg7V/ZW3mBfPLCTFQWEiPAA5CKXHJOAPbnJ0xDHLiE6KbPRvrYCwLuWqTG0fLfXVjMUcQ==",
"license": "MIT",
"dependencies": {
"yerror": "^8.0.0"
},
"engines": {
"node": ">=18.16.0"
}
},
"node_modules/is-core-module": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
@@ -2551,15 +2401,6 @@
"markdown-it": "bin/markdown-it.mjs"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
@@ -2812,12 +2653,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -3874,6 +3709,15 @@
"node": ">= 14.6"
}
},
"node_modules/yerror": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/yerror/-/yerror-8.0.0.tgz",
"integrity": "sha512-FemWD5/UqNm8ffj8oZIbjWXIF2KE0mZssggYpdaQkWDDgXBQ/35PNIxEuz6/YLn9o0kOxDBNJe8x8k9ljD7k/g==",
"license": "MIT",
"engines": {
"node": ">=18.16.0"
}
},
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",

View File

@@ -18,13 +18,13 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"bin": {
"scrypted-package-json": "bin/scrypted-package-json.js",
"scrypted-changelog": "bin/scrypted-changelog.js",
"scrypted-setup-project": "bin/scrypted-setup-project.js",
"scrypted-webpack": "bin/scrypted-webpack.js",
"scrypted-deploy-debug": "bin/scrypted-deploy-debug.js",
"scrypted-deploy": "bin/scrypted-deploy.js",
"scrypted-debug": "bin/scrypted-debug.js"
"scrypted-package-json": "dist/src/bin/scrypted-package-json.js",
"scrypted-changelog": "dist/src/bin/scrypted-changelog.js",
"scrypted-setup-project": "dist/src/bin/scrypted-setup-project.js",
"scrypted-webpack": "dist/src/bin/scrypted-webpack.js",
"scrypted-deploy-debug": "dist/src/bin/scrypted-deploy-debug.js",
"scrypted-deploy": "dist/src/bin/scrypted-deploy.js",
"scrypted-debug": "dist/src/bin/scrypted-debug.js"
},
"author": "",
"license": "ISC",
@@ -36,8 +36,8 @@
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.3.0",
"@rollup/plugin-virtual": "^3.0.2",
"@scrypted/auth-fetch": "^1.0.3",
"adm-zip": "^0.5.16",
"axios": "^1.10.0",
"babel-loader": "^10.0.0",
"babel-plugin-const-enum": "^1.2.0",
"ncp": "^2.0.0",
@@ -53,7 +53,10 @@
"webpack-bundle-analyzer": "^4.10.2"
},
"devDependencies": {
"@types/adm-zip": "^0.5.8",
"@types/ncp": "^2.0.8",
"@types/node": "^24.9.2",
"@types/tmp": "^0.2.6",
"ts-node": "^10.9.2",
"typedoc": "^0.28.14"
},

View File

@@ -1,5 +1,4 @@
import https from 'https';
import axios from 'axios';
import { authFetch } from '@scrypted/auth-fetch';
import process from 'process';
import path from 'path';
import fs from 'fs';
@@ -52,131 +51,103 @@ function toIpAndPort(ip: string): string {
return ip;
}
export function deploy(debugHost: string, noRebind?: boolean): Promise<void> {
export async function deploy(debugHost: string, noRebind?: boolean): Promise<void> {
debugHost = toIpAndPort(debugHost);
return new Promise((resolve, reject) => {
let out: string;
if (process.env.NODE_ENV === 'production')
out = path.resolve(process.cwd(), 'dist');
else
out = path.resolve(process.cwd(), 'out');
let out: string;
if (process.env.NODE_ENV === 'production')
out = path.resolve(process.cwd(), 'dist');
else
out = path.resolve(process.cwd(), 'out');
const outFilename = 'plugin.zip';
const main = path.resolve(out, outFilename);
if (!fs.existsSync(main)) {
console.error('npm run scrypted-webpack to build a webpack bundle for Scrypted.');
reject(new Error(`Missing webpack bundle: ${main}`));
return;
}
const outFilename = 'plugin.zip';
const main = path.resolve(out, outFilename);
if (!fs.existsSync(main)) {
console.error('npm run scrypted-webpack to build a webpack bundle for Scrypted.');
throw new Error(`Missing webpack bundle: ${main}`);
}
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString());
const npmPackage = packageJson.name || '';
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString());
const npmPackage = packageJson.name || '';
const rebindQuery = noRebind ? 'no-rebind' : '';
const rebindQuery = noRebind ? 'no-rebind' : '';
const deployUrl = `https://${debugHost}/web/component/script/deploy?${rebindQuery}&npmPackage=${npmPackage}`;
const setupUrl = `https://${debugHost}/web/component/script/setup?${rebindQuery}&npmPackage=${npmPackage}`;
const deployUrl = `https://${debugHost}/web/component/script/deploy?${rebindQuery}&npmPackage=${npmPackage}`;
const setupUrl = `https://${debugHost}/web/component/script/setup?${rebindQuery}&npmPackage=${npmPackage}`;
const fileContents = fs.readFileSync(main);
console.log(`deploying to ${debugHost}`);
const fileContents = fs.readFileSync(main);
console.log(`deploying to ${debugHost}`);
let auth: { username: string; password: string };
try {
auth = getLogin(debugHost);
}
catch (e) {
console.error(e);
showLoginError();
process.exit(1);
}
const auth = getLogin(debugHost);
const httpsAgent = new https.Agent({
rejectUnauthorized: false
try {
await authFetch({
url: setupUrl,
method: 'POST',
body: packageJson,
credential: auth,
timeout: 10000,
rejectUnauthorized: false,
checkStatusCode(statusCode) {
if (statusCode === 401) {
showLoginError();
}
return statusCode >= 200 && statusCode < 300;
},
});
axios.post(setupUrl, packageJson,
{
auth,
timeout: 10000,
maxRedirects: 0,
httpsAgent,
validateStatus: function (status: number) {
if (status === 401) {
showLoginError();
}
return status >= 200 && status < 300;
},
})
.then(() => {
console.log(`configured ${debugHost}`);
console.log(`configured ${debugHost}`);
return axios.post(deployUrl, fileContents,
{
auth: getLogin(debugHost),
timeout: 10000,
maxRedirects: 0,
httpsAgent,
validateStatus: function (status: number) {
return status >= 200 && status < 300;
},
headers: {
"Content-Type": "application/zip "
}
}
);
})
.then(() => {
console.log(`deployed to ${debugHost}`);
resolve();
})
.catch((err: Error) => {
console.error(err.message);
if (axios.isAxiosError(err) && err.response?.data) {
console.log('\x1b[31m%s\x1b[0m', err.response.data);
}
reject(err);
});
});
await authFetch({
url: deployUrl,
method: 'POST',
body: fileContents,
credential: auth,
timeout: 10000,
rejectUnauthorized: false,
headers: {
'Content-Type': 'application/zip',
},
});
console.log(`deployed to ${debugHost}`);
}
catch (err) {
const error = err as Error;
console.error(error.message);
throw error;
}
}
export function debug(debugHost: string, entryPoint?: string): Promise<void> {
export async function debug(debugHost: string, entryPoint?: string): Promise<void> {
debugHost = toIpAndPort(debugHost);
return new Promise((resolve, reject) => {
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString());
const npmPackage = packageJson.name || '';
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString());
const npmPackage = packageJson.name || '';
const debugUrl = `https://${debugHost}/web/component/script/debug?npmPackage=${npmPackage}`;
console.log(`initiating debugger on ${debugHost}`);
const debugUrl = `https://${debugHost}/web/component/script/debug?npmPackage=${npmPackage}`;
console.log(`initiating debugger on ${debugHost}`);
const httpsAgent = new https.Agent({
rejectUnauthorized: false
const auth = getLogin(debugHost);
try {
await authFetch({
url: debugUrl,
method: 'POST',
credential: auth,
timeout: 10000,
rejectUnauthorized: false,
});
axios.post(debugUrl, undefined, {
auth: getLogin(debugHost),
timeout: 10000,
maxRedirects: 0,
httpsAgent,
validateStatus: function (status: number) {
return status >= 200 && status < 300;
},
})
.then(() => {
console.log(`debugger ready on ${debugHost}`);
resolve();
})
.catch((err: Error) => {
console.error(err.message);
if (axios.isAxiosError(err) && err.response?.data) {
console.log('\x1b[31m%s\x1b[0m', err.response.data);
}
reject(err);
});
});
console.log(`debugger ready on ${debugHost}`);
}
catch (err) {
const error = err as Error;
console.error(error.message);
throw error;
}
}
export function getDefaultWebpackConfig(name: string): unknown {