Skip to content

Commit

Permalink
lib: add navigator.platform
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak committed Oct 28, 2023
1 parent 14af167 commit 66e2ffc
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
15 changes: 15 additions & 0 deletions doc/api/globals.md
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,21 @@ logical processors available to the current Node.js instance.
console.log(`This process is running on ${navigator.hardwareConcurrency} logical processors`);
```

### `navigator.platform`

<!-- YAML
added: REPLACEME
-->

* {string}

The `navigator.platform` read-only property returns a string identifying the
platform on which the Node.js instance is running.

```js
console.log(`This process is running on ${navigator.platform}`);
```

### `navigator.userAgent`

<!-- YAML
Expand Down
62 changes: 62 additions & 0 deletions lib/internal/navigator.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use strict';

const {
StringPrototypeToUpperCase,
StringPrototypeSlice,
ObjectDefineProperties,
Symbol,
} = primordials;
Expand All @@ -20,10 +22,61 @@ const {
const kInitialize = Symbol('kInitialize');
const nodeVersion = process.version;

/**
* @param {Object} process

Check warning on line 26 in lib/internal/navigator.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Invalid JSDoc @param "process" type "Object"; prefer: "object"
* @param {string} process.platform
* @param {string} process.arch
* @returns {string}
*/
function getNavigatorPlatform(process) {
if (process.platform === 'darwin') {
// On macOS, modern browsers return 'MacIntel' even if running on Apple Silicon.
return 'MacIntel';
} else if (process.platform === 'win32') {
// On Windows, modern browsers return 'Win32' even if running on a 64-bit version of Windows.
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#usage_notes
return 'Win32';
} else if (process.platform === 'linux') {
if (process.arch === 'ia32') {
return 'Linux i686';
} else if (process.arch === 'x64') {
return 'Linux x86_64';
} else {

Check failure on line 44 in lib/internal/navigator.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Unnecessary 'else' after 'return'
return `Linux ${process.arch}`;
}
} else if (process.platform === 'freebsd') {
if (process.arch === 'ia32') {
return 'FreeBSD i386';
} else if (process.arch === 'x64') {
return 'FreeBSD amd64';
} else {

Check failure on line 52 in lib/internal/navigator.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Unnecessary 'else' after 'return'
return `FreeBSD ${process.arch}`;
}
} else if (process.platform === 'openbsd') {
if (process.arch === 'ia32') {
return 'OpenBSD i386';
} else if (process.arch === 'x64') {
return 'OpenBSD amd64';
} else {

Check failure on line 60 in lib/internal/navigator.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Unnecessary 'else' after 'return'
return `OpenBSD ${process.arch}`;
}
} else if (process.platform === 'sunos') {
if (process.arch === 'ia32') {
return 'SunOS i86pc';
} else {

Check failure on line 66 in lib/internal/navigator.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Unnecessary 'else' after 'return'
return `SunOS ${process.arch}`;
}
} else {
// For cases like freebsd, openbsd, sunos, aix etc.
return `${StringPrototypeToUpperCase(process.platform[0])}${StringPrototypeSlice(process.platform, 1)} ${process.arch}`;
}
}

class Navigator {
// Private properties are used to avoid brand validations.
#availableParallelism;
#userAgent = `Node.js/${nodeVersion.slice(1, nodeVersion.indexOf('.'))}`;
#platform = getNavigatorPlatform(process);

constructor() {
if (arguments[0] === kInitialize) {
Expand All @@ -46,14 +99,23 @@ class Navigator {
get userAgent() {
return this.#userAgent;
}

/**
* @return {string}
*/
get platform() {
return this.#platform;
}
}

ObjectDefineProperties(Navigator.prototype, {
hardwareConcurrency: kEnumerableProperty,
userAgent: kEnumerableProperty,
platform: kEnumerableProperty,
});

module.exports = {
getNavigatorPlatform,
navigator: new Navigator(kInitialize),
Navigator,
};
55 changes: 55 additions & 0 deletions test/parallel/test-navigator.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
'use strict';

// Flags: --expose-internals

require('../common');
const assert = require('assert');
const { getNavigatorPlatform } = require('internal/navigator');

const is = {
number: (value, key) => {
Expand All @@ -15,3 +18,55 @@ is.number(navigator.hardwareConcurrency, 'hardwareConcurrency');
assert.ok(navigator.hardwareConcurrency > 0);
assert.strictEqual(typeof navigator.userAgent, 'string');
assert.match(navigator.userAgent, /^Node\.js\/\d+$/);

assert.strictEqual(typeof navigator.platform, 'string');
if (process.platform === 'darwin') {
assert.strictEqual(navigator.platform, 'MacIntel');
} else if (process.platform === 'win32') {
assert.strictEqual(navigator.platform, 'Win32');
} else if (process.platform === 'linux' && process.arch === 'ia32') {
assert.strictEqual(navigator.platform, 'Linux i686');
} else if (process.platform === 'linux' && process.arch === 'x64') {
assert.strictEqual(navigator.platform, 'Linux x86_64');
} else if (process.platform === 'freebsd') {
if (process.arch === 'ia32') {
assert.strictEqual(navigator.platform, 'FreeBSD i386');
} else if (process.arch === 'x64') {
assert.strictEqual(navigator.platform, 'FreeBSD amd64');
} else {
assert.strictEqual(navigator.platform, `FreeBSD ${process.arch}`);
}
} else if (process.platform === 'openbsd') {
if (process.arch === 'ia32') {
assert.strictEqual(navigator.platform, 'OpenBSD i386');
} else if (process.arch === 'x64') {
assert.strictEqual(navigator.platform, 'OpenBSD amd64');
} else {
assert.strictEqual(navigator.platform, `OpenBSD ${process.arch}`);
}
} else if (process.platform === 'sunos') {
if (process.arch === 'ia32') {
assert.strictEqual(navigator.platform, 'SunOS i86pc');
} else {
assert.strictEqual(navigator.platform, `SunOS ${process.arch}`);
}
} else {
assert.strictEqual(navigator.platform, `${process.platform[0].toUpperCase()}${process.platform.slice(1)} ${process.arch}`);
}

assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'darwin' }), 'MacIntel');
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'darwin' }), 'MacIntel');
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'linux' }), 'Linux i686');
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'linux' }), 'Linux x86_64');
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'linux' }), 'Linux arm64');
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'win32' }), 'Win32');
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'win32' }), 'Win32');
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'win32' }), 'Win32');
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'freebsd' }), 'FreeBSD i386');
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'freebsd' }), 'FreeBSD amd64');
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'freebsd' }), 'FreeBSD arm64');
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'openbsd' }), 'OpenBSD i386');
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'openbsd' }), 'OpenBSD amd64');
assert.strictEqual(getNavigatorPlatform({ arch: 'arm64', platform: 'openbsd' }), 'OpenBSD arm64');
assert.strictEqual(getNavigatorPlatform({ arch: 'ia32', platform: 'sunos' }), 'SunOS i86pc');
assert.strictEqual(getNavigatorPlatform({ arch: 'x64', platform: 'sunos' }), 'SunOS x64');

0 comments on commit 66e2ffc

Please sign in to comment.