quick-n-dirty-utils 0.0.13 → 1.0.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 CHANGED
@@ -31,12 +31,12 @@ const range = util.range(1, 10)
31
31
 
32
32
  ### Date / Time
33
33
 
34
- All date / time functions use `moment` (MomentJS, the de-factor standard library for date/time) to provide the
34
+ All date / time functions use `luxon` (Luxon, the de-factor standard library for date/time) to provide the
35
35
  functionality.
36
36
 
37
37
  #### `formatDate(date, format)`
38
- Converts a `Date` object or `moment` object into a string for quick display of dates **without** a time component.
39
- The default format is `YYYY-MM-DD`.
38
+ Converts a `Date` object, Unix timestamp or `luxon.DateTime` object into a string for quick display of dates
39
+ **without** a time component. The default format is `yyyy-MM-dd`.
40
40
 
41
41
  Example:
42
42
 
@@ -50,15 +50,15 @@ const reactComponent = props => (
50
50
  <div>{util.formatDate(new Date())}</div>
51
51
 
52
52
  {/* prints out a date like 18/02/20 */}
53
- <div>{util.formatDate(new Date(), "DD/MM/YY")}</div>
53
+ <div>{util.formatDate(new Date(), "dd/MM/yy")}</div>
54
54
  </div>
55
55
  )
56
56
  ```
57
57
 
58
- #### `formatDateTime(dateTime)`
59
- Converts a `Date` object or `moment` object into a string for quick display of dates **with** a time component. If you
60
- require a custom format, you can simply use `formatDate(new Date(), "YY-MM-DD hh:mm:ss)`. The default format is
61
- `DD/MM/YY hh:mm`
58
+ #### `formatDateTime(dateTime, format)`
59
+ Converts a `Date` object, Unix timestamp or `luxon.DateTime` object into a string for quick display of dates
60
+ **with** a time component. If you require a custom format, you can provide this. The default format is
61
+ `dd/MM/yy T` (e.g. 31/12/22 16:43)
62
62
 
63
63
  Example:
64
64
 
@@ -76,8 +76,8 @@ const reactComponent = props => (
76
76
 
77
77
  #### `applyTimeZoneOffset(timestamp, serverOffsetMin)`
78
78
  Used to offset mismatching server/client time zones in regards to timestamps. If your server provides Unix timestamps,
79
- but is located in a different timezone, then simply printing out those timestamps (as `moment`/`Date`) will print the
80
- time in the clients (browser) time zone, not the server time zone. Example: Your server provides timestamps for events
79
+ but is located in a different timezone, then simply printing out those timestamps (as `luxon.DateTime`/`Date`) will print
80
+ the time in the clients (browser) time zone, not the server time zone. Example: Your server provides timestamps for events
81
81
  and the event occurred at midnight, but you are located 2 hours behind the server's time zone. If you use that timestamp
82
82
  and print out the date (e.g. `util.formatDateTime(new Date(myTimestamp))`), it will show you 10pm, rather than midnight.
83
83
  Depending on the application, it might be useful to retain the local time.
@@ -218,6 +218,43 @@ fetch("http://myurl.com", {
218
218
  })
219
219
  ```
220
220
 
221
+
222
+ #### React State Handlers
223
+
224
+ When a React component uses a state variable to store a list of items any create/update/delete operation
225
+ will have to modify that state variable. To help integrate new/updated items or remove items, the
226
+ following 2 functions are available:
227
+
228
+ ```javascript
229
+ import util from "quick-n-dirty-utils"
230
+ import React from "react"
231
+
232
+ class MyComp extends React.Component {
233
+ constructor(props) {
234
+ super(props)
235
+ this.state = { myList: [] }
236
+ }
237
+ saveItem(item) {
238
+ // doesn't matter if add or update
239
+ this.setState(oldState => ({
240
+ ...oldState,
241
+ myList: util.integrateDbItem(oldState.myList, item),
242
+ }))
243
+ }
244
+ deleteItem(itemId) {
245
+ this.setState(oldState => ({
246
+ ...oldState,
247
+ myList: util.removeDbItem(oldState.myList, itemId),
248
+ }))
249
+ }
250
+ }
251
+ ```
252
+
253
+ Both functions will use the MongoDB convention and use the JSON key `_id` to match items. You can
254
+ override that by providing a 3rd parameter: `util.integrateDbItem(oldState.myList, item, "uid")`
255
+ and `util.removeDbItem(oldState.myList, itemId, "uid")` if for example your JSON key holding the
256
+ unique ID is called `uid`.
257
+
221
258
  #### Login
222
259
 
223
260
  The login functions (including `getAuthJsonHeader()` and `getAuthHeader()`) assume that you use the browser's
@@ -355,6 +392,13 @@ The colors are defaulted to blue (1.0) -> white (0.5) -> red (0.0) and are provi
355
392
 
356
393
  Static field providing a `colors` setting for the `getTriColor(..)` function for red -> yellow -> green.
357
394
 
395
+ #### `hexToRgb(hexValue, alpha)`
396
+
397
+ Converts a colour provided as hexadecimal string into an RGB string, like `rgb(255, 255, 255)` that can
398
+ be used in CSS. It allows an optional `alpha` parameter (default `null`), which will create a string
399
+ like `rgba(255, 255, 255, 0.3)` for an `alpha = 0.3`. The `hexValue` can be provided with or without the
400
+ `#` prefix.
401
+
358
402
  ### Sorting
359
403
 
360
404
  This library introduces a way to sort lists. It has capabilties to sort in ascending or descending order
@@ -5,9 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports["default"] = void 0;
7
7
 
8
- var _moment = _interopRequireDefault(require("moment"));
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
8
+ var _luxon = require("luxon");
11
9
 
12
10
  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
13
11
 
@@ -26,9 +24,9 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
26
24
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
27
25
 
28
26
  // default date format
29
- var DATE_FORMAT = "YYYY-MM-DD"; // default date/time format
27
+ var DATE_FORMAT = "yyyy-MM-dd"; // default date/time format
30
28
 
31
- var DATE_TIME_FORMAT = "DD/MM/YY hh:mm"; // localStorage key uses to store the auth token
29
+ var DATE_TIME_FORMAT = "dd/MM/yy T"; // localStorage key uses to store the auth token
32
30
 
33
31
  var LS_AUTH_KEY = "auth_token";
34
32
  var SORT_DIRECTIONS = {
@@ -39,7 +37,7 @@ var SORT_DIRECTIONS = {
39
37
  * Utilities used across components
40
38
  */
41
39
 
42
- var util = {
40
+ var qndUtils = {
43
41
  /**
44
42
  * Default date format for quick display
45
43
  */
@@ -61,18 +59,54 @@ var util = {
61
59
 
62
60
  /**
63
61
  * Uses the hard-coded date format to format the provided date. If no valid date is provided, null is returned.
64
- * @param {(object|string)} date: the date to format, provided either as string or moment object. If a string is
65
- * provided, that string needs to be parsable by moment
66
- * @param {string} dateFormat: the date format to be used by moment to serialise the date, default "YY-MM-DD"
62
+ * @param {(object|string)} date: the date to format, provided either as string or Luxon object. If a string is
63
+ * provided, that string needs to be parsable by Luxon
64
+ * @param {string} dateFormat: the date format to be used by Luxon to serialise the date, default "yyyy-MM-dd"
67
65
  * @returns {String} the formatted string or null, if the provided date string or object is not valid or cannot be
68
66
  * parsed.
69
67
  */
70
68
  formatDate: function formatDate(date) {
71
69
  var dateFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DATE_FORMAT;
72
- var d = (0, _moment["default"])(date);
73
70
 
74
- if (d.isValid()) {
75
- return d.format(dateFormat);
71
+ // handling JS date objects
72
+ if (date instanceof Date) {
73
+ return this.formatDate(_luxon.DateTime.fromJSDate(date));
74
+ } // handling unix timestamps (guessing s or ms)
75
+
76
+
77
+ if (typeof date === "number") {
78
+ if (date < 5000000000) {
79
+ // otherwise would be year 2128+
80
+ return this.formatDate(_luxon.DateTime.fromSeconds(date), dateFormat);
81
+ } // doesn't work for dates before 28 Feb 1970
82
+
83
+
84
+ return this.formatDate(_luxon.DateTime.fromMillis(date), dateFormat);
85
+ } // handling string date/times
86
+
87
+
88
+ if (typeof date === "string") {
89
+ // attempt to parse
90
+ var functions = [_luxon.DateTime.fromISO, _luxon.DateTime.fromSQL, _luxon.DateTime.fromRFC2822];
91
+
92
+ for (var i = 0; i < functions.length; i += 1) {
93
+ var parsedDate = functions[i](date);
94
+
95
+ if (parsedDate.isValid) {
96
+ return this.formatDate(parsedDate, dateFormat);
97
+ }
98
+ }
99
+
100
+ throw Error("Provided string date could not be detected, please convert to Luxon DateTime before formatting");
101
+ } // handling momentjs objects
102
+
103
+
104
+ if (date._isAMomentObject != null && date.unix != null) {
105
+ return this.formatDate(date.unix(), dateFormat);
106
+ }
107
+
108
+ if (date.isValid) {
109
+ return date.toFormat(dateFormat);
76
110
  }
77
111
 
78
112
  return null;
@@ -80,13 +114,15 @@ var util = {
80
114
 
81
115
  /**
82
116
  * Uses a hard-coded date/time format to format the provided date. If no valid date is provided, null is returned.
83
- * @param {(object|string)} date: the date to format, provided either as string or moment object. If a string is
84
- * provided, that string needs to be parsable by moment
117
+ * @param {(object|string)} date: the date to format, provided either as string, Number or Luxon object. If a string
118
+ * is provided, that string needs to be parsable by Luxon
119
+ * @param {string} dateTimeFormat - the Luxon datetime format, defaults to dd/MM/yy T
85
120
  * @returns {String} the formatted string or null, if the provided date string or object is not valid or cannot be
86
121
  * parsed.
87
122
  */
88
123
  formatDateTime: function formatDateTime(date) {
89
- return this.formatDate(date, DATE_TIME_FORMAT);
124
+ var dateTimeFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DATE_TIME_FORMAT;
125
+ return this.formatDate(date, dateTimeFormat);
90
126
  },
91
127
 
92
128
  /**
@@ -193,13 +229,13 @@ var util = {
193
229
  },
194
230
 
195
231
  /**
196
- * Applies an offset to a unix timestamp to allow native JS dates and moment to render the resulting date in the
232
+ * Applies an offset to a unix timestamp to allow native JS dates and Luxon to render the resulting date in the
197
233
  * server's timezone, rather than the browsers time zone. The idea is to convert all timestamps of a time series
198
234
  * received from a server in a different time into offset timestamps, which then allows to render the data as chart
199
235
  * or table using the server's time and not the users time.
200
236
  * @param {number} timestamp: the original timestamp in seconds since 1970
201
237
  * @param {number} serverOffsetMin: the number of minutes behind UTC (e.g. +10:00 is 600 minutes after UTC)
202
- * @returns {number} the offset timestamp which when used by moment or as argument for new Date(..) will produce a
238
+ * @returns {number} the offset timestamp which when used by Luxon or as argument for new Date(..) will produce a
203
239
  * date / time string in the server's timezone rather than the users/browser timezone
204
240
  */
205
241
  applyTimeZoneOffset: function applyTimeZoneOffset(timestamp) {
@@ -430,9 +466,14 @@ var util = {
430
466
 
431
467
  /**
432
468
  * Sums up all the values in the provided list
433
- * @param {Array} list
469
+ * @param {Array} list - a list of numbers
470
+ * @returns {Number} the sum of all the items in the list or 0 if the list is empty.
434
471
  */
435
472
  sum: function sum(list) {
473
+ if (list.length === 0) {
474
+ return 0;
475
+ }
476
+
436
477
  return list.reduce(function (a, b) {
437
478
  return a + b;
438
479
  }, 0);
@@ -457,9 +498,9 @@ var util = {
457
498
 
458
499
  /**
459
500
  * Returns an inversed JSON object, where every value becomes the key and maps to its original key.
460
- * @param {object} jsonObject - a flat JSON object, with simple keys and simple values (boolean,
501
+ * @param {object} jsonObject - a flat JSON object, with simple keys and simple values (boolean,
461
502
  * string, number are supported)
462
- * @param {boolean} showWarning - optional flag to print out console warnings in case any key/value
503
+ * @param {boolean} showWarning - optional flag to print out console warnings in case any key/value
463
504
  * pair cannot be mapped or if the JSON object contains duplicates - default = true
464
505
  * @returns {object} a JSON object which maps from each value of the input to the key.
465
506
  */
@@ -533,19 +574,20 @@ var util = {
533
574
  return;
534
575
  }
535
576
 
536
- return current[k];
577
+ current = current[k];
537
578
  }); // return the final value after iterating through all keys
538
579
 
539
580
  return current;
540
581
  },
541
582
 
542
583
  /**
543
- * A function that will map a list of items to a JSON object which contains keys extracted from each item
584
+ * A function that will map a list of items to a JSON object which contains keys extracted from each item
544
585
  * and the value is the object from that list with that key. If multiple values map to the same keys an array
545
586
  * of objects will be mapped to that key.
546
587
  * @param {Array} list - a list of items
547
- * @param {string|function} - a string key (can contain . for nested levels) or a lambda that does the extraction
548
- * for each item.
588
+ * @param {string|function} keyOrFunction - a string key (can contain . for nested levels) or a lambda that does
589
+ * the extraction for each item.
590
+ * @returns {Object} a json object mapping from key to an item or list of items
549
591
  */
550
592
  mapListToKeyObject: function mapListToKeyObject(list, keyOrFunction) {
551
593
  // check if it's a simple key mapping or lambda
@@ -576,7 +618,63 @@ var util = {
576
618
  }
577
619
  });
578
620
  return result;
621
+ },
622
+
623
+ /**
624
+ * Adds or updates an item in a list of items and returns the updated list. This is useful for React state updates.
625
+ * @param {Array} list - a list of items
626
+ * @param {Object} item - a JSON object to be added to the list or updated, if it already exists
627
+ * @param {string} idKey - the JSON key pointing to the element ID of the item and items in the list
628
+ * @returns {Array} the updated array with the provided `item` either added or updated.
629
+ */
630
+ integrateDbItem: function integrateDbItem(list, item) {
631
+ var idKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "_id";
632
+ var index = list.map(function (i) {
633
+ return i[idKey];
634
+ }).indexOf(item[idKey]);
635
+
636
+ if (index === -1) {
637
+ list.push(item);
638
+ } else {
639
+ list[index] = item;
640
+ }
641
+
642
+ return list;
643
+ },
644
+
645
+ /**
646
+ * Removes an item from a list by referring to the unique item id. This is a simple id filter. Useful for React state updates.
647
+ * @param {Array} list - a list of items
648
+ * @param {string} itemId - the id of the item to remove
649
+ * @param {string} idKey - the JSON key pointing to the element ID of the item and items in the list
650
+ * @returns {Array} the provided list minus the element with the id provided.
651
+ */
652
+ removeDbItem: function removeDbItem(list, itemId) {
653
+ var idKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "_id";
654
+ return list.filter(function (item) {
655
+ return item[idKey] !== itemId;
656
+ });
657
+ },
658
+
659
+ /**
660
+ * Translates a hex colour code into an RGB string. If alpha is provided, it will return an RGBA string. The string can be used in CSS styles
661
+ * @param {string} hexValue - the hex value of colour; can be provided with or without the # and as 3 or 6 digit color
662
+ * @param {Number} alpha - optional: if provided an RGBA (transparency) colour will be returned
663
+ * @returns {string} a colour string usable in colour definitions in CSS
664
+ */
665
+ hexToRgb: function hexToRgb(hexValue) {
666
+ var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
667
+ var hex = hexValue.replace("#", "");
668
+ var r = parseInt(hex.length === 3 ? hex.slice(0, 1).repeat(2) : hex.slice(0, 2), 16);
669
+ var g = parseInt(hex.length === 3 ? hex.slice(1, 2).repeat(2) : hex.slice(2, 4), 16);
670
+ var b = parseInt(hex.length === 3 ? hex.slice(2, 3).repeat(2) : hex.slice(4, 6), 16);
671
+
672
+ if (alpha != null) {
673
+ return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(alpha, ")");
674
+ }
675
+
676
+ return "rgb(".concat(r, ", ").concat(g, ", ").concat(b, ")");
579
677
  }
580
678
  };
581
- var _default = util;
679
+ var _default = qndUtils;
582
680
  exports["default"] = _default;
package/index.js CHANGED
@@ -1 +1 @@
1
- module.exports = require("./dist/util").default
1
+ module.exports = { util: require("./dist/functions").default }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quick-n-dirty-utils",
3
- "version": "0.0.13",
3
+ "version": "1.0.0",
4
4
  "description": "Little useful nuggets for accelerated web development",
5
5
  "scripts": {
6
6
  "build": "./node_modules/.bin/babel src --out-dir ./dist",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "homepage": "https://github.com/ilfrich/quick-n-dirty-utils#readme",
24
24
  "dependencies": {
25
- "moment": "^2.24.0"
25
+ "luxon": "^3.0.1"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@babel/cli": "^7.2.2",