Skip to content

Commit 961a62f

Browse files
committed
lib: add navigator.platform
1 parent 14af167 commit 961a62f

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

doc/api/globals.md

+15
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,21 @@ logical processors available to the current Node.js instance.
637637
console.log(`This process is running on ${navigator.hardwareConcurrency} logical processors`);
638638
```
639639

640+
### `navigator.platform`
641+
642+
<!-- YAML
643+
added: REPLACEME
644+
-->
645+
646+
* {string}
647+
648+
The `navigator.platform` read-only property returns a string identifying the
649+
platform on which the Node.js instance is running.
650+
651+
```js
652+
console.log(`This process is running on ${navigator.platform}`);
653+
```
654+
640655
### `navigator.userAgent`
641656

642657
<!-- YAML

lib/internal/navigator.js

+40
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
'use strict';
22

33
const {
4+
StringPrototypeToUpperCase,
5+
StringPrototypeSlice,
46
ObjectDefineProperties,
57
Symbol,
68
} = primordials;
@@ -20,10 +22,39 @@ const {
2022
const kInitialize = Symbol('kInitialize');
2123
const nodeVersion = process.version;
2224

25+
/**
26+
* @param {Object} process
27+
* @param {string} process.platform
28+
* @param {string} process.arch
29+
* @returns {string}
30+
*/
31+
function getNavigatorPlatform(process) {
32+
if (process.platform === 'darwin') {
33+
// On macOS, modern browsers return 'MacIntel' even if running on Apple Silicon.
34+
return 'MacIntel';
35+
} else if (process.platform === 'win32') {
36+
// On Windows, modern browsers return 'Win32' even if running on a 64-bit version of Windows.
37+
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#usage_notes
38+
return 'Win32';
39+
} else if (process.platform === 'linux') {
40+
if (process.arch === 'ia32') {
41+
return 'Linux i686';
42+
} else if (process.arch === 'x64') {
43+
return 'Linux x86_64';
44+
} else {
45+
return `Linux ${process.arch}`;
46+
}
47+
} else {
48+
// For cases like freebsd, openbsd, sunos, aix etc.
49+
return `${StringPrototypeToUpperCase(process.platform[0])}${StringPrototypeSlice(process.platform, 1)} ${process.arch}`;
50+
}
51+
}
52+
2353
class Navigator {
2454
// Private properties are used to avoid brand validations.
2555
#availableParallelism;
2656
#userAgent = `Node.js/${nodeVersion.slice(1, nodeVersion.indexOf('.'))}`;
57+
#platform = getNavigatorPlatform(process);
2758

2859
constructor() {
2960
if (arguments[0] === kInitialize) {
@@ -46,14 +77,23 @@ class Navigator {
4677
get userAgent() {
4778
return this.#userAgent;
4879
}
80+
81+
/**
82+
* @return {string}
83+
*/
84+
get platform() {
85+
return this.#platform;
86+
}
4987
}
5088

5189
ObjectDefineProperties(Navigator.prototype, {
5290
hardwareConcurrency: kEnumerableProperty,
5391
userAgent: kEnumerableProperty,
92+
platform: kEnumerableProperty,
5493
});
5594

5695
module.exports = {
96+
getNavigatorPlatform,
5797
navigator: new Navigator(kInitialize),
5898
Navigator,
5999
};

test/parallel/test-navigator.js

+25
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
'use strict';
22

3+
// Flags: --expose-internals
4+
35
require('../common');
46
const assert = require('assert');
7+
const { getNavigatorPlatform } = require('internal/navigator');
58

69
const is = {
710
number: (value, key) => {
@@ -15,3 +18,25 @@ is.number(navigator.hardwareConcurrency, 'hardwareConcurrency');
1518
assert.ok(navigator.hardwareConcurrency > 0);
1619
assert.strictEqual(typeof navigator.userAgent, 'string');
1720
assert.match(navigator.userAgent, /^Node\.js\/\d+$/);
21+
22+
assert.strictEqual(typeof navigator.platform, 'string');
23+
if (process.platform === 'darwin') {
24+
assert.strictEqual(navigator.platform, 'MacIntel');
25+
} else if (process.platform === 'win32') {
26+
assert.strictEqual(navigator.platform, 'Win32');
27+
} else if (process.platform === 'linux' && process.arch === 'ia32') {
28+
assert.strictEqual(navigator.platform, 'Linux i686');
29+
} else if (process.platform === 'linux' && process.arch === 'x64') {
30+
assert.strictEqual(navigator.platform, 'Linux x86_64');
31+
} else {
32+
assert.strictEqual(navigator.platform, `${process.platform[0].toUpperCase()}${process.platform.slice(1)} ${process.arch}`);
33+
}
34+
35+
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'darwin'}), 'MacIntel');
36+
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'darwin'}), 'MacIntel');
37+
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'linux'}), 'Linux i686');
38+
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'linux'}), 'Linux x86_64');
39+
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'linux'}), 'Linux arm64');
40+
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'freebsd'}), 'Freebsd x64');
41+
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'win32'}), 'Win32');
42+
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'win32'}), 'Win32');

0 commit comments

Comments
 (0)