From 148bd27fd3d9e0c26daceeddfde4249ac5e10930 Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Tue, 31 Mar 2026 08:19:48 -0700 Subject: [PATCH] sdk: switch off axios to @scrypted/auth-fetch --- sdk/bin/index.js | 170 ----------------- sdk/bin/scrypted-changelog.js | 58 ------ sdk/bin/scrypted-debug.js | 22 --- sdk/bin/scrypted-deploy-debug.js | 23 --- sdk/bin/scrypted-deploy.js | 20 -- sdk/bin/scrypted-package-json.js | 19 -- sdk/bin/scrypted-setup-project.js | 6 - sdk/bin/scrypted-webpack.js | 243 ------------------------ sdk/package-lock.json | 294 +++++++----------------------- sdk/package.json | 19 +- sdk/src/bin/index.ts | 185 ++++++++----------- 11 files changed, 158 insertions(+), 901 deletions(-) delete mode 100644 sdk/bin/index.js delete mode 100755 sdk/bin/scrypted-changelog.js delete mode 100755 sdk/bin/scrypted-debug.js delete mode 100755 sdk/bin/scrypted-deploy-debug.js delete mode 100755 sdk/bin/scrypted-deploy.js delete mode 100755 sdk/bin/scrypted-package-json.js delete mode 100755 sdk/bin/scrypted-setup-project.js delete mode 100755 sdk/bin/scrypted-webpack.js diff --git a/sdk/bin/index.js b/sdk/bin/index.js deleted file mode 100644 index 3eebceed7..000000000 --- a/sdk/bin/index.js +++ /dev/null @@ -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}`)); -} diff --git a/sdk/bin/scrypted-changelog.js b/sdk/bin/scrypted-changelog.js deleted file mode 100755 index 71f35c630..000000000 --- a/sdk/bin/scrypted-changelog.js +++ /dev/null @@ -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 = '
\nChangelog\n\n'; - for (const [version, log] of versions.entries()) { - changeLog += `### ${version}\n\n${log}\n\n`; - } - - changeLog += '
\n'; - - fs.writeFileSync('CHANGELOG.md', changeLog); -}); diff --git a/sdk/bin/scrypted-debug.js b/sdk/bin/scrypted-debug.js deleted file mode 100755 index aa32c98a3..000000000 --- a/sdk/bin/scrypted-debug.js +++ /dev/null @@ -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 [main.js]'); - return 1; -} - -scrypted.debug(process.argv[2], process.argv[3]) -.catch((err) => { - console.error(err.message); - report('debug failed'); -}); diff --git a/sdk/bin/scrypted-deploy-debug.js b/sdk/bin/scrypted-deploy-debug.js deleted file mode 100755 index 9db934dcb..000000000 --- a/sdk/bin/scrypted-deploy-debug.js +++ /dev/null @@ -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 [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'); -}); diff --git a/sdk/bin/scrypted-deploy.js b/sdk/bin/scrypted-deploy.js deleted file mode 100755 index 8917c420f..000000000 --- a/sdk/bin/scrypted-deploy.js +++ /dev/null @@ -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 '); - return 1; -} - -scrypted.deploy(process.argv[2]) -.catch((err) => { - console.error(err.message); - report('deploy failed'); -}); diff --git a/sdk/bin/scrypted-package-json.js b/sdk/bin/scrypted-package-json.js deleted file mode 100755 index 5d21c6656..000000000 --- a/sdk/bin/scrypted-package-json.js +++ /dev/null @@ -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'); diff --git a/sdk/bin/scrypted-setup-project.js b/sdk/bin/scrypted-setup-project.js deleted file mode 100755 index c690396f0..000000000 --- a/sdk/bin/scrypted-setup-project.js +++ /dev/null @@ -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'); diff --git a/sdk/bin/scrypted-webpack.js b/sdk/bin/scrypted-webpack.js deleted file mode 100755 index 168d384c1..000000000 --- a/sdk/bin/scrypted-webpack.js +++ /dev/null @@ -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

' + 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); - })); \ No newline at end of file diff --git a/sdk/package-lock.json b/sdk/package-lock.json index 79cadca96..7fee31567 100644 --- a/sdk/package-lock.json +++ b/sdk/package-lock.json @@ -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", diff --git a/sdk/package.json b/sdk/package.json index 50f895887..50d126f94 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -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" }, diff --git a/sdk/src/bin/index.ts b/sdk/src/bin/index.ts index 1ea436b75..cb8a22daa 100644 --- a/sdk/src/bin/index.ts +++ b/sdk/src/bin/index.ts @@ -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 { +export async function deploy(debugHost: string, noRebind?: boolean): Promise { 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 { +export async function debug(debugHost: string, entryPoint?: string): Promise { 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 {