ntpclient 1.6.5 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{esm/cli.js → cli.js} +7 -3
- package/dist/{esm/index.js → index.js} +1 -1
- package/package.json +9 -18
- package/dist/cjs/cli.js +0 -30
- package/dist/cjs/index.js +0 -94
- package/dist/cjs/package.json +0 -3
- package/dist/esm/cli.d.ts +0 -2
- package/dist/esm/index.d.ts +0 -15
- package/dist/esm/package.json +0 -3
- /package/dist/{cjs/cli.d.ts → cli.d.ts} +0 -0
- /package/dist/{cjs/index.d.ts → index.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ TypeScript implementation of the NTP Client Protocol. Based on [node-ntp-client]
|
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
12
|
-
ℹ️ This is a
|
|
12
|
+
ℹ️ This is a pure [ESM](https://nodejs.org/api/esm.html#introduction) module.
|
|
13
13
|
|
|
14
14
|
Run `yarn add ntpclient` or `npm i ntpclient`.
|
|
15
15
|
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
2
5
|
import { program as commander } from 'commander';
|
|
3
|
-
import { createRequire } from 'module';
|
|
4
|
-
const require = createRequire(import.meta.url);
|
|
5
6
|
import { NTPClient } from './index.js';
|
|
6
|
-
const
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
const packageJsonPath = path.join(__dirname, '../package.json');
|
|
10
|
+
const { bin, description, version } = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
7
11
|
commander
|
|
8
12
|
.name(Object.keys(bin)[0])
|
|
9
13
|
.version(version)
|
package/package.json
CHANGED
|
@@ -1,43 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Florian Imdahl <git@ffflorian.de>",
|
|
3
|
-
"bin": "dist/
|
|
3
|
+
"bin": "dist/cli.js",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"commander": "12.1.0"
|
|
6
6
|
},
|
|
7
7
|
"description": "A TypeScript implementation of the NTP Client Protocol",
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"rimraf": "
|
|
10
|
-
"typescript": "5.5.
|
|
11
|
-
"vitest": "
|
|
9
|
+
"rimraf": "6.0.1",
|
|
10
|
+
"typescript": "5.5.4",
|
|
11
|
+
"vitest": "2.0.5"
|
|
12
12
|
},
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">= 18.0"
|
|
15
15
|
},
|
|
16
|
-
"exports":
|
|
17
|
-
".": {
|
|
18
|
-
"import": "./dist/esm/index.js",
|
|
19
|
-
"require": "./dist/cjs/index.js"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
16
|
+
"exports": "./dist/index.js",
|
|
22
17
|
"files": [
|
|
23
18
|
"dist"
|
|
24
19
|
],
|
|
25
20
|
"license": "GPL-3.0",
|
|
26
|
-
"
|
|
27
|
-
"module": "dist/esm/index.js",
|
|
21
|
+
"module": "dist/index.js",
|
|
28
22
|
"name": "ntpclient",
|
|
29
23
|
"repository": "https://github.com/ffflorian/node-packages/tree/main/packages/ntpclient",
|
|
30
24
|
"scripts": {
|
|
31
|
-
"build": "
|
|
32
|
-
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
33
|
-
"build:esm": "tsc -p tsconfig.json",
|
|
25
|
+
"build": "tsc -p tsconfig.json",
|
|
34
26
|
"clean": "rimraf dist",
|
|
35
27
|
"dist": "yarn clean && yarn build",
|
|
36
|
-
"generate:packagejson": "../../bin/generate-hybrid-package-json.sh",
|
|
37
28
|
"start": "node --loader ts-node/esm src/cli.ts",
|
|
38
29
|
"test": "vitest run"
|
|
39
30
|
},
|
|
40
31
|
"type": "module",
|
|
41
|
-
"version": "1.
|
|
42
|
-
"gitHead": "
|
|
32
|
+
"version": "1.7.0",
|
|
33
|
+
"gitHead": "f1a74d8ec9721d5b52a00e41b2ec73278e048290"
|
|
43
34
|
}
|
package/dist/cjs/cli.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { program as commander } from 'commander';
|
|
3
|
-
import { createRequire } from 'module';
|
|
4
|
-
const require = createRequire(import.meta.url);
|
|
5
|
-
import { NTPClient } from './index.js';
|
|
6
|
-
const { bin, description, version } = require('../package.json');
|
|
7
|
-
commander
|
|
8
|
-
.name(Object.keys(bin)[0])
|
|
9
|
-
.version(version)
|
|
10
|
-
.description(description)
|
|
11
|
-
.option('-s, --server <host>', 'Specify a custom NTP server')
|
|
12
|
-
.option('-p, --port <number>', 'Specify a custom NTP port')
|
|
13
|
-
.option('-t, --timeout <number>', 'Specify the timeout in milliseconds')
|
|
14
|
-
.parse(process.argv);
|
|
15
|
-
const commanderOptions = commander.opts();
|
|
16
|
-
void (async () => {
|
|
17
|
-
try {
|
|
18
|
-
const date = await new NTPClient({
|
|
19
|
-
...(commanderOptions.server && { server: commanderOptions.server }),
|
|
20
|
-
...(commanderOptions.port && { port: commanderOptions.port }),
|
|
21
|
-
...(commanderOptions.timeout && { replyTimeout: commanderOptions.timeout }),
|
|
22
|
-
}).getNetworkTime();
|
|
23
|
-
console.info(date.toString());
|
|
24
|
-
process.exit();
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
console.error(error);
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|
|
30
|
-
})();
|
package/dist/cjs/index.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import * as dgram from 'dgram';
|
|
2
|
-
const TEN_SECONDS_IN_MILLIS = 10000;
|
|
3
|
-
const defaultConfig = {
|
|
4
|
-
port: 123,
|
|
5
|
-
replyTimeout: TEN_SECONDS_IN_MILLIS,
|
|
6
|
-
server: 'pool.ntp.org',
|
|
7
|
-
};
|
|
8
|
-
export class NTPClient {
|
|
9
|
-
constructor(configOrServer, port, replyTimeout) {
|
|
10
|
-
this.config = defaultConfig;
|
|
11
|
-
if (typeof configOrServer === 'string') {
|
|
12
|
-
this.config.server = configOrServer;
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
this.config = {
|
|
16
|
-
...this.config,
|
|
17
|
-
...configOrServer,
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
if (port) {
|
|
21
|
-
this.config.port = port;
|
|
22
|
-
}
|
|
23
|
-
if (replyTimeout) {
|
|
24
|
-
this.config.replyTimeout = replyTimeout;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/** Fetches the current NTP Time from the given server and port. */
|
|
28
|
-
getNetworkTime(ntpReplyTimeout) {
|
|
29
|
-
if (ntpReplyTimeout) {
|
|
30
|
-
this.config.replyTimeout = ntpReplyTimeout;
|
|
31
|
-
}
|
|
32
|
-
return new Promise((resolve, reject) => {
|
|
33
|
-
const client = dgram.createSocket('udp4');
|
|
34
|
-
const ntpData = Buffer.alloc(48);
|
|
35
|
-
// RFC 2030 -> LI = 0 (no warning, 2 bits), VN = 3 (IPv4 only, 3 bits), Mode = 3 (Client Mode, 3 bits) -> 1 byte
|
|
36
|
-
// -> rtol(LI, 6) ^ rotl(VN, 3) ^ rotl(Mode, 0)
|
|
37
|
-
// -> = 0x00 ^ 0x18 ^ 0x03
|
|
38
|
-
ntpData[0] = 0x1b;
|
|
39
|
-
const timeout = setTimeout(() => {
|
|
40
|
-
client.close();
|
|
41
|
-
reject(new Error('Timeout waiting for NTP response.'));
|
|
42
|
-
errorFired = true;
|
|
43
|
-
}, this.config.replyTimeout);
|
|
44
|
-
/*
|
|
45
|
-
* Some errors can happen before/after send() or cause send() to break.
|
|
46
|
-
* Some errors will also be given to send()
|
|
47
|
-
* NOTE: the error rejection is not generalised, as the client has to
|
|
48
|
-
* lose the connection also, apparently.
|
|
49
|
-
*/
|
|
50
|
-
let errorFired = false;
|
|
51
|
-
client.on('error', err => {
|
|
52
|
-
if (errorFired) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
errorFired = true;
|
|
56
|
-
clearTimeout(timeout);
|
|
57
|
-
return reject(err);
|
|
58
|
-
});
|
|
59
|
-
client.send(ntpData, 0, ntpData.length, this.config.port, this.config.server, err => {
|
|
60
|
-
if (err) {
|
|
61
|
-
if (errorFired) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
clearTimeout(timeout);
|
|
65
|
-
errorFired = true;
|
|
66
|
-
client.close();
|
|
67
|
-
return reject(err);
|
|
68
|
-
}
|
|
69
|
-
client.once('message', msg => {
|
|
70
|
-
clearTimeout(timeout);
|
|
71
|
-
client.close();
|
|
72
|
-
// Offset to get to the "Transmit Timestamp" field (time at which the reply
|
|
73
|
-
// departed the server for the client, in 64-bit timestamp format.
|
|
74
|
-
const offsetTransmitTime = 40;
|
|
75
|
-
let intpart = 0;
|
|
76
|
-
let fractpart = 0;
|
|
77
|
-
// Get the seconds part
|
|
78
|
-
for (let index = 0; index <= 3; index++) {
|
|
79
|
-
intpart = 256 * intpart + msg[offsetTransmitTime + index];
|
|
80
|
-
}
|
|
81
|
-
// Get the seconds fraction
|
|
82
|
-
for (let index = 4; index <= 7; index++) {
|
|
83
|
-
fractpart = 256 * fractpart + msg[offsetTransmitTime + index];
|
|
84
|
-
}
|
|
85
|
-
const milliseconds = intpart * 1000 + (fractpart * 1000) / 4294967296;
|
|
86
|
-
// **UTC** time
|
|
87
|
-
const date = new Date('Jan 01 1900 GMT');
|
|
88
|
-
date.setUTCMilliseconds(date.getUTCMilliseconds() + milliseconds);
|
|
89
|
-
return resolve(date);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
package/dist/cjs/package.json
DELETED
package/dist/esm/cli.d.ts
DELETED
package/dist/esm/index.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface NTPConfig {
|
|
2
|
-
/** Remote NTP Server port number */
|
|
3
|
-
port?: number;
|
|
4
|
-
/** Amount of acceptable time to await for a response from the remote server. */
|
|
5
|
-
replyTimeout?: number;
|
|
6
|
-
/** IP/Hostname of the remote NTP Server */
|
|
7
|
-
server?: string;
|
|
8
|
-
}
|
|
9
|
-
export declare class NTPClient {
|
|
10
|
-
private readonly config;
|
|
11
|
-
constructor(server?: string, port?: number, timeout?: number);
|
|
12
|
-
constructor(config?: NTPConfig);
|
|
13
|
-
/** Fetches the current NTP Time from the given server and port. */
|
|
14
|
-
getNetworkTime(ntpReplyTimeout?: number): Promise<Date>;
|
|
15
|
-
}
|
package/dist/esm/package.json
DELETED
|
File without changes
|
|
File without changes
|