@naturalcycles/nodejs-lib 13.23.1 → 13.24.1

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.
@@ -34,7 +34,7 @@ function csvStringParse(str, cfg = {}) {
34
34
  }
35
35
  exports.csvStringParse = csvStringParse;
36
36
  function csvStringToArray(str) {
37
- const objPattern = new RegExp('(,|\\r?\\n|\\r|^)(?:"([^"]*(?:""[^"]*)*)"|([^,\\r\\n]*))', 'gi');
37
+ const objPattern = new RegExp(String.raw `(,|\r?\n|\r|^)(?:"([^"]*(?:""[^"]*)*)"|([^,\r\n]*))`, 'gi');
38
38
  let matches;
39
39
  const arr = [[]];
40
40
  while ((matches = objPattern.exec(str))) {
@@ -130,7 +130,7 @@ class SlackService {
130
130
  }
131
131
  exports.SlackService = SlackService;
132
132
  function slackDefaultMessagePrefixHook(msg) {
133
- const tokens = [(0, js_lib_1.localTimeNow)().toPretty()];
133
+ const tokens = [js_lib_1.localTime.now().toPretty()];
134
134
  const { ctx } = msg;
135
135
  // AppEngine-specific decoration
136
136
  if (GAE && ctx && typeof ctx === 'object' && typeof ctx.header === 'function') {
@@ -103,7 +103,7 @@ class ProgressLogger {
103
103
  if (perHour > 900) {
104
104
  perHour = Math.round(perHour / 1000) + 'K';
105
105
  }
106
- logger.log(`${(0, colors_1.dimGrey)((0, js_lib_1.localTimeNow)().toPretty())} ${(0, colors_1.white)(metric)} took ${(0, colors_1.yellow)((0, js_lib_1._since)(this.started))} so far to process ${(0, colors_1.yellow)(batchedProgress)} rows, ~${(0, colors_1.yellow)(perHour)}/hour`);
106
+ logger.log(`${(0, colors_1.dimGrey)(js_lib_1.localTime.now().toPretty())} ${(0, colors_1.white)(metric)} took ${(0, colors_1.yellow)((0, js_lib_1._since)(this.started))} so far to process ${(0, colors_1.yellow)(batchedProgress)} rows, ~${(0, colors_1.yellow)(perHour)}/hour`);
107
107
  }
108
108
  else if (final) {
109
109
  logger.log(`${(0, colors_1.boldWhite)(metric)} took ${(0, colors_1.yellow)((0, js_lib_1._since)(this.started))} to process ${(0, colors_1.yellow)(batchedProgress)} rows with total RPS of ${(0, colors_1.yellow)(rpsTotal)}`);
@@ -5,7 +5,7 @@ const js_lib_1 = require("@naturalcycles/js-lib");
5
5
  const fs2_1 = require("../fs/fs2");
6
6
  const git_util_1 = require("./git.util");
7
7
  function generateBuildInfo(opt = {}) {
8
- const now = (0, js_lib_1.localTimeOrNow)(opt.overrideTimestamp);
8
+ const now = js_lib_1.localTime.orNow(opt.overrideTimestamp);
9
9
  const ts = now.unix();
10
10
  const rev = (0, git_util_1.gitCurrentCommitSha)();
11
11
  const branchName = (0, git_util_1.gitCurrentBranchName)();
@@ -41,14 +41,14 @@ function stringExtensions(joi) {
41
41
  let { min, max } = args;
42
42
  // Today allows +-14 hours gap to account for different timezones
43
43
  if (max === 'today') {
44
- max = (0, js_lib_1.localTimeNow)().plus(14, 'hour').toISODate();
44
+ max = getTodayStrPlus15();
45
45
  }
46
46
  if (min === 'today') {
47
- min = (0, js_lib_1.localTimeNow)().minus(14, 'hour').toISODate();
47
+ min = getTodayStrMinus15();
48
48
  }
49
49
  // console.log('min/max', min, max)
50
- const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v);
51
- if (!m || m.length <= 1) {
50
+ const parts = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v);
51
+ if (!parts || parts.length < 4) {
52
52
  err = 'string.dateString';
53
53
  }
54
54
  else if (min && v < min) {
@@ -57,8 +57,7 @@ function stringExtensions(joi) {
57
57
  else if (max && v > max) {
58
58
  err = 'string.dateStringMax';
59
59
  }
60
- else if (!js_lib_1.LocalDate.isValid(v)) {
61
- // todo: replace with another regex (from ajv-validators) for speed
60
+ else if (!isValidDate(parts)) {
62
61
  err = 'string.dateStringCalendarAccuracy';
63
62
  }
64
63
  if (err) {
@@ -71,3 +70,39 @@ function stringExtensions(joi) {
71
70
  };
72
71
  }
73
72
  exports.stringExtensions = stringExtensions;
73
+ const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
74
+ // Based on: https://github.com/ajv-validator
75
+ function isValidDate(parts) {
76
+ const year = Number(parts[1]);
77
+ const month = Number(parts[2]);
78
+ const day = Number(parts[3]);
79
+ return (month >= 1 &&
80
+ month <= 12 &&
81
+ day >= 1 &&
82
+ day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]));
83
+ }
84
+ function isLeapYear(year) {
85
+ return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
86
+ }
87
+ let lastCheckedPlus = 0;
88
+ let todayStrPlusCached;
89
+ let lastCheckedMinus = 0;
90
+ let todayStrMinusCached;
91
+ function getTodayStrPlus15() {
92
+ const now = Date.now();
93
+ if (now - lastCheckedPlus < 3_600_000) {
94
+ // cached for 1 hour
95
+ return todayStrPlusCached;
96
+ }
97
+ lastCheckedPlus = now;
98
+ return (todayStrPlusCached = js_lib_1.localTime.now().plus(15, 'hour').toISODate());
99
+ }
100
+ function getTodayStrMinus15() {
101
+ const now = Date.now();
102
+ if (now - lastCheckedMinus < 3_600_000) {
103
+ // cached for 1 hour
104
+ return todayStrMinusCached;
105
+ }
106
+ lastCheckedMinus = now;
107
+ return (todayStrMinusCached = js_lib_1.localTime.now().plus(-15, 'hour').toISODate());
108
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
- "version": "13.23.1",
3
+ "version": "13.24.1",
4
4
  "scripts": {
5
5
  "prepare": "husky",
6
6
  "docs-serve": "vuepress dev docs",
@@ -34,7 +34,7 @@
34
34
  "yargs": "^17.0.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@naturalcycles/bench-lib": "^2.0.0",
37
+ "@naturalcycles/bench-lib": "^3.0.0",
38
38
  "@naturalcycles/dev-lib": "^13.0.0",
39
39
  "@types/node": "^20.1.0",
40
40
  "@types/yargs": "^16.0.0",
@@ -56,7 +56,10 @@ export function csvStringParse<T extends AnyObject = any>(
56
56
  }
57
57
 
58
58
  export function csvStringToArray(str: string): string[][] {
59
- const objPattern = new RegExp('(,|\\r?\\n|\\r|^)(?:"([^"]*(?:""[^"]*)*)"|([^,\\r\\n]*))', 'gi')
59
+ const objPattern = new RegExp(
60
+ String.raw`(,|\r?\n|\r|^)(?:"([^"]*(?:""[^"]*)*)"|([^,\r\n]*))`,
61
+ 'gi',
62
+ )
60
63
  let matches: RegExpExecArray | null
61
64
  const arr: any[][] = [[]]
62
65
 
@@ -6,7 +6,7 @@ import {
6
6
  CommonLogLevel,
7
7
  Fetcher,
8
8
  getFetcher,
9
- localTimeNow,
9
+ localTime,
10
10
  PQueue,
11
11
  } from '@naturalcycles/js-lib'
12
12
  import { _inspect, InspectAnyOptions } from '..'
@@ -180,7 +180,7 @@ export class SlackService<CTX = any> {
180
180
  }
181
181
 
182
182
  export function slackDefaultMessagePrefixHook(msg: SlackMessage): string[] {
183
- const tokens = [localTimeNow().toPretty()]
183
+ const tokens = [localTime.now().toPretty()]
184
184
  const { ctx } = msg
185
185
 
186
186
  // AppEngine-specific decoration
@@ -4,7 +4,7 @@ import {
4
4
  _since,
5
5
  AnyObject,
6
6
  CommonLogger,
7
- localTimeNow,
7
+ localTime,
8
8
  SimpleMovingAverage,
9
9
  UnixTimestampMillisNumber,
10
10
  } from '@naturalcycles/js-lib'
@@ -294,7 +294,7 @@ export class ProgressLogger<T> implements Disposable {
294
294
  }
295
295
 
296
296
  logger.log(
297
- `${dimGrey(localTimeNow().toPretty())} ${white(metric)} took ${yellow(
297
+ `${dimGrey(localTime.now().toPretty())} ${white(metric)} took ${yellow(
298
298
  _since(this.started),
299
299
  )} so far to process ${yellow(batchedProgress)} rows, ~${yellow(perHour)}/hour`,
300
300
  )
@@ -2,7 +2,7 @@ import {
2
2
  _filterUndefinedValues,
3
3
  AnyObject,
4
4
  BuildInfo,
5
- localTimeOrNow,
5
+ localTime,
6
6
  UnixTimestampNumber,
7
7
  } from '@naturalcycles/js-lib'
8
8
  import { fs2 } from '../fs/fs2'
@@ -21,7 +21,7 @@ export interface GenerateBuildInfoOptions {
21
21
  }
22
22
 
23
23
  export function generateBuildInfo(opt: GenerateBuildInfoOptions = {}): BuildInfo {
24
- const now = localTimeOrNow(opt.overrideTimestamp)
24
+ const now = localTime.orNow(opt.overrideTimestamp)
25
25
  const ts = now.unix()
26
26
 
27
27
  const rev = gitCurrentCommitSha()
@@ -1,4 +1,4 @@
1
- import { LocalDate, localTimeNow } from '@naturalcycles/js-lib'
1
+ import { localTime } from '@naturalcycles/js-lib'
2
2
  import Joi, { Extension, StringSchema as JoiStringSchema } from 'joi'
3
3
 
4
4
  export interface StringSchema<TSchema = string> extends JoiStringSchema<TSchema> {
@@ -51,22 +51,21 @@ export function stringExtensions(joi: typeof Joi): Extension {
51
51
 
52
52
  // Today allows +-14 hours gap to account for different timezones
53
53
  if (max === 'today') {
54
- max = localTimeNow().plus(14, 'hour').toISODate()
54
+ max = getTodayStrPlus15()
55
55
  }
56
56
  if (min === 'today') {
57
- min = localTimeNow().minus(14, 'hour').toISODate()
57
+ min = getTodayStrMinus15()
58
58
  }
59
59
  // console.log('min/max', min, max)
60
60
 
61
- const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v)
62
- if (!m || m.length <= 1) {
61
+ const parts = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v)
62
+ if (!parts || parts.length < 4) {
63
63
  err = 'string.dateString'
64
64
  } else if (min && v < min) {
65
65
  err = 'string.dateStringMin'
66
66
  } else if (max && v > max) {
67
67
  err = 'string.dateStringMax'
68
- } else if (!LocalDate.isValid(v)) {
69
- // todo: replace with another regex (from ajv-validators) for speed
68
+ } else if (!isValidDate(parts)) {
70
69
  err = 'string.dateStringCalendarAccuracy'
71
70
  }
72
71
 
@@ -80,3 +79,48 @@ export function stringExtensions(joi: typeof Joi): Extension {
80
79
  },
81
80
  }
82
81
  }
82
+
83
+ const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
84
+ // Based on: https://github.com/ajv-validator
85
+ function isValidDate(parts: string[]): boolean {
86
+ const year = Number(parts[1])
87
+ const month = Number(parts[2])
88
+ const day = Number(parts[3])
89
+ return (
90
+ month >= 1 &&
91
+ month <= 12 &&
92
+ day >= 1 &&
93
+ day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]!)
94
+ )
95
+ }
96
+
97
+ function isLeapYear(year: number): boolean {
98
+ return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
99
+ }
100
+
101
+ let lastCheckedPlus = 0
102
+ let todayStrPlusCached: string
103
+ let lastCheckedMinus = 0
104
+ let todayStrMinusCached: string
105
+
106
+ function getTodayStrPlus15(): string {
107
+ const now = Date.now()
108
+ if (now - lastCheckedPlus < 3_600_000) {
109
+ // cached for 1 hour
110
+ return todayStrPlusCached
111
+ }
112
+
113
+ lastCheckedPlus = now
114
+ return (todayStrPlusCached = localTime.now().plus(15, 'hour').toISODate())
115
+ }
116
+
117
+ function getTodayStrMinus15(): string {
118
+ const now = Date.now()
119
+ if (now - lastCheckedMinus < 3_600_000) {
120
+ // cached for 1 hour
121
+ return todayStrMinusCached
122
+ }
123
+
124
+ lastCheckedMinus = now
125
+ return (todayStrMinusCached = localTime.now().plus(-15, 'hour').toISODate())
126
+ }