read-excel-file 5.7.1 → 5.8.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.
Files changed (213) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +45 -19
  3. package/bundle/read-excel-file.min.js +1 -1
  4. package/bundle/read-excel-file.min.js.map +1 -1
  5. package/commonjs/read/coordinates.js +7 -10
  6. package/commonjs/read/coordinates.js.map +1 -1
  7. package/commonjs/read/dropEmptyColumns.js +6 -18
  8. package/commonjs/read/dropEmptyColumns.js.map +1 -1
  9. package/commonjs/read/dropEmptyColumns.test.js.map +1 -1
  10. package/commonjs/read/dropEmptyRows.js +11 -23
  11. package/commonjs/read/dropEmptyRows.js.map +1 -1
  12. package/commonjs/read/dropEmptyRows.test.js.map +1 -1
  13. package/commonjs/read/getData.js +31 -43
  14. package/commonjs/read/getData.js.map +1 -1
  15. package/commonjs/read/isDateTimestamp.js +51 -40
  16. package/commonjs/read/isDateTimestamp.js.map +1 -1
  17. package/commonjs/read/parseCell.js +3 -10
  18. package/commonjs/read/parseCell.js.map +1 -1
  19. package/commonjs/read/parseCellValue.js +28 -59
  20. package/commonjs/read/parseCellValue.js.map +1 -1
  21. package/commonjs/read/parseCells.js +3 -7
  22. package/commonjs/read/parseCells.js.map +1 -1
  23. package/commonjs/read/parseDate.js +5 -5
  24. package/commonjs/read/parseDate.js.map +1 -1
  25. package/commonjs/read/parseDate.test.js.map +1 -1
  26. package/commonjs/read/parseDimensions.js +6 -18
  27. package/commonjs/read/parseDimensions.js.map +1 -1
  28. package/commonjs/read/parseFilePaths.js +4 -11
  29. package/commonjs/read/parseFilePaths.js.map +1 -1
  30. package/commonjs/read/parseProperties.js +6 -8
  31. package/commonjs/read/parseProperties.js.map +1 -1
  32. package/commonjs/read/parseSharedStrings.js +0 -3
  33. package/commonjs/read/parseSharedStrings.js.map +1 -1
  34. package/commonjs/read/parseSheet.js +3 -7
  35. package/commonjs/read/parseSheet.js.map +1 -1
  36. package/commonjs/read/parseStyles.js +13 -21
  37. package/commonjs/read/parseStyles.js.map +1 -1
  38. package/commonjs/read/readSheetNamesBrowser.js +0 -3
  39. package/commonjs/read/readSheetNamesBrowser.js.map +1 -1
  40. package/commonjs/read/readSheetNamesNode.js +0 -3
  41. package/commonjs/read/readSheetNamesNode.js.map +1 -1
  42. package/commonjs/read/readSheetNamesNode.test.js.map +1 -1
  43. package/commonjs/read/readSheetNamesWebWorker.js +0 -3
  44. package/commonjs/read/readSheetNamesWebWorker.js.map +1 -1
  45. package/commonjs/read/readXlsx.js +34 -42
  46. package/commonjs/read/readXlsx.js.map +1 -1
  47. package/commonjs/read/readXlsxFileBrowser.js +0 -5
  48. package/commonjs/read/readXlsxFileBrowser.js.map +1 -1
  49. package/commonjs/read/readXlsxFileContents.js +12 -22
  50. package/commonjs/read/readXlsxFileContents.js.map +1 -1
  51. package/commonjs/read/readXlsxFileNode.js +0 -5
  52. package/commonjs/read/readXlsxFileNode.js.map +1 -1
  53. package/commonjs/read/readXlsxFileNode.test.js.map +1 -1
  54. package/commonjs/read/readXlsxFileWebWorker.js +0 -5
  55. package/commonjs/read/readXlsxFileWebWorker.js.map +1 -1
  56. package/commonjs/read/schema/convertMapToSchema.js +1 -8
  57. package/commonjs/read/schema/convertMapToSchema.js.map +1 -1
  58. package/commonjs/read/schema/convertMapToSchema.test.js.map +1 -1
  59. package/commonjs/read/schema/convertToJson.js +143 -142
  60. package/commonjs/read/schema/convertToJson.js.map +1 -1
  61. package/commonjs/read/schema/convertToJson.legacy.js +60 -0
  62. package/commonjs/read/schema/convertToJson.legacy.js.map +1 -0
  63. package/commonjs/read/schema/convertToJson.legacy.test.js.map +1 -0
  64. package/commonjs/read/schema/convertToJson.spreadsheet.js +25 -0
  65. package/commonjs/read/schema/convertToJson.spreadsheet.js.map +1 -0
  66. package/commonjs/read/schema/convertToJson.spreadsheet.test.js.map +1 -0
  67. package/commonjs/read/schema/convertToJson.test.js.map +1 -1
  68. package/commonjs/read/unpackXlsxFileBrowser.js +3 -9
  69. package/commonjs/read/unpackXlsxFileBrowser.js.map +1 -1
  70. package/commonjs/read/unpackXlsxFileNode.js +9 -15
  71. package/commonjs/read/unpackXlsxFileNode.js.map +1 -1
  72. package/commonjs/types/Boolean.js +0 -4
  73. package/commonjs/types/Boolean.js.map +1 -1
  74. package/commonjs/types/Date.js +0 -12
  75. package/commonjs/types/Date.js.map +1 -1
  76. package/commonjs/types/Email.js +0 -7
  77. package/commonjs/types/Email.js.map +1 -1
  78. package/commonjs/types/Email.test.js.map +1 -1
  79. package/commonjs/types/Integer.js +0 -7
  80. package/commonjs/types/Integer.js.map +1 -1
  81. package/commonjs/types/Integer.test.js.map +1 -1
  82. package/commonjs/types/InvalidError.js +8 -28
  83. package/commonjs/types/InvalidError.js.map +1 -1
  84. package/commonjs/types/Number.js +2 -10
  85. package/commonjs/types/Number.js.map +1 -1
  86. package/commonjs/types/String.js +4 -11
  87. package/commonjs/types/String.js.map +1 -1
  88. package/commonjs/types/URL.js +5 -8
  89. package/commonjs/types/URL.js.map +1 -1
  90. package/commonjs/types/URL.test.js.map +1 -1
  91. package/commonjs/xml/dom.js +6 -25
  92. package/commonjs/xml/dom.js.map +1 -1
  93. package/commonjs/xml/xlsx.js +1 -24
  94. package/commonjs/xml/xlsx.js.map +1 -1
  95. package/commonjs/xml/xml.js +1 -4
  96. package/commonjs/xml/xml.js.map +1 -1
  97. package/commonjs/xml/xmlBrowser.js +1 -2
  98. package/commonjs/xml/xmlBrowser.js.map +1 -1
  99. package/commonjs/xml/xpath/xlsx-xpath.js +3 -16
  100. package/commonjs/xml/xpath/xlsx-xpath.js.map +1 -1
  101. package/commonjs/xml/xpath/xpathBrowser.js +3 -5
  102. package/commonjs/xml/xpath/xpathBrowser.js.map +1 -1
  103. package/commonjs/xml/xpath/xpathNode.js +1 -5
  104. package/commonjs/xml/xpath/xpathNode.js.map +1 -1
  105. package/map/index.cjs +2 -0
  106. package/map/index.cjs.js +7 -0
  107. package/map/index.d.ts +11 -0
  108. package/map/index.js +1 -0
  109. package/map/package.json +17 -0
  110. package/modules/read/coordinates.js +7 -8
  111. package/modules/read/coordinates.js.map +1 -1
  112. package/modules/read/dropEmptyColumns.js +6 -17
  113. package/modules/read/dropEmptyColumns.js.map +1 -1
  114. package/modules/read/dropEmptyColumns.test.js.map +1 -1
  115. package/modules/read/dropEmptyRows.js +11 -22
  116. package/modules/read/dropEmptyRows.js.map +1 -1
  117. package/modules/read/dropEmptyRows.test.js.map +1 -1
  118. package/modules/read/getData.js +31 -39
  119. package/modules/read/getData.js.map +1 -1
  120. package/modules/read/isDateTimestamp.js +52 -39
  121. package/modules/read/isDateTimestamp.js.map +1 -1
  122. package/modules/read/parseCell.js +6 -6
  123. package/modules/read/parseCell.js.map +1 -1
  124. package/modules/read/parseCellValue.js +30 -55
  125. package/modules/read/parseCellValue.js.map +1 -1
  126. package/modules/read/parseCells.js +3 -3
  127. package/modules/read/parseCells.js.map +1 -1
  128. package/modules/read/parseDate.js +5 -4
  129. package/modules/read/parseDate.js.map +1 -1
  130. package/modules/read/parseDate.test.js.map +1 -1
  131. package/modules/read/parseDimensions.js +9 -17
  132. package/modules/read/parseDimensions.js.map +1 -1
  133. package/modules/read/parseFilePaths.js +5 -10
  134. package/modules/read/parseFilePaths.js.map +1 -1
  135. package/modules/read/parseProperties.js +8 -7
  136. package/modules/read/parseProperties.js.map +1 -1
  137. package/modules/read/parseSharedStrings.js +0 -1
  138. package/modules/read/parseSharedStrings.js.map +1 -1
  139. package/modules/read/parseSheet.js +3 -2
  140. package/modules/read/parseSheet.js.map +1 -1
  141. package/modules/read/parseStyles.js +16 -21
  142. package/modules/read/parseStyles.js.map +1 -1
  143. package/modules/read/readSheetNamesBrowser.js +1 -1
  144. package/modules/read/readSheetNamesBrowser.js.map +1 -1
  145. package/modules/read/readSheetNamesNode.js +1 -1
  146. package/modules/read/readSheetNamesNode.js.map +1 -1
  147. package/modules/read/readSheetNamesNode.test.js.map +1 -1
  148. package/modules/read/readSheetNamesWebWorker.js +1 -1
  149. package/modules/read/readSheetNamesWebWorker.js.map +1 -1
  150. package/modules/read/readXlsx.js +37 -35
  151. package/modules/read/readXlsx.js.map +1 -1
  152. package/modules/read/readXlsxFileBrowser.js +1 -1
  153. package/modules/read/readXlsxFileBrowser.js.map +1 -1
  154. package/modules/read/readXlsxFileContents.js +12 -17
  155. package/modules/read/readXlsxFileContents.js.map +1 -1
  156. package/modules/read/readXlsxFileNode.js +1 -1
  157. package/modules/read/readXlsxFileNode.js.map +1 -1
  158. package/modules/read/readXlsxFileNode.test.js.map +1 -1
  159. package/modules/read/readXlsxFileWebWorker.js +1 -1
  160. package/modules/read/readXlsxFileWebWorker.js.map +1 -1
  161. package/modules/read/schema/convertMapToSchema.js +1 -7
  162. package/modules/read/schema/convertMapToSchema.js.map +1 -1
  163. package/modules/read/schema/convertMapToSchema.test.js.map +1 -1
  164. package/modules/read/schema/convertToJson.js +143 -133
  165. package/modules/read/schema/convertToJson.js.map +1 -1
  166. package/modules/read/schema/convertToJson.legacy.js +53 -0
  167. package/modules/read/schema/convertToJson.legacy.js.map +1 -0
  168. package/modules/read/schema/convertToJson.legacy.test.js.map +1 -0
  169. package/modules/read/schema/convertToJson.spreadsheet.js +19 -0
  170. package/modules/read/schema/convertToJson.spreadsheet.js.map +1 -0
  171. package/modules/read/schema/convertToJson.spreadsheet.test.js.map +1 -0
  172. package/modules/read/schema/convertToJson.test.js.map +1 -1
  173. package/modules/read/unpackXlsxFileBrowser.js +4 -7
  174. package/modules/read/unpackXlsxFileBrowser.js.map +1 -1
  175. package/modules/read/unpackXlsxFileNode.js +9 -7
  176. package/modules/read/unpackXlsxFileNode.js.map +1 -1
  177. package/modules/types/Boolean.js +0 -1
  178. package/modules/types/Boolean.js.map +1 -1
  179. package/modules/types/Date.js +0 -8
  180. package/modules/types/Date.js.map +1 -1
  181. package/modules/types/Email.js +0 -2
  182. package/modules/types/Email.js.map +1 -1
  183. package/modules/types/Email.test.js.map +1 -1
  184. package/modules/types/Integer.js +0 -2
  185. package/modules/types/Integer.js.map +1 -1
  186. package/modules/types/Integer.test.js.map +1 -1
  187. package/modules/types/InvalidError.js +7 -25
  188. package/modules/types/InvalidError.js.map +1 -1
  189. package/modules/types/Number.js +2 -7
  190. package/modules/types/Number.js.map +1 -1
  191. package/modules/types/String.js +4 -8
  192. package/modules/types/String.js.map +1 -1
  193. package/modules/types/URL.js +5 -4
  194. package/modules/types/URL.js.map +1 -1
  195. package/modules/types/URL.test.js.map +1 -1
  196. package/modules/xml/dom.js +6 -18
  197. package/modules/xml/dom.js.map +1 -1
  198. package/modules/xml/xlsx.js +4 -13
  199. package/modules/xml/xlsx.js.map +1 -1
  200. package/modules/xml/xml.js.map +1 -1
  201. package/modules/xml/xmlBrowser.js.map +1 -1
  202. package/modules/xml/xpath/xlsx-xpath.js +2 -1
  203. package/modules/xml/xpath/xlsx-xpath.js.map +1 -1
  204. package/modules/xml/xpath/xpathBrowser.js +3 -4
  205. package/modules/xml/xpath/xpathBrowser.js.map +1 -1
  206. package/modules/xml/xpath/xpathNode.js +1 -0
  207. package/modules/xml/xpath/xpathNode.js.map +1 -1
  208. package/package.json +6 -1
  209. package/schema/index.cjs +2 -2
  210. package/schema/index.cjs.js +2 -2
  211. package/schema/index.d.ts +7 -2
  212. package/schema/index.js +1 -1
  213. package/types.d.ts +25 -2
@@ -7,186 +7,195 @@ exports["default"] = _default;
7
7
  exports.getBlock = getBlock;
8
8
  exports.parseArray = parseArray;
9
9
  exports.parseValue = parseValue;
10
-
11
10
  var _Number = _interopRequireDefault(require("../../types/Number.js"));
12
-
13
11
  var _String = _interopRequireDefault(require("../../types/String.js"));
14
-
15
12
  var _Boolean = _interopRequireDefault(require("../../types/Boolean.js"));
16
-
17
13
  var _Date = _interopRequireDefault(require("../../types/Date.js"));
18
-
19
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
20
-
21
15
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
22
-
23
16
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
24
-
25
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
26
-
17
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
27
18
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
28
-
29
- function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
30
-
19
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
31
20
  function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
32
-
33
21
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
34
-
35
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
36
-
37
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
38
-
39
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
40
-
41
- 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; }
42
-
22
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
23
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
24
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
25
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
26
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
27
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
43
28
  var DEFAULT_OPTIONS = {
44
- isColumnOriented: false
29
+ schemaPropertyValueForMissingColumn: undefined,
30
+ schemaPropertyValueForUndefinedCellValue: undefined,
31
+ schemaPropertyValueForNullCellValue: null,
32
+ schemaPropertyShouldSkipRequiredValidationForMissingColumn: function schemaPropertyShouldSkipRequiredValidationForMissingColumn() {
33
+ return false;
34
+ },
35
+ // `getEmptyObjectValue(object, { path })` applies to both the top-level object
36
+ // and any of its sub-objects.
37
+ getEmptyObjectValue: function getEmptyObjectValue() {
38
+ return null;
39
+ },
40
+ getEmptyArrayValue: function getEmptyArrayValue() {
41
+ return null;
42
+ },
43
+ isColumnOriented: false,
44
+ arrayValueSeparator: ','
45
45
  };
46
+
46
47
  /**
47
- * Convert 2D array to nested objects.
48
- * If row oriented data, row 0 is dotted key names.
49
- * Column oriented data is transposed.
48
+ * (this function is exported from `read-excel-file/map`)
49
+ * Converts spreadsheet-alike data structure into an array of objects.
50
+ * The first row should be the list of column headers.
50
51
  * @param {any[][]} data - An array of rows, each row being an array of cells.
51
52
  * @param {object} schema
53
+ * @param {object} [options]
54
+ * @param {null} [options.schemaPropertyValueForMissingColumn] — By default, when some of the `schema` columns are missing in the input `data`, those properties are set to `undefined` in the output objects. Pass `schemaPropertyValueForMissingColumn: null` to set such "missing column" properties to `null` in the output objects.
55
+ * @param {null} [options.schemaPropertyValueForNullCellValue] — By default, when it encounters a `null` value in a cell in input `data`, it sets it to `undefined` in the output object. Pass `schemaPropertyValueForNullCellValue: null` to make it set such values as `null`s in output objects.
56
+ * @param {null} [options.schemaPropertyValueForUndefinedCellValue] — By default, when it encounters an `undefined` value in a cell in input `data`, it it sets it to `undefined` in the output object. Pass `schemaPropertyValueForUndefinedCellValue: null` to make it set such values as `null`s in output objects.
57
+ * @param {boolean} [options.schemaPropertyShouldSkipRequiredValidationForMissingColumn(column: string, { object })] — By default, it does apply `required` validation to `schema` properties for which columns are missing in the input `data`. One could pass a custom `schemaPropertyShouldSkipRequiredValidationForMissingColumn(column, { object })` to disable `required` validation for missing columns in some or all cases.
58
+ * @param {function} [options.getEmptyObjectValue(object, { path })] — By default, it returns `null` for an "empty" resulting object. One could override that value using `getEmptyObjectValue(object, { path })` parameter. The value applies to both top-level object and any nested sub-objects in case of a nested schema, hence the additional `path?: string` parameter.
59
+ * @param {function} [getEmptyArrayValue(array, { path })] — By default, it returns `null` for an "empty" array value. One could override that value using `getEmptyArrayValue(array, { path })` parameter.
60
+ * @param {boolean} [options.isColumnOriented] — By default, the headers are assumed to be the first row in the `data`. Pass `isColumnOriented: true` if the headers are the first column in the `data`. i.e. if `data` is "transposed".
61
+ * @param {object} [options.rowIndexMap] — Custom row index mapping `data` rows. If present, will overwrite the indexes of `data` rows with the indexes from this `rowIndexMap`.
52
62
  * @return {object[]}
53
63
  */
54
-
55
64
  function _default(data, schema, options) {
56
65
  if (options) {
57
66
  options = _objectSpread(_objectSpread({}, DEFAULT_OPTIONS), options);
58
67
  } else {
59
68
  options = DEFAULT_OPTIONS;
60
69
  }
61
-
62
70
  var _options = options,
63
- isColumnOriented = _options.isColumnOriented,
64
- rowMap = _options.rowMap,
65
- ignoreEmptyRows = _options.ignoreEmptyRows;
71
+ isColumnOriented = _options.isColumnOriented,
72
+ rowIndexMap = _options.rowIndexMap;
66
73
  validateSchema(schema);
67
-
68
74
  if (isColumnOriented) {
69
75
  data = transpose(data);
70
76
  }
71
-
72
77
  var columns = data[0];
73
78
  var results = [];
74
79
  var errors = [];
75
-
76
80
  for (var i = 1; i < data.length; i++) {
77
- var result = read(schema, data[i], i, columns, errors, options);
78
-
79
- if (result !== null || ignoreEmptyRows === false) {
80
- results.push(result);
81
- }
82
- } // Correct error rows.
83
-
81
+ var result = read(schema, data[i], i, undefined, columns, errors, options);
82
+ results.push(result);
83
+ }
84
84
 
85
- if (rowMap) {
85
+ // Set the correct `row` number in `errors` if a custom `rowIndexMap` is supplied.
86
+ if (rowIndexMap) {
86
87
  for (var _iterator = _createForOfIteratorHelperLoose(errors), _step; !(_step = _iterator()).done;) {
87
88
  var error = _step.value;
88
89
  // Convert the `row` index in `data` to the
89
90
  // actual `row` index in the spreadsheet.
90
91
  // `- 1` converts row number to row index.
91
92
  // `+ 1` converts row index to row number.
92
- error.row = rowMap[error.row - 1] + 1;
93
+ error.row = rowIndexMap[error.row - 1] + 1;
93
94
  }
94
95
  }
95
-
96
96
  return {
97
97
  rows: results,
98
98
  errors: errors
99
99
  };
100
100
  }
101
-
102
- function read(schema, row, rowIndex, columns, errors, options) {
101
+ function read(schema, row, rowIndex, path, columns, errors, options) {
103
102
  var object = {};
104
103
  var isEmptyObject = true;
105
-
106
104
  var createError = function createError(_ref) {
107
105
  var column = _ref.column,
108
- value = _ref.value,
109
- errorMessage = _ref.error,
110
- reason = _ref.reason;
106
+ value = _ref.value,
107
+ errorMessage = _ref.error,
108
+ reason = _ref.reason;
111
109
  var error = {
112
110
  error: errorMessage,
113
111
  row: rowIndex + 1,
114
112
  column: column,
115
113
  value: value
116
114
  };
117
-
118
115
  if (reason) {
119
116
  error.reason = reason;
120
117
  }
121
-
122
118
  if (schema[column].type) {
123
119
  error.type = schema[column].type;
124
120
  }
125
-
126
121
  return error;
127
122
  };
128
-
129
123
  var pendingRequiredChecks = [];
130
124
 
125
+ // For each schema entry.
131
126
  var _loop = function _loop() {
132
127
  var key = _Object$keys[_i];
133
128
  var schemaEntry = schema[key];
134
129
  var isNestedSchema = _typeof(schemaEntry.type) === 'object' && !Array.isArray(schemaEntry.type);
135
- var rawValue = row[columns.indexOf(key)];
136
130
 
137
- if (rawValue === undefined) {
138
- rawValue = null;
139
- }
131
+ // The path of this property inside the resulting object.
132
+ var propertyPath = "".concat(path || '', ".").concat(schemaEntry.prop);
140
133
 
141
- var value = void 0;
142
- var error = void 0;
143
- var reason = void 0;
134
+ // Read the cell value for the schema entry.
135
+ var cellValue;
136
+ var columnIndex = columns.indexOf(key);
137
+ var isMissingColumn = columnIndex < 0;
138
+ if (!isMissingColumn) {
139
+ cellValue = row[columnIndex];
140
+ }
141
+ var value;
142
+ var error;
143
+ var reason;
144
144
 
145
+ // Get property `value` from cell value.
145
146
  if (isNestedSchema) {
146
- value = read(schemaEntry.type, row, rowIndex, columns, errors, options);
147
+ value = read(schemaEntry.type, row, rowIndex, propertyPath, columns, errors, options);
147
148
  } else {
148
- if (rawValue === null) {
149
- value = null;
149
+ if (isMissingColumn) {
150
+ value = options.schemaPropertyValueForMissingColumn;
151
+ } else if (cellValue === undefined) {
152
+ value = options.schemaPropertyValueForUndefinedCellValue;
153
+ } else if (cellValue === null) {
154
+ value = options.schemaPropertyValueForNullCellValue;
150
155
  } else if (Array.isArray(schemaEntry.type)) {
151
- var notEmpty = false;
152
- var array = parseArray(rawValue).map(function (_value) {
156
+ var array = parseArray(cellValue, options.arrayValueSeparator).map(function (_value) {
157
+ if (error) {
158
+ return;
159
+ }
153
160
  var result = parseValue(_value, schemaEntry, options);
154
-
155
161
  if (result.error) {
162
+ // In case of an error, `value` won't be returned and will just be reported
163
+ // as part of an `error` object, so it's fine assigning just an element of the array.
156
164
  value = _value;
157
165
  error = result.error;
158
166
  reason = result.reason;
159
167
  }
160
-
161
- if (result.value !== null) {
162
- notEmpty = true;
163
- }
164
-
165
168
  return result.value;
166
169
  });
167
-
168
170
  if (!error) {
169
- value = notEmpty ? array : null;
171
+ var isEmpty = array.every(isEmptyValue);
172
+ value = isEmpty ? options.getEmptyArrayValue(array, {
173
+ path: propertyPath
174
+ }) : array;
170
175
  }
171
176
  } else {
172
- var result = parseValue(rawValue, schemaEntry, options);
177
+ var result = parseValue(cellValue, schemaEntry, options);
173
178
  error = result.error;
174
179
  reason = result.reason;
175
- value = error ? rawValue : result.value;
180
+ value = error ? cellValue : result.value;
176
181
  }
177
182
  }
178
183
 
179
- if (!error && value === null) {
180
- if (typeof schemaEntry.required === 'function') {
184
+ // Apply `required` validation if the value is "empty".
185
+ if (!error && isEmptyValue(value)) {
186
+ if (schemaEntry.required) {
187
+ // Will perform this `required()` validation in the end,
188
+ // when all properties of the mapped object have been mapped.
181
189
  pendingRequiredChecks.push({
182
- column: key
190
+ column: key,
191
+ value: value,
192
+ isMissingColumn: isMissingColumn
183
193
  });
184
- } else if (schemaEntry.required === true) {
185
- error = 'required';
186
194
  }
187
195
  }
188
-
189
196
  if (error) {
197
+ // If there was an error then the property value in the `object` will be `undefined`,
198
+ // i.e it won't add the property value to the mapped object.
190
199
  errors.push(createError({
191
200
  column: key,
192
201
  value: value,
@@ -194,60 +203,73 @@ function read(schema, row, rowIndex, columns, errors, options) {
194
203
  reason: reason
195
204
  }));
196
205
  } else {
197
- if (isEmptyObject && value !== null) {
206
+ // Possibly unmark the mapped object as "empty".
207
+ if (isEmptyObject && !isEmptyValue(value)) {
198
208
  isEmptyObject = false;
199
209
  }
200
-
201
- if (value !== null || options.includeNullValues) {
210
+ // Set the value in the mapped object.
211
+ // Skip setting `undefined` values because they're already `undefined`.
212
+ if (value !== undefined) {
202
213
  object[schemaEntry.prop] = value;
203
214
  }
204
215
  }
205
216
  };
206
-
207
217
  for (var _i = 0, _Object$keys = Object.keys(schema); _i < _Object$keys.length; _i++) {
208
218
  _loop();
209
219
  }
210
220
 
221
+ // Return `null` for an "empty" mapped object.
211
222
  if (isEmptyObject) {
212
- return null;
223
+ return options.getEmptyObjectValue(object, {
224
+ path: path
225
+ });
213
226
  }
214
227
 
228
+ // Perform any `required` validations.
215
229
  for (var _i2 = 0, _pendingRequiredCheck = pendingRequiredChecks; _i2 < _pendingRequiredCheck.length; _i2++) {
216
- var column = _pendingRequiredCheck[_i2].column;
217
- var required = schema[column].required(object);
218
-
219
- if (required) {
220
- errors.push(createError({
221
- column: column,
222
- value: null,
223
- error: 'required'
224
- }));
230
+ var _pendingRequiredCheck2 = _pendingRequiredCheck[_i2],
231
+ column = _pendingRequiredCheck2.column,
232
+ value = _pendingRequiredCheck2.value,
233
+ isMissingColumn = _pendingRequiredCheck2.isMissingColumn;
234
+ // Can optionally skip `required` validation for missing columns.
235
+ var skipRequiredValidation = isMissingColumn && options.schemaPropertyShouldSkipRequiredValidationForMissingColumn(column, {
236
+ object: object
237
+ });
238
+ if (!skipRequiredValidation) {
239
+ var required = schema[column].required;
240
+ var isRequired = typeof required === 'boolean' ? required : required(object);
241
+ if (isRequired) {
242
+ errors.push(createError({
243
+ column: column,
244
+ value: value,
245
+ error: 'required'
246
+ }));
247
+ }
225
248
  }
226
249
  }
227
250
 
251
+ // Return the mapped object.
228
252
  return object;
229
253
  }
254
+
230
255
  /**
231
256
  * Converts textual value to a javascript typed value.
232
257
  * @param {any} value
233
258
  * @param {object} schemaEntry
234
259
  * @return {{ value: any, error: string }}
235
260
  */
236
-
237
-
238
261
  function parseValue(value, schemaEntry, options) {
239
262
  if (value === null) {
240
263
  return {
241
264
  value: null
242
265
  };
243
266
  }
244
-
245
267
  var result;
246
-
247
268
  if (schemaEntry.parse) {
248
269
  result = parseCustomValue(value, schemaEntry.parse);
249
270
  } else if (schemaEntry.type) {
250
- result = parseValueOfType(value, // Supports parsing array types.
271
+ result = parseValueOfType(value,
272
+ // Supports parsing array types.
251
273
  // See `parseArray()` function for more details.
252
274
  // Example `type`: String[]
253
275
  // Input: 'Barack Obama, "String, with, colons", Donald Trump'
@@ -256,14 +278,13 @@ function parseValue(value, schemaEntry, options) {
256
278
  } else {
257
279
  result = {
258
280
  value: value
259
- }; // throw new Error('Invalid schema entry: no .type and no .parse():\n\n' + JSON.stringify(schemaEntry, null, 2))
260
- } // If errored then return the error.
261
-
262
-
281
+ };
282
+ // throw new Error('Invalid schema entry: no .type and no .parse():\n\n' + JSON.stringify(schemaEntry, null, 2))
283
+ }
284
+ // If errored then return the error.
263
285
  if (result.error) {
264
286
  return result;
265
287
  }
266
-
267
288
  if (result.value !== null) {
268
289
  if (schemaEntry.oneOf && schemaEntry.oneOf.indexOf(result.value) < 0) {
269
290
  return {
@@ -271,7 +292,6 @@ function parseValue(value, schemaEntry, options) {
271
292
  reason: 'unknown'
272
293
  };
273
294
  }
274
-
275
295
  if (schemaEntry.validate) {
276
296
  try {
277
297
  schemaEntry.validate(result.value);
@@ -282,27 +302,23 @@ function parseValue(value, schemaEntry, options) {
282
302
  }
283
303
  }
284
304
  }
285
-
286
305
  return result;
287
306
  }
307
+
288
308
  /**
289
309
  * Converts textual value to a custom value using supplied `.parse()`.
290
310
  * @param {any} value
291
311
  * @param {function} parse
292
312
  * @return {{ value: any, error: string }}
293
313
  */
294
-
295
-
296
314
  function parseCustomValue(value, parse) {
297
315
  try {
298
316
  value = parse(value);
299
-
300
317
  if (value === undefined) {
301
318
  return {
302
319
  value: null
303
320
  };
304
321
  }
305
-
306
322
  return {
307
323
  value: value
308
324
  };
@@ -310,57 +326,46 @@ function parseCustomValue(value, parse) {
310
326
  var result = {
311
327
  error: error.message
312
328
  };
313
-
314
329
  if (error.reason) {
315
330
  result.reason = error.reason;
316
331
  }
317
-
318
332
  return result;
319
333
  }
320
334
  }
335
+
321
336
  /**
322
337
  * Converts textual value to a javascript typed value.
323
338
  * @param {any} value
324
339
  * @param {} type
325
340
  * @return {{ value: (string|number|Date|boolean), error: string, reason?: string }}
326
341
  */
327
-
328
-
329
342
  function parseValueOfType(value, type, options) {
330
343
  switch (type) {
331
344
  case String:
332
345
  return parseCustomValue(value, _String["default"]);
333
-
334
346
  case Number:
335
347
  return parseCustomValue(value, _Number["default"]);
336
-
337
348
  case Date:
338
349
  return parseCustomValue(value, function (value) {
339
350
  return (0, _Date["default"])(value, {
340
351
  properties: options.properties
341
352
  });
342
353
  });
343
-
344
354
  case Boolean:
345
355
  return parseCustomValue(value, _Boolean["default"]);
346
-
347
356
  default:
348
357
  if (typeof type === 'function') {
349
358
  return parseCustomValue(value, type);
350
359
  }
351
-
352
360
  throw new Error("Unsupported schema type: ".concat(type && type.name || type));
353
361
  }
354
362
  }
355
-
356
363
  function getBlock(string, endCharacter, startIndex) {
357
364
  var i = 0;
358
365
  var substring = '';
359
366
  var character;
360
-
361
367
  while (startIndex + i < string.length) {
362
368
  var _character = string[startIndex + i];
363
-
364
369
  if (_character === endCharacter) {
365
370
  return [substring, i];
366
371
  } else if (_character === '"') {
@@ -372,36 +377,31 @@ function getBlock(string, endCharacter, startIndex) {
372
377
  i++;
373
378
  }
374
379
  }
375
-
376
380
  return [substring, i];
377
381
  }
382
+
378
383
  /**
379
384
  * Parses a string of comma-separated substrings into an array of substrings.
380
385
  * (the `export` is just for tests)
381
386
  * @param {string} string — A string of comma-separated substrings.
382
387
  * @return {string[]} An array of substrings.
383
388
  */
384
-
385
-
386
- function parseArray(string) {
389
+ function parseArray(string, arrayValueSeparator) {
387
390
  var blocks = [];
388
391
  var index = 0;
389
-
390
392
  while (index < string.length) {
391
- var _getBlock = getBlock(string, ',', index),
392
- _getBlock2 = _slicedToArray(_getBlock, 2),
393
- substring = _getBlock2[0],
394
- length = _getBlock2[1];
395
-
396
- index += length + ','.length;
393
+ var _getBlock = getBlock(string, arrayValueSeparator, index),
394
+ _getBlock2 = _slicedToArray(_getBlock, 2),
395
+ substring = _getBlock2[0],
396
+ length = _getBlock2[1];
397
+ index += length + arrayValueSeparator.length;
397
398
  blocks.push(substring.trim());
398
399
  }
399
-
400
400
  return blocks;
401
- } // Transpose a 2D array.
402
- // https://stackoverflow.com/questions/17428587/transposing-a-2d-array-in-javascript
403
-
401
+ }
404
402
 
403
+ // Transpose a 2D array.
404
+ // https://stackoverflow.com/questions/17428587/transposing-a-2d-array-in-javascript
405
405
  var transpose = function transpose(array) {
406
406
  return array[0].map(function (_, i) {
407
407
  return array.map(function (row) {
@@ -409,15 +409,16 @@ var transpose = function transpose(array) {
409
409
  });
410
410
  });
411
411
  };
412
-
413
412
  function validateSchema(schema) {
414
413
  for (var _i3 = 0, _Object$keys2 = Object.keys(schema); _i3 < _Object$keys2.length; _i3++) {
415
414
  var key = _Object$keys2[_i3];
416
415
  var entry = schema[key];
417
-
418
416
  if (!entry.prop) {
419
417
  throw new Error("\"prop\" not defined for schema entry \"".concat(key, "\"."));
420
418
  }
421
419
  }
422
420
  }
421
+ function isEmptyValue(value) {
422
+ return value === undefined || value === null;
423
+ }
423
424
  //# sourceMappingURL=convertToJson.js.map