Skip to content

Commit 5d77ea1

Browse files
feat(util): support local files for options.manifestUrl (#1494)
Fixes: #1490
1 parent c816533 commit 5d77ea1

File tree

13 files changed

+85
-37
lines changed

13 files changed

+85
-37
lines changed

.github/workflows/ci.yml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: e2e
33
on:
44
pull_request:
55
branches:
6-
- main
6+
- main
77

88
permissions:
99
contents: read
@@ -18,9 +18,9 @@ jobs:
1818
strategy:
1919
matrix:
2020
os:
21-
- macos-15
22-
- ubuntu-24.04
23-
- windows-2025
21+
- macos-15
22+
- ubuntu-24.04
23+
- windows-2025
2424
fail-fast: false
2525
runs-on: ${{ matrix.os }}
2626
steps:
@@ -36,8 +36,19 @@ jobs:
3636
run: npm ci
3737
- name: Check for linting errors
3838
run: npm run lint
39-
- name: Run tests
39+
- name: Run tests with coverage
4040
run: npm run test:cov
41+
env:
42+
CI: true
43+
- name: Upload coverage artifact
44+
if: always()
45+
uses: actions/upload-artifact@v6.0.0
46+
with:
47+
name: coverage-${{ matrix.os }}
48+
path: coverage
4149
- name: Report Coverage
4250
if: always()
43-
uses: davelosert/vitest-coverage-report-action@v2.9.0
51+
uses: davelosert/vitest-coverage-report-action@v2.9.0
52+
with:
53+
name: Vitest Coverage (${{ matrix.os }})
54+
json-summary-path: coverage/coverage-summary.json

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ Options
194194
| platform | `"linux" \| "osx" \| "win"` | | Host platform |
195195
| arch | `"ia32" \| "x64" \| "arm64"` | | Host architecture |
196196
| downloadUrl | `"https://dl.nwjs.io" \| "https://npm.taobao.org/mirrors/nwjs" \| https://npmmirror.com/mirrors/nwjs \| "https://github.com/corwin-of-amber/nw.js/releases/"` | `"https://dl.nwjs.io"` | Download server. Supports file systems too (for example `file:///home/localghost/nwjs_mirror`) |
197-
| manifestUrl | `"https://nwjs.io/versions.json" \| "https://raw.githubusercontent.com/nwutils/nw-builder/main/src/util/osx.arm.versions.json"` | `"https://nwjs.io/versions.json"` | Versions manifest |
197+
| manifestUrl | `"https://nwjs.io/versions.json" \| "https://raw.githubusercontent.com/nwutils/nw-builder/main/src/util/osx.arm.versions.json"` | `"https://nwjs.io/versions.json"` | Versions manifest URI, gotten via https or local file |
198198
| cacheDir | `string` | `"./cache"` | Directory to cache NW binaries |
199199
| cache | `boolean` | `true`| If true the existing cache is used. Otherwise it removes and redownloads it. |
200200
| ffmpeg | `boolean` | `false`| If true the chromium ffmpeg is replaced by community version with proprietary codecs. |

package-lock.json

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
"yauzl-promise": "^4.0.0"
7878
},
7979
"volta": {
80-
"node": "24.9.0",
81-
"npm": "11.6.4"
80+
"node": "25.2.1",
81+
"npm": "11.7.0"
8282
}
8383
}

src/bld.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ import setOsxConfig from './bld/osx.js';
8989
* @property {"normal" | "sdk"} [flavor = "normal"] Build flavor
9090
* @property {"linux" | "osx" | "win"} [platform] Target platform
9191
* @property {"ia32" | "x64" | "arm64"} [arch] Target arch
92-
* @property {string} [manifestUrl = "https://nwjs.io/versions.json"] Manifest URL
92+
* @property {string} [manifestUrl = "https://nwjs.io/versions.json"] Versions manifest URI, https or file path
9393
* @property {string} [srcDir = "./src"] Source directory
9494
* @property {string} [cacheDir = "./cache"] Cache directory
9595
* @property {string} [outDir = "./out"] Out directory

src/cli.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ program
1414
.option('--platform <string>', 'NW.js supported platform', util.PLATFORM_KV[process.platform])
1515
.option('--arch <string>', 'NW.js supported architecture', util.ARCH_KV[process.arch])
1616
.option('--downloadUrl <string>', 'NW.js download server', 'https://dl.nwjs.io')
17-
.option('--manifestUrl <string>', 'NW.js version info', 'https://nwjs.io/versions.json')
17+
.option('--manifestUrl <string>', 'NW.js versions manifest URI', 'https://nwjs.io/versions.json')
1818
.option('--cacheDir <string>', 'Cache NW.js binaries', './cache')
1919
.option('--outDir <string>', 'NW.js build artifacts', './out')
2020
.option('--app <object>', 'Platform specific app metadata. Refer to docs for more info', {})

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import util from './util.js';
1616
* @property {"linux" | "osx" | "win"} platform Host platform
1717
* @property {"ia32" | "x64" | "arm64"} arch Host architecture
1818
* @property {"https://dl.nwjs.io" | string} [downloadUrl="https://dl.nwjs.io"] Download server
19-
* @property {"https://nwjs.io/versions.json" | string} [manifestUrl="https://nwjs.io/versions.json"] Versions manifest
19+
* @property {"https://nwjs.io/versions.json" | string} [manifestUrl="https://nwjs.io/versions.json"] Versions manifest URI, https or file path
2020
* @property {"./cache" | string} [cacheDir="./cache"] Directory to cache NW binaries
2121
* @property {"./" | string} [srcDir="./"] File paths to application code
2222
* @property {"./out" | string} [outDir="./out"] Directory to store build artifacts

src/util.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,23 @@ import fs from 'node:fs';
33
import https from 'node:https';
44
import path from 'node:path';
55
import process from 'node:process';
6+
import url from 'node:url';
67

78
import * as GlobModule from 'glob';
89

910
/**
1011
* Get manifest (array of NW release metadata) from URL.
11-
* @param {string} manifestUrl Url to manifest
12-
* @returns {Promise<string>} - Manifest object
12+
* @param {string} manifestUrl Versions manifest URI, https or file path
13+
* @returns {string} - Manifest object
1314
*/
1415
function getManifest(manifestUrl) {
1516
let chunks = '';
1617

18+
if (manifestUrl.startsWith('file://')) {
19+
const filePath = url.fileURLToPath(manifestUrl);
20+
return fs.readFileSync(filePath, 'utf-8');
21+
}
22+
1723
return new Promise((resolve) => {
1824
const req = https.get(manifestUrl, (response) => {
1925
response.on('data', (chunk) => {
@@ -42,8 +48,8 @@ function getManifest(manifestUrl) {
4248
* @param {string} platform NW platform
4349
* @param {string} arch NW architecture
4450
* @param {string} cacheDir Directory to store NW binaries
45-
* @param {string} manifestUrl Url to manifest
46-
* @returns {object} Version specific release info
51+
* @param {string} manifestUrl Versions manifest URI, https or file path
52+
* @returns {Promise<object>} Version specific release info
4753
*/
4854
async function getReleaseInfo(
4955
version,
@@ -343,8 +349,8 @@ export const validate = async (options, releaseInfo) => {
343349
if (typeof options.downloadUrl === 'string' && !options.downloadUrl.startsWith('http') && !options.downloadUrl.startsWith('file')) {
344350
throw new Error('Expected options.downloadUrl to be a string and starts with `http` or `file`.');
345351
}
346-
if (typeof options.manifestUrl === 'string' && !options.manifestUrl.startsWith('http') && !options.manifestUrl.startsWith('file')) {
347-
throw new Error('Expected options.manifestUrl to be a string and starts with `http` or `file`.');
352+
if (typeof options.manifestUrl === 'string' && !options.manifestUrl.startsWith('https') && !options.manifestUrl.startsWith('file')) {
353+
throw new Error('Expected options.manifestUrl to be a string and starts with `https` or `file`.');
348354
}
349355
if (typeof options.cacheDir !== 'string') {
350356
throw new Error('Expected options.cacheDir to be a string. Got ' + typeof options.cacheDir);
@@ -425,15 +431,15 @@ export const validate = async (options, releaseInfo) => {
425431
}
426432

427433
if (typeof options.nativeAddon !== 'boolean') {
428-
throw new Error('Expected options.nativeAddon to be a boolean. Got ' + typeof options.nativeAddon);
434+
throw new Error('Expected options.nativeAddon to be a boolean. Got ' + typeof options.nativeAddon);
429435
}
430436

431437
if (typeof options.zip !== 'boolean' &
432-
options.zip !== 'zip' &&
433-
options.zip !== 'tar' &&
434-
options.zip !== 'tgz') {
435-
throw new Error('Expected options.zip to be a boolean, `zip`, `tar` or `tgz`. Got ' + typeof options.zip);
436-
}
438+
options.zip !== 'zip' &&
439+
options.zip !== 'tar' &&
440+
options.zip !== 'tgz') {
441+
throw new Error('Expected options.zip to be a boolean, `zip`, `tar` or `tgz`. Got ' + typeof options.zip);
442+
}
437443

438444
if (options.platform === 'linux') {
439445
if (options.app.name && typeof options.app.name !== 'string') {
@@ -664,4 +670,4 @@ function log(severity, logLevel, message) {
664670
return stdout;
665671
}
666672

667-
export default { fileExists, getReleaseInfo, getPath, PLATFORM_KV, ARCH_KV, EXE_NAME, globFiles, getNodeManifest, parse, validate, log };
673+
export default { fileExists, getReleaseInfo, getManifest, getPath, PLATFORM_KV, ARCH_KV, EXE_NAME, globFiles, getNodeManifest, parse, validate, log };
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"latest": "v0.106.1",
3+
"stable": "v0.106.1",
4+
"lts": "v0.14.7",
5+
"versions": [
6+
{
7+
"version": "v0.106.1",
8+
"date": "2025/12/26",
9+
"files": [
10+
"win-x64",
11+
"win-ia32",
12+
"win-arm64",
13+
"linux-x64",
14+
"linux-ia32",
15+
"osx-x64",
16+
"osx-arm64"
17+
],
18+
"flavors": [
19+
"normal",
20+
"sdk"
21+
],
22+
"components": {
23+
"node": "25.2.1",
24+
"chromium": "143.0.7499.170"
25+
}
26+
}
27+
]
28+
}

tests/specs/node.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ describe('get/node', function () {
2020
'0.106.0',
2121
'./tests/fixtures'
2222
);
23-
expect(util.fileExists(nodeFile)).resolves.toBe(true);
23+
await expect(util.fileExists(nodeFile)).resolves.toBe(true);
2424
});
2525
});

0 commit comments

Comments
 (0)