1 | "use strict";
|
2 |
|
3 | const fs = require("./utils/fs");
|
4 | const validate = require("./utils/validate");
|
5 |
|
6 | const supportedReturnAs = ["utf8", "buffer", "json", "jsonWithDates"];
|
7 |
|
8 | const validateInput = (methodName, path, returnAs) => {
|
9 | const methodSignature = `${methodName}(path, returnAs)`;
|
10 | validate.argument(methodSignature, "path", path, ["string"]);
|
11 | validate.argument(methodSignature, "returnAs", returnAs, [
|
12 | "string",
|
13 | "undefined"
|
14 | ]);
|
15 |
|
16 | if (returnAs && supportedReturnAs.indexOf(returnAs) === -1) {
|
17 | throw new Error(
|
18 | `Argument "returnAs" passed to ${methodSignature} must have one of values: ${supportedReturnAs.join(
|
19 | ", "
|
20 | )}`
|
21 | );
|
22 | }
|
23 | };
|
24 |
|
25 |
|
26 |
|
27 | const jsonDateParser = (key, value) => {
|
28 | const reISO = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/;
|
29 | if (typeof value === "string") {
|
30 | if (reISO.exec(value)) {
|
31 | return new Date(value);
|
32 | }
|
33 | }
|
34 | return value;
|
35 | };
|
36 |
|
37 | const makeNicerJsonParsingError = (path, err) => {
|
38 | const nicerError = new Error(
|
39 | `JSON parsing failed while reading ${path} [${err}]`
|
40 | );
|
41 | nicerError.originalError = err;
|
42 | return nicerError;
|
43 | };
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | const readSync = (path, returnAs) => {
|
50 | const retAs = returnAs || "utf8";
|
51 | let data;
|
52 |
|
53 | let encoding = "utf8";
|
54 | if (retAs === "buffer") {
|
55 | encoding = null;
|
56 | }
|
57 |
|
58 | try {
|
59 | data = fs.readFileSync(path, { encoding });
|
60 | } catch (err) {
|
61 | if (err.code === "ENOENT") {
|
62 |
|
63 | return undefined;
|
64 | }
|
65 |
|
66 | throw err;
|
67 | }
|
68 |
|
69 | try {
|
70 | if (retAs === "json") {
|
71 | data = JSON.parse(data);
|
72 | } else if (retAs === "jsonWithDates") {
|
73 | data = JSON.parse(data, jsonDateParser);
|
74 | }
|
75 | } catch (err) {
|
76 | throw makeNicerJsonParsingError(path, err);
|
77 | }
|
78 |
|
79 | return data;
|
80 | };
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 | const readAsync = (path, returnAs) => {
|
87 | return new Promise((resolve, reject) => {
|
88 | const retAs = returnAs || "utf8";
|
89 | let encoding = "utf8";
|
90 | if (retAs === "buffer") {
|
91 | encoding = null;
|
92 | }
|
93 |
|
94 | fs.readFile(path, { encoding })
|
95 | .then(data => {
|
96 |
|
97 | try {
|
98 | if (retAs === "json") {
|
99 | resolve(JSON.parse(data));
|
100 | } else if (retAs === "jsonWithDates") {
|
101 | resolve(JSON.parse(data, jsonDateParser));
|
102 | } else {
|
103 | resolve(data);
|
104 | }
|
105 | } catch (err) {
|
106 | reject(makeNicerJsonParsingError(path, err));
|
107 | }
|
108 | })
|
109 | .catch(err => {
|
110 | if (err.code === "ENOENT") {
|
111 |
|
112 | resolve(undefined);
|
113 | } else {
|
114 |
|
115 | reject(err);
|
116 | }
|
117 | });
|
118 | });
|
119 | };
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | exports.validateInput = validateInput;
|
126 | exports.sync = readSync;
|
127 | exports.async = readAsync;
|