1 |
|
2 |
|
3 |
|
4 | const MIME_MAP = [
|
5 | { type: 'text/plain', ext: 'txt' },
|
6 | { type: 'text/html', ext: 'html' },
|
7 | { type: 'text/javascript', ext: 'js' },
|
8 | { type: 'text/css', ext: 'css' },
|
9 | { type: 'text/csv', ext: 'csv' },
|
10 | { type: 'text/yaml', ext: 'yml' },
|
11 | { type: 'text/yaml', ext: 'yaml' },
|
12 | { type: 'text/calendar', ext: 'ics' },
|
13 | { type: 'text/calendar', ext: 'ical' },
|
14 |
|
15 | { type: 'image/apng', ext: 'apng' },
|
16 | { type: 'image/bmp', ext: 'bmp' },
|
17 | { type: 'image/gif', ext: 'gif' },
|
18 | { type: 'image/x-icon', ext: 'ico' },
|
19 | { type: 'image/x-icon', ext: 'cur' },
|
20 | { type: 'image/jpeg', ext: 'jpg' },
|
21 | { type: 'image/jpeg', ext: 'jpeg' },
|
22 | { type: 'image/jpeg', ext: 'jfif' },
|
23 | { type: 'image/jpeg', ext: 'pjp' },
|
24 | { type: 'image/jpeg', ext: 'pjpeg' },
|
25 | { type: 'image/png', ext: 'png' },
|
26 | { type: 'image/svg+xml', ext: 'svg' },
|
27 | { type: 'image/tiff', ext: 'tif' },
|
28 | { type: 'image/tiff', ext: 'tiff' },
|
29 | { type: 'image/webp', ext: 'webp' },
|
30 |
|
31 | { type: 'application/json', ext: 'json' },
|
32 | { type: 'application/xml', ext: 'xml' },
|
33 | { type: 'application/x-sh', ext: 'sh' },
|
34 | { type: 'application/zip', ext: 'zip' },
|
35 | { type: 'application/x-rar-compressed', ext: 'rar' },
|
36 | { type: 'application/x-tar', ext: 'tar' },
|
37 | { type: 'application/x-bzip', ext: 'bz' },
|
38 | { type: 'application/x-bzip2', ext: 'bz2' },
|
39 | { type: 'application/pdf', ext: 'pdf' },
|
40 | { type: 'application/java-archive', ext: 'jar' },
|
41 | { type: 'application/msword', ext: 'doc' },
|
42 | { type: 'application/vnd.ms-excel', ext: 'xls' },
|
43 | { type: 'application/vnd.ms-excel', ext: 'xlsx' },
|
44 |
|
45 | { type: 'message/rfc822', ext: 'eml' },
|
46 | ];
|
47 |
|
48 | export const isEmpty = (obj = {}) => Object.keys(obj).length === 0;
|
49 |
|
50 | export const sortByField = (list, field, dir) => {
|
51 | if (!list || !list.sort) {
|
52 | return false;
|
53 | }
|
54 |
|
55 | const dirX = dir && dir === 'desc' ? -1 : 1;
|
56 | list.sort(function(a, b) {
|
57 | const a_val = a[field];
|
58 | const b_val = b[field];
|
59 |
|
60 | if (typeof b_val === 'undefined') {
|
61 | return typeof a_val === 'undefined' ? 0 : 1 * dirX;
|
62 | }
|
63 |
|
64 | if (typeof a_val === 'undefined') {
|
65 | return -1 * dirX;
|
66 | }
|
67 |
|
68 | if (a_val < b_val) {
|
69 | return -1 * dirX;
|
70 | }
|
71 | if (a_val > b_val) {
|
72 | return 1 * dirX;
|
73 | }
|
74 |
|
75 | return 0;
|
76 | });
|
77 |
|
78 | return true;
|
79 | };
|
80 |
|
81 | export const objectLessAttributes = (obj, less) => {
|
82 | const ret = Object.assign({}, obj);
|
83 | if (less) {
|
84 | if (typeof less === 'string') {
|
85 | delete ret[less];
|
86 | } else {
|
87 | less.forEach(attr => {
|
88 | delete ret[attr];
|
89 | });
|
90 | }
|
91 | }
|
92 |
|
93 | return ret;
|
94 | };
|
95 |
|
96 | export const filenameToContentType = (
|
97 | filename,
|
98 | defVal = 'application/octet-stream'
|
99 | ) => {
|
100 | const name = filename.toLowerCase();
|
101 |
|
102 | const filtered = MIME_MAP.filter(mime => name.endsWith('.' + mime.ext));
|
103 | return filtered.length > 0 ? filtered[0].type : defVal;
|
104 | };
|
105 |
|
106 | export const isTextFile = contentType => {
|
107 | const type = contentType.toLowerCase();
|
108 | if (type.startsWith('text/')) {
|
109 | return true;
|
110 | }
|
111 | return (
|
112 | 'application/json' === type ||
|
113 | 'application/xml' === type ||
|
114 | 'application/sh' === type
|
115 | );
|
116 | };
|
117 |
|
118 | export const generateRandomString = () => {
|
119 | let result = '';
|
120 | const chars =
|
121 | '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
122 | for (let i = 32; i > 0; i -= 1) {
|
123 | result += chars[Math.floor(Math.random() * chars.length)];
|
124 | }
|
125 | return result;
|
126 | };
|
127 |
|
128 | export const makeQuerablePromise = promise => {
|
129 | if (promise.isResolved) return promise;
|
130 |
|
131 | let isPending = true;
|
132 | let isRejected = false;
|
133 | let isFullfilled = false;
|
134 |
|
135 | const result = promise.then(
|
136 | data => {
|
137 | isFullfilled = true;
|
138 | isPending = false;
|
139 | return data;
|
140 | },
|
141 | e => {
|
142 | isRejected = true;
|
143 | isPending = false;
|
144 | throw e;
|
145 | }
|
146 | );
|
147 |
|
148 | result.isFullfilled = () => isFullfilled;
|
149 | result.isPending = () => isPending;
|
150 | result.isRejected = () => isRejected;
|
151 |
|
152 | return result;
|
153 | };
|
154 |
|
155 | export const isWebWorker = () => {
|
156 | if (typeof self === 'undefined') {
|
157 | return false;
|
158 | }
|
159 | const selfContext = self as { WorkerGlobalScope? };
|
160 | return (
|
161 | typeof selfContext.WorkerGlobalScope !== 'undefined' &&
|
162 | self instanceof selfContext.WorkerGlobalScope
|
163 | );
|
164 | };
|
165 |
|
166 | export const browserOrNode = () => {
|
167 | const isBrowser =
|
168 | typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
169 | const isNode =
|
170 | typeof process !== 'undefined' &&
|
171 | process.versions != null &&
|
172 | process.versions.node != null;
|
173 |
|
174 | return {
|
175 | isBrowser,
|
176 | isNode,
|
177 | };
|
178 | };
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 |
|
185 |
|
186 | export const transferKeyToLowerCase = (
|
187 | obj,
|
188 | whiteListForItself = [],
|
189 | whiteListForChildren = []
|
190 | ) => {
|
191 | if (!isStrictObject(obj)) return obj;
|
192 | const ret = {};
|
193 |
|
194 | for (const key in obj) {
|
195 | if (obj.hasOwnProperty(key)) {
|
196 | const transferedKey = whiteListForItself.includes(key)
|
197 | ? key
|
198 | : key[0].toLowerCase() + key.slice(1);
|
199 |
|
200 | ret[transferedKey] = whiteListForChildren.includes(key)
|
201 | ? obj[key]
|
202 | : transferKeyToLowerCase(
|
203 | obj[key],
|
204 | whiteListForItself,
|
205 | whiteListForChildren
|
206 | );
|
207 | }
|
208 | }
|
209 |
|
210 | return ret;
|
211 | };
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 | export const transferKeyToUpperCase = (
|
220 | obj,
|
221 | whiteListForItself = [],
|
222 | whiteListForChildren = []
|
223 | ) => {
|
224 | if (!isStrictObject(obj)) return obj;
|
225 | const ret = {};
|
226 |
|
227 | for (const key in obj) {
|
228 | if (obj.hasOwnProperty(key)) {
|
229 | const transferredKey = whiteListForItself.includes(key)
|
230 | ? key
|
231 | : key[0].toUpperCase() + key.slice(1);
|
232 |
|
233 | ret[transferredKey] = whiteListForChildren.includes(key)
|
234 | ? obj[key]
|
235 | : transferKeyToUpperCase(
|
236 | obj[key],
|
237 | whiteListForItself,
|
238 | whiteListForChildren
|
239 | );
|
240 | }
|
241 | }
|
242 | return ret;
|
243 | };
|
244 |
|
245 |
|
246 |
|
247 |
|
248 |
|
249 |
|
250 | export const isStrictObject = obj => {
|
251 | return (
|
252 | obj instanceof Object &&
|
253 | !(obj instanceof Array) &&
|
254 | !(obj instanceof Function) &&
|
255 | !(obj instanceof Number) &&
|
256 | !(obj instanceof String) &&
|
257 | !(obj instanceof Boolean)
|
258 | );
|
259 | };
|