ntpclient 1.1.1 → 1.1.3

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/cli.d.ts CHANGED
@@ -1 +1,2 @@
1
+ #!/usr/bin/env node
1
2
  export {};
package/cli.js CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
4
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -9,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
10
  });
10
11
  };
11
12
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const commander = require("commander");
13
+ const commander_1 = require("commander");
13
14
  const fs = require("fs");
14
15
  const path = require("path");
15
16
  const _1 = require("./");
@@ -19,7 +20,7 @@ const packageJsonPath = fs.existsSync(defaultPackageJsonPath)
19
20
  : path.join(__dirname, '../package.json');
20
21
  const packageJson = fs.readFileSync(packageJsonPath, 'utf-8');
21
22
  const { bin, description, version } = JSON.parse(packageJson);
22
- commander
23
+ commander_1.program
23
24
  .name(Object.keys(bin)[0])
24
25
  .version(version)
25
26
  .description(description)
@@ -27,7 +28,7 @@ commander
27
28
  .option('-p, --port <number>', 'Specify a custom NTP port')
28
29
  .option('-t, --timeout <number>', 'Specify the timeout in milliseconds')
29
30
  .parse(process.argv);
30
- const commanderOptions = commander.opts();
31
+ const commanderOptions = commander_1.program.opts();
31
32
  void (() => __awaiter(void 0, void 0, void 0, function* () {
32
33
  try {
33
34
  const date = yield new _1.NTPClient(Object.assign(Object.assign(Object.assign({}, (commanderOptions.server && { server: commanderOptions.server })), (commanderOptions.port && { port: commanderOptions.port })), (commanderOptions.timeout && { replyTimeout: commanderOptions.timeout }))).getNetworkTime();
package/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,uCAAuC;AACvC,yBAAyB;AACzB,6BAA6B;AAE7B,yBAA6B;AAE7B,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AACpE,MAAM,eAAe,GAAG,EAAE,CAAC,UAAU,CAAC,sBAAsB,CAAC;IAC3D,CAAC,CAAC,sBAAsB;IACxB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAE5C,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC9D,MAAM,EAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAC,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAE5D,SAAS;KACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;KACzB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,WAAW,CAAC;KACxB,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;KAC5D,MAAM,CAAC,qBAAqB,EAAE,2BAA2B,CAAC;KAC1D,MAAM,CAAC,wBAAwB,EAAE,qCAAqC,CAAC;KACvE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvB,MAAM,gBAAgB,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;AAE1C,KAAK,CAAC,GAAS,EAAE;IACf,IAAI;QACF,MAAM,IAAI,GAAG,MAAM,IAAI,YAAS,+CAC3B,CAAC,gBAAgB,CAAC,MAAM,IAAI,EAAC,MAAM,EAAE,gBAAgB,CAAC,MAAM,EAAC,CAAC,GAC9D,CAAC,gBAAgB,CAAC,IAAI,IAAI,EAAC,IAAI,EAAE,gBAAgB,CAAC,IAAI,EAAC,CAAC,GACxD,CAAC,gBAAgB,CAAC,OAAO,IAAI,EAAC,YAAY,EAAE,gBAAgB,CAAC,OAAO,EAAC,CAAC,EACzE,CAAC,cAAc,EAAE,CAAC;QAEpB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9B,OAAO,CAAC,IAAI,EAAE,CAAC;KAChB;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;AACH,CAAC,CAAA,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,yCAA+C;AAC/C,yBAAyB;AACzB,6BAA6B;AAE7B,yBAA6B;AAE7B,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AACpE,MAAM,eAAe,GAAG,EAAE,CAAC,UAAU,CAAC,sBAAsB,CAAC;IAC3D,CAAC,CAAC,sBAAsB;IACxB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAE5C,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC9D,MAAM,EAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAC,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAE5D,mBAAS;KACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;KACzB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,WAAW,CAAC;KACxB,MAAM,CAAC,qBAAqB,EAAE,6BAA6B,CAAC;KAC5D,MAAM,CAAC,qBAAqB,EAAE,2BAA2B,CAAC;KAC1D,MAAM,CAAC,wBAAwB,EAAE,qCAAqC,CAAC;KACvE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvB,MAAM,gBAAgB,GAAG,mBAAS,CAAC,IAAI,EAAE,CAAC;AAE1C,KAAK,CAAC,GAAS,EAAE;IACf,IAAI;QACF,MAAM,IAAI,GAAG,MAAM,IAAI,YAAS,+CAC3B,CAAC,gBAAgB,CAAC,MAAM,IAAI,EAAC,MAAM,EAAE,gBAAgB,CAAC,MAAM,EAAC,CAAC,GAC9D,CAAC,gBAAgB,CAAC,IAAI,IAAI,EAAC,IAAI,EAAE,gBAAgB,CAAC,IAAI,EAAC,CAAC,GACxD,CAAC,gBAAgB,CAAC,OAAO,IAAI,EAAC,YAAY,EAAE,gBAAgB,CAAC,OAAO,EAAC,CAAC,EACzE,CAAC,cAAc,EAAE,CAAC;QAEpB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9B,OAAO,CAAC,IAAI,EAAE,CAAC;KAChB;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;AACH,CAAC,CAAA,CAAC,EAAE,CAAC"}
package/package.json CHANGED
@@ -3,71 +3,42 @@
3
3
  "bin": {
4
4
  "ntpclient": "cli.js"
5
5
  },
6
- "deno": "edition-deno/src/index.ts",
7
6
  "dependencies": {
8
- "commander": "7.1.0"
7
+ "commander": "9.4.1"
9
8
  },
10
9
  "description": "A TypeScript implementation of the NTP Client Protocol",
11
10
  "devDependencies": {
12
- "@ffflorian/eslint-config": "0.6.2",
13
- "@ffflorian/prettier-config": "0.1.2",
14
- "@ffflorian/semantic-release-config": "0.5.0",
15
- "@semantic-release/changelog": "5.0.1",
16
- "@semantic-release/git": "9.0.0",
17
- "@types/jasmine": "3.6.3",
18
- "@types/node": "~14",
19
- "@typescript-eslint/eslint-plugin": "4.0.0",
20
- "@typescript-eslint/parser": "3.10.1",
11
+ "@evilmartians/lefthook": "1.2.1",
12
+ "@ffflorian/eslint-config": "0.8.3",
13
+ "@ffflorian/prettier-config": "0.1.4",
14
+ "@ffflorian/semantic-release-config": "0.5.2",
15
+ "@semantic-release/changelog": "6.0.1",
16
+ "@semantic-release/git": "10.0.1",
17
+ "@types/jasmine": "4.3.0",
18
+ "@types/node": "~16",
19
+ "@typescript-eslint/eslint-plugin": "5.43.0",
20
+ "@typescript-eslint/parser": "5.43.0",
21
21
  "babel-eslint": "10.1.0",
22
22
  "cpx": "1.5.0",
23
- "eslint": "7.20.0",
24
- "eslint-config-prettier": "7.2.0",
25
- "eslint-plugin-import": "2.22.1",
26
- "eslint-plugin-jasmine": "4.1.2",
27
- "eslint-plugin-jsdoc": "32.0.2",
28
- "eslint-plugin-no-unsanitized": "3.1.4",
29
- "eslint-plugin-prettier": "3.3.1",
30
- "eslint-plugin-simple-import-sort": "7.0.0",
31
- "eslint-plugin-sort-keys-fix": "1.1.1",
32
- "eslint-plugin-typescript-sort-keys": "1.5.0",
33
- "husky": "5.0.9",
34
- "jasmine": "3.6.4",
35
- "lint-staged": "10.5.4",
36
- "make-deno-edition": "1.2.0",
37
- "prettier": "2.2.1",
23
+ "eslint": "7.32.0",
24
+ "eslint-config-prettier": "8.5.0",
25
+ "eslint-plugin-import": "2.26.0",
26
+ "eslint-plugin-jasmine": "4.1.3",
27
+ "eslint-plugin-jsdoc": "39.6.2",
28
+ "eslint-plugin-no-unsanitized": "4.0.1",
29
+ "eslint-plugin-prettier": "4.2.1",
30
+ "eslint-plugin-simple-import-sort": "8.0.0",
31
+ "eslint-plugin-sort-keys-fix": "1.1.2",
32
+ "eslint-plugin-typescript-sort-keys": "2.1.0",
33
+ "eslint-plugin-unused-imports": "1.1.5",
34
+ "jasmine": "4.5.0",
35
+ "prettier": "2.7.1",
38
36
  "publish-flat": "1.4.1",
39
37
  "rimraf": "3.0.2",
40
- "semantic-release": "17.3.9",
41
- "ts-node": "9.1.1",
42
- "typescript": "4.1.5"
38
+ "semantic-release": "19.0.5",
39
+ "ts-node": "10.9.1",
40
+ "typescript": "4.9.3"
43
41
  },
44
- "editions": [
45
- {
46
- "description": "TypeScript source code with import for modules",
47
- "directory": "src",
48
- "engines": false,
49
- "entry": "src/index.ts",
50
- "tags": [
51
- "source",
52
- "typescript",
53
- "import"
54
- ]
55
- },
56
- {
57
- "description": "TypeScript source code made to be compatible with Deno",
58
- "directory": "edition-deno",
59
- "entry": "src/index.ts",
60
- "tags": [
61
- "typescript",
62
- "import",
63
- "deno"
64
- ],
65
- "engines": {
66
- "deno": true,
67
- "browsers": false
68
- }
69
- }
70
- ],
71
42
  "engines": {
72
43
  "node": ">= 10.9"
73
44
  },
@@ -77,26 +48,10 @@
77
48
  "cli.js.map",
78
49
  "index.d.ts",
79
50
  "index.js",
80
- "index.js.map"
81
- ],
82
- "keywords": [
83
- "deno",
84
- "deno-edition",
85
- "deno-entry",
86
- "denoland"
51
+ "index.js.map",
52
+ "src"
87
53
  ],
88
54
  "license": "GPL-3.0",
89
- "lint-staged": {
90
- "*.{json,md}": [
91
- "prettier --write"
92
- ],
93
- "spec/**/*.ts": [
94
- "eslint --config .eslintrc.spec.json --fix"
95
- ],
96
- "src/**/*.ts": [
97
- "eslint --fix"
98
- ]
99
- },
100
55
  "main": "index.js",
101
56
  "name": "ntpclient",
102
57
  "prettier": "@ffflorian/prettier-config",
@@ -105,11 +60,10 @@
105
60
  },
106
61
  "repository": "https://github.com/ffflorian/ntpclient.git",
107
62
  "scripts": {
108
- "build:deno": "make-deno-edition",
109
63
  "build:ts": "tsc",
110
- "clear": "rimraf dist edition-deno",
64
+ "clear": "rimraf dist",
111
65
  "copy:source": "cpx \"src/*.ts\" flattened",
112
- "dist": "yarn clear && yarn build:ts && yarn build:deno",
66
+ "dist": "yarn clear && yarn build:ts",
113
67
  "fix": "yarn fix:other && yarn fix:ts",
114
68
  "fix:other": "yarn prettier --write",
115
69
  "fix:ts": "yarn lint:ts --fix && yarn lint:ts:spec --fix",
@@ -119,10 +73,10 @@
119
73
  "lint:ts": "eslint --ignore-path .gitignore --ext .ts src/",
120
74
  "lint:ts:spec": "eslint --ignore-path .gitignore --ext .ts --config .eslintrc.spec.json spec/",
121
75
  "postversion": "node ../node_modules/publish-flat/cli-copy.js -i package.json -o ../package.json version",
122
- "prettier": "prettier --ignore-path .gitignore \"*.{json,md}\"",
76
+ "prettier": "prettier \"*.{json,md,yml}\"",
123
77
  "release": "semantic-release",
124
78
  "start": "ts-node src/cli.ts",
125
79
  "test": "ts-node -P tsconfig.jasmine.json node_modules/.bin/jasmine"
126
80
  },
127
- "version": "1.1.1"
81
+ "version": "1.1.3"
128
82
  }
package/src/cli.ts ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {program as commander} from 'commander';
4
+ import * as fs from 'fs';
5
+ import * as path from 'path';
6
+
7
+ import {NTPClient} from './';
8
+
9
+ const defaultPackageJsonPath = path.join(__dirname, 'package.json');
10
+ const packageJsonPath = fs.existsSync(defaultPackageJsonPath)
11
+ ? defaultPackageJsonPath
12
+ : path.join(__dirname, '../package.json');
13
+
14
+ const packageJson = fs.readFileSync(packageJsonPath, 'utf-8');
15
+ const {bin, description, version} = JSON.parse(packageJson);
16
+
17
+ commander
18
+ .name(Object.keys(bin)[0])
19
+ .version(version)
20
+ .description(description)
21
+ .option('-s, --server <host>', 'Specify a custom NTP server')
22
+ .option('-p, --port <number>', 'Specify a custom NTP port')
23
+ .option('-t, --timeout <number>', 'Specify the timeout in milliseconds')
24
+ .parse(process.argv);
25
+
26
+ const commanderOptions = commander.opts();
27
+
28
+ void (async () => {
29
+ try {
30
+ const date = await new NTPClient({
31
+ ...(commanderOptions.server && {server: commanderOptions.server}),
32
+ ...(commanderOptions.port && {port: commanderOptions.port}),
33
+ ...(commanderOptions.timeout && {replyTimeout: commanderOptions.timeout}),
34
+ }).getNetworkTime();
35
+
36
+ console.info(date.toString());
37
+ process.exit();
38
+ } catch (error) {
39
+ console.error(error);
40
+ process.exit(1);
41
+ }
42
+ })();
package/src/index.ts ADDED
@@ -0,0 +1,127 @@
1
+ /* eslint-disable no-magic-numbers */
2
+ import * as dgram from 'dgram';
3
+
4
+ const TEN_SECONDS_IN_MILLIS = 10_000;
5
+
6
+ export interface NTPConfig {
7
+ /** Remote NTP Server port number */
8
+ port?: number;
9
+ /** Amount of acceptable time to await for a response from the remote server. */
10
+ replyTimeout?: number;
11
+ /** IP/Hostname of the remote NTP Server */
12
+ server?: string;
13
+ }
14
+
15
+ const defaultConfig: Required<NTPConfig> = {
16
+ port: 123,
17
+ replyTimeout: TEN_SECONDS_IN_MILLIS,
18
+ server: 'pool.ntp.org',
19
+ };
20
+
21
+ export class NTPClient {
22
+ private readonly config: Required<NTPConfig>;
23
+
24
+ constructor(server?: string, port?: number, timeout?: number);
25
+ constructor(config?: NTPConfig);
26
+ constructor(configOrServer?: string | NTPConfig, port?: number, replyTimeout?: number) {
27
+ this.config = defaultConfig;
28
+
29
+ if (typeof configOrServer === 'string') {
30
+ this.config.server = configOrServer;
31
+ } else {
32
+ this.config = {
33
+ ...this.config,
34
+ ...configOrServer,
35
+ };
36
+ }
37
+ if (port) {
38
+ this.config.port = port;
39
+ }
40
+ if (replyTimeout) {
41
+ this.config.replyTimeout = replyTimeout;
42
+ }
43
+ }
44
+
45
+ /** Fetches the current NTP Time from the given server and port. */
46
+ public getNetworkTime(ntpReplyTimeout?: number): Promise<Date> {
47
+ if (ntpReplyTimeout) {
48
+ this.config.replyTimeout = ntpReplyTimeout;
49
+ }
50
+
51
+ return new Promise((resolve, reject) => {
52
+ const client = dgram.createSocket('udp4');
53
+ const ntpData = Buffer.alloc(48);
54
+
55
+ // RFC 2030 -> LI = 0 (no warning, 2 bits), VN = 3 (IPv4 only, 3 bits), Mode = 3 (Client Mode, 3 bits) -> 1 byte
56
+ // -> rtol(LI, 6) ^ rotl(VN, 3) ^ rotl(Mode, 0)
57
+ // -> = 0x00 ^ 0x18 ^ 0x03
58
+ ntpData[0] = 0x1b;
59
+
60
+ const timeout = setTimeout(() => {
61
+ client.close();
62
+ reject(new Error('Timeout waiting for NTP response.'));
63
+ errorFired = true;
64
+ }, this.config.replyTimeout);
65
+
66
+ /*
67
+ * Some errors can happen before/after send() or cause send() to break.
68
+ * Some errors will also be given to send()
69
+ * NOTE: the error rejection is not generalised, as the client has to
70
+ * lose the connection also, apparently.
71
+ */
72
+ let errorFired = false;
73
+
74
+ client.on('error', err => {
75
+ if (errorFired) {
76
+ return;
77
+ }
78
+
79
+ errorFired = true;
80
+ clearTimeout(timeout);
81
+
82
+ return reject(err);
83
+ });
84
+
85
+ client.send(ntpData, 0, ntpData.length, this.config.port, this.config.server, err => {
86
+ if (err) {
87
+ if (errorFired) {
88
+ return;
89
+ }
90
+ clearTimeout(timeout);
91
+ errorFired = true;
92
+ client.close();
93
+ return reject(err);
94
+ }
95
+
96
+ client.once('message', msg => {
97
+ clearTimeout(timeout);
98
+ client.close();
99
+
100
+ // Offset to get to the "Transmit Timestamp" field (time at which the reply
101
+ // departed the server for the client, in 64-bit timestamp format.
102
+ const offsetTransmitTime = 40;
103
+ let intpart = 0;
104
+ let fractpart = 0;
105
+
106
+ // Get the seconds part
107
+ for (let index = 0; index <= 3; index++) {
108
+ intpart = 256 * intpart + msg[offsetTransmitTime + index];
109
+ }
110
+
111
+ // Get the seconds fraction
112
+ for (let index = 4; index <= 7; index++) {
113
+ fractpart = 256 * fractpart + msg[offsetTransmitTime + index];
114
+ }
115
+
116
+ const milliseconds = intpart * 1000 + (fractpart * 1000) / 0x100_000_000;
117
+
118
+ // **UTC** time
119
+ const date = new Date('Jan 01 1900 GMT');
120
+ date.setUTCMilliseconds(date.getUTCMilliseconds() + milliseconds);
121
+
122
+ return resolve(date);
123
+ });
124
+ });
125
+ });
126
+ }
127
+ }
package/CHANGELOG.md DELETED
@@ -1,34 +0,0 @@
1
- # [1.1.0](https://github.com/ffflorian/ntpclient/compare/v1.0.2...v1.1.0) (2021-02-19)
2
-
3
-
4
- ### Features
5
-
6
- * Deno edition ([#572](https://github.com/ffflorian/ntpclient/issues/572)) ([ab0b63f](https://github.com/ffflorian/ntpclient/commit/ab0b63fb51d1b986846ea92d99ad8053e1ec5bee))
7
-
8
- ## [1.0.2](https://github.com/ffflorian/ntpclient/compare/v1.0.1...v1.0.2) (2019-09-06)
9
-
10
- ### Bug Fixes
11
-
12
- - Use postversion when publishing ([762781c](https://github.com/ffflorian/ntpclient/commit/762781c))
13
-
14
- ## [1.0.1](https://github.com/ffflorian/ntpclient/compare/v1.0.0...v1.0.1) (2019-06-14)
15
-
16
- ### Bug Fixes
17
-
18
- - Use flattened dir to publish ([e431a72](https://github.com/ffflorian/ntpclient/commit/e431a72))
19
-
20
- # [1.0.0](https://github.com/ffflorian/ntpclient/compare/v0.8.0...v1.0.0) (2019-06-13)
21
-
22
- ### Features
23
-
24
- - New import structure, remove webpack ([1b6b324](https://github.com/ffflorian/ntpclient/commit/1b6b324))
25
-
26
- ### BREAKING CHANGES
27
-
28
- - NTPClient is not a default export anymore and the 'dist' directory is omitted
29
-
30
- # [0.8.0](https://github.com/ffflorian/ntpclient/compare/v0.7.3...v0.8.0) (2019-05-27)
31
-
32
- ### Features
33
-
34
- - Force release ([a13fb26](https://github.com/ffflorian/ntpclient/commit/a13fb26))