diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0223349..5866871 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,19 +11,21 @@ build: stage: build script: - npx tsc + - npx rollup --config + - PACKAGE=`npm --color="always" pack` - mv "$PACKAGE" nxapi.tgz - # - npm run build-macos-linux - # - npm run build-windows - # - mv dist/bin/nxapi . - # - mv dist/bin/nxapi.exe . + - npx electron-builder build --macos --windows --linux + - mv dist/app/package app artifacts: paths: - dist - nxapi.tgz - # - nxapi - # - nxapi.exe + - app + - '!app/mac' + - '!app/win-unpacked' + - '!app/linux-unpacked' publish-npm: stage: deploy diff --git a/package-lock.json b/package-lock.json index 9561e29..cb7755b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "@rollup/plugin-alias": "^3.1.9", "@rollup/plugin-commonjs": "^21.0.3", "@rollup/plugin-html": "^0.2.4", + "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.1.3", "@rollup/plugin-replace": "^4.0.0", "@rollup/plugin-typescript": "^8.3.1", @@ -303,6 +304,18 @@ "rollup": "^1.20.0 || ^2.0.0" } }, + "node_modules/@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.0.8" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, "node_modules/@rollup/plugin-node-resolve": { "version": "13.1.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", @@ -5921,6 +5934,15 @@ "magic-string": "^0.25.7" } }, + "@rollup/plugin-json": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", + "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8" + } + }, "@rollup/plugin-node-resolve": { "version": "13.1.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", diff --git a/package.json b/package.json index 035b38a..afc39e2 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,9 @@ }, "files": [ "dist", + "!dist/app", + "!dist/app-main-bundle.cjs", + "!dist/cli-bundle.js", "bin", "resources" ], @@ -18,12 +21,7 @@ "nxapi": "bin/nxapi.js" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "cli": "node bin/nxapi.js", - "build-macos-linux": "caxa --input . --exclude src dist/bin data node_modules --prepare-command \"npm ci --production\" --output dist/bin/nxapi -- \"{{caxa}}/node_modules/.bin/node\" \"{{caxa}}/bin/nxapi.js\"", - "build-macosapp": "caxa --input . --exclude src dist/bin data node_modules --prepare-command \"npm ci --production\" --output dist/bin/nxapi.app -- \"{{caxa}}/node_modules/.bin/node\" \"{{caxa}}/bin/nxapi.js\" \"presence\"", - "build-windows": "caxa --input . --exclude src dist/bin data node_modules --prepare-command \"npm ci --production\" --output dist/bin/nxapi.exe -- \"{{caxa}}/node_modules/.bin/node\" \"{{caxa}}/bin/nxapi.js\"", - "start": "node bin/nxapi.js presence" + "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "body-parser": "^1.19.2", @@ -48,6 +46,7 @@ "@rollup/plugin-alias": "^3.1.9", "@rollup/plugin-commonjs": "^21.0.3", "@rollup/plugin-html": "^0.2.4", + "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.1.3", "@rollup/plugin-replace": "^4.0.0", "@rollup/plugin-typescript": "^8.3.1", @@ -75,5 +74,28 @@ "ts-json-schema-generator": "^1.0.0", "tslib": "^2.4.0", "typescript": "^4.7.0-dev.20220308" + }, + "build": { + "appId": "uk.org.fancy.nxapi.app", + "productName": "Nintendo Switch Online", + "copyright": "Copyright © 2022 Samuel Elliott", + "npmRebuild": false, + "files": [ + "dist/app/bundle", + "dist/app-main-bundle.cjs", + "dist/cli-bundle.js", + "!dist/app/package", + "resources" + ], + "asar": false, + "extraMetadata": { + "main": "dist/app-main-bundle.cjs" + }, + "directories": { + "output": "dist/app/package" + }, + "mac": { + "identity": null + } } } diff --git a/rollup.config.js b/rollup.config.js index 47fa623..34d4e8b 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -6,7 +6,78 @@ import alias from '@rollup/plugin-alias'; import nodeResolve from '@rollup/plugin-node-resolve'; import nodePolyfill from 'rollup-plugin-polyfill-node'; import html from '@rollup/plugin-html'; +import json from '@rollup/plugin-json'; +/** + * @type {import('rollup').RollupOptions} + */ +const cli = { + input: 'src/cli-entry.ts', + output: { + file: 'dist/cli-bundle.js', + format: 'es', + inlineDynamicImports: true, + }, + plugins: [ + typescript({ + noEmit: true, + declaration: false, + }), + commonjs({ + // the ".ts" extension is required + extensions: ['.js', '.jsx', '.ts', '.tsx'], + esmExternals: true, + // events and stream modify module.exports + requireReturnsDefault: 'preferred', + }), + json(), + nodeResolve({ + browser: false, + preferBuiltins: true, + }), + ], + external: [ + 'node-notifier', + 'frida', + ], +}; + +/** + * @type {import('rollup').RollupOptions} + */ +const app = { + input: 'src/app/main/app-entry.cts', + output: { + file: 'dist/app-main-bundle.cjs', + format: 'cjs', + inlineDynamicImports: true, + }, + plugins: [ + typescript({ + noEmit: true, + declaration: false, + }), + commonjs({ + // the ".ts" extension is required + extensions: ['.js', '.jsx', '.ts', '.tsx'], + esmExternals: true, + // events and stream modify module.exports + requireReturnsDefault: 'preferred', + }), + json(), + nodeResolve({ + browser: false, + preferBuiltins: true, + }), + ], + external: [ + 'electron', + ], +}; + +/** + * @type {import('rollup').RollupOptions} + */ const app_preload = { input: 'src/app/preload/index.ts', output: { @@ -33,6 +104,9 @@ const app_preload = { ], }; +/** + * @type {import('rollup').RollupOptions} + */ const app_preload_webservice = { input: 'src/app/preload-webservice/index.ts', output: { @@ -59,6 +133,9 @@ const app_preload_webservice = { ], }; +/** + * @type {import('rollup').RollupOptions} + */ const app_browser = { input: 'src/app/browser/index.ts', output: { @@ -92,6 +169,8 @@ const app_browser = { }; export default [ + cli, + app, app_preload, app_preload_webservice, app_browser, diff --git a/src/app/README.md b/src/app/README.md new file mode 100644 index 0000000..7b7e2ba --- /dev/null +++ b/src/app/README.md @@ -0,0 +1,10 @@ +Electron app +--- + +The Electron app is bundled into ~4 files in `dist/app/bundle` using Rollup. The main process code is not bundled for development, but is when packaging the app at `dist/app-main-bundle.cjs` (with the command line executable at `dist/cli-bundle.js`). + +[electron.ts](electron.ts) exports all Electron APIs used in the main process. This is because the `electron` module doesn't actually exist - Electron patches the `require` function, but not the module importer. Additionally Electron does not support using a standard JavaScript module as the app entrypoint, so [main/app-entry.cts](main/app-entry.cts) is used to import the actual app entrypoint after the `ready` event. + +Electron APIs used in renderer processes should be imported directly from the `electron` module as they are always bundled into a CommonJS module. + +Any files outside this directory must not depend on anything here, as this directory won't be included in the npm package. diff --git a/src/cli-entry.ts b/src/cli-entry.ts new file mode 100644 index 0000000..0742cb7 --- /dev/null +++ b/src/cli-entry.ts @@ -0,0 +1,7 @@ +// #!/usr/bin/env node + +import createDebug from 'debug'; + +createDebug.log = console.warn.bind(console); + +import('./cli.js').then(cli => cli.main.call(null));