utilitas 1995.2.83 → 1995.2.85

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/lib/horizon.mjs CHANGED
@@ -6,6 +6,11 @@ RegExp.escape = RegExp.escape || (str => { //$& means the whole matched string
6
6
  return String(str).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
7
7
  }); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
8
8
 
9
+ // BigInt
10
+ BigInt.prototype.toJSON = BigInt.prototype.toJSON || function() {
11
+ return this.toString();
12
+ };
13
+
9
14
  // Assert
10
15
  import { default as asst } from 'assert';
11
16
  const _assert = asst || ((val, err) => {
package/lib/manifest.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  const manifest = {
2
2
  "name": "utilitas",
3
3
  "description": "Just another common utility for JavaScript.",
4
- "version": "1995.2.83",
4
+ "version": "1995.2.85",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/Leask/utilitas",
7
7
  "main": "index.mjs",
package/lib/storage.mjs CHANGED
@@ -12,7 +12,7 @@ import { homedir, tmpdir } from 'os';
12
12
  import { promisify } from 'util';
13
13
  import { v4 as uuidv4 } from 'uuid';
14
14
 
15
- const _NEED = ['mime-types', '@google-cloud/storage'];
15
+ const _NEED = ['file-type', 'mime-types', '@google-cloud/storage'];
16
16
  const errorMessage = 'Invalid file.';
17
17
  const defaultMetadata = { cacheControl: 'public, max-age=31536000' };
18
18
  const getGcUrlByBucket = bucket => `https://storage.cloud.google.com/${bucket}`;
@@ -24,11 +24,12 @@ const log = content => _log(content, import.meta.url);
24
24
  const sanitizeFilename = (s, r) => s.replace(/[\/?<>\\:*|"]/g, r || '_').trim();
25
25
 
26
26
  const [
27
- NULL, BASE64, BUFFER, FILE, STREAM, TEXT, _JSON, encoding, BINARY, mode,
28
- dirMode,
27
+ NULL, BASE64, BUFFER, FILE, STREAM, TEXT, _JSON, encoding, BINARY, BLOB,
28
+ DATAURL, mode, dirMode, MIME_TEXT, MIME_BINARY
29
29
  ] = [
30
30
  'NULL', 'BASE64', 'BUFFER', 'FILE', 'STREAM', 'TEXT', 'JSON', 'utf8',
31
- 'binary', '0644', '0755',
31
+ 'binary', 'BLOB', 'DATAURL', '0644', '0755', 'text/plain',
32
+ 'application/octet-stream',
32
33
  ];
33
34
 
34
35
  const [encodeBase64, encodeBinary, encodeNull]
@@ -161,7 +162,17 @@ const touchPath = async (path, options) => {
161
162
  const encodeBase64DataURL = (mime, buffer) => {
162
163
  assert((mime = trim(mime)), 'MIME type is required.', 400);
163
164
  assert(Buffer.isBuffer(buffer), 'Data buffer is required.', 400);
164
- return `data:${mime};${BASE64},${buffer.toString(BASE64)}`;
165
+ return `data:${mime};${BASE64},${base64Encode(buffer, true)}`;
166
+ };
167
+
168
+ const decodeBase64DataURL = dataUrl => {
169
+ const parts = dataUrl.split(',');
170
+ const mime = parts[0].match(/:(.*?);/)[1];
171
+ const binStr = atob(parts[1]);
172
+ const buffer = new ArrayBuffer(binStr.length);
173
+ const bfView = new Uint8Array(buffer);
174
+ for (let i = 0; i < binStr.length; i++) { bfView[i] = binStr.charCodeAt(i); }
175
+ return { mime, buffer: Buffer.from(buffer) };
165
176
  };
166
177
 
167
178
  // https://stackoverflow.com/questions/42210199/remove-illegal-characters-from-a-file-name-but-leave-spaces
@@ -203,6 +214,15 @@ const unzip = async (any, options) => {
203
214
  ), options);
204
215
  };
205
216
 
217
+ const blobToBuffer = async blob => {
218
+ const reader = new FileReader();
219
+ return new Promise((resolve, reject) => {
220
+ reader.onload = () => resolve(Buffer.from(reader.result));
221
+ reader.onerror = reject;
222
+ reader.readAsArrayBuffer(blob);
223
+ });
224
+ };
225
+
206
226
  const convert = async (any, options) => {
207
227
  assert(any, options?.errorMessage || 'Invalid input.', 400);
208
228
  const result = {}
@@ -210,19 +230,31 @@ const convert = async (any, options) => {
210
230
  (Buffer.isBuffer(any) || ArrayBuffer.isArrayBuffer(any))
211
231
  ? BUFFER : options?.input, options?.expected || BUFFER
212
232
  ].map(x => ensureString(x, { case: 'UP' }));
213
- let [oriFile, meta, subExp] = [null, null, expected];
233
+ let [oriFile, meta, mime, subExp] = [null, null, MIME_BINARY, expected];
214
234
  switch (input) {
215
235
  case FILE:
216
236
  oriFile = any;
217
237
  break;
218
238
  case TEXT:
219
239
  any = Buffer.from(any);
240
+ mime = MIME_TEXT;
241
+ input = BUFFER;
242
+ break;
243
+ case BLOB:
244
+ any = await blobToBuffer(any);
245
+ input = BUFFER;
246
+ break;
247
+ case DATAURL:
248
+ const resp = decodeBase64DataURL(any);
249
+ any = resp.buffer;
250
+ mime = resp.mime;
220
251
  input = BUFFER;
221
252
  break;
222
253
  }
223
254
  switch (expected) {
224
255
  case STREAM: subExp = FILE; break;
225
- case TEXT: case _JSON: subExp = BUFFER;
256
+ case DATAURL: subExp = BUFFER; break;
257
+ case TEXT: case _JSON: subExp = BUFFER; break;
226
258
  }
227
259
  oriFile && (meta = await assertPath(any, 'F', 'R'));
228
260
  if (input !== subExp) {
@@ -240,6 +272,7 @@ const convert = async (any, options) => {
240
272
  case STREAM: result.content = createReadStream(any); break;
241
273
  case TEXT: result.content = any.toString(); break;
242
274
  case _JSON: result.content = JSON.parse(any.toString()); break;
275
+ case DATAURL: result.content = encodeBase64DataURL(options?.mime || mime, any); break;
243
276
  default: result.content = any;
244
277
  }
245
278
  // use options.cleanup to remove original file
@@ -254,7 +287,7 @@ const convert = async (any, options) => {
254
287
  }
255
288
  );
256
289
  // get file with meta data
257
- options?.meta && (result.meta = meta);
290
+ options?.meta && (result = { ...result, mime, meta });
258
291
  // return
259
292
  return Object.keys(result).length === 1 ? result.content : result;
260
293
  };
@@ -268,7 +301,7 @@ const analyzeFile = async (any, options) => {
268
301
  return {
269
302
  content, extname: extname(filename).replace(/^\.|\.$/g, ''),
270
303
  filename, hashAlgorithm, hash: _hash,
271
- mime: extract(await fileTypeFromBuffer(content), 'mime') || lookup(filename) || 'application/octet-stream',
304
+ mime: extract(await fileTypeFromBuffer(content), 'mime') || lookup(filename) || MIME_BINARY,
272
305
  size: content.length,
273
306
  };
274
307
  };
@@ -430,7 +463,9 @@ export {
430
463
  _NEED,
431
464
  analyzeFile,
432
465
  assertPath,
466
+ blobToBuffer,
433
467
  convert,
468
+ decodeBase64DataURL,
434
469
  deleteFileOnCloud,
435
470
  deleteOnCloud,
436
471
  downloadFileFromCloud,
package/lib/utilitas.mjs CHANGED
@@ -267,9 +267,16 @@ const decode = (string, toBuf, encoding) => {
267
267
  return toBuf ? buf : buf.toString('utf8');
268
268
  };
269
269
 
270
- const parseJson = (any, fallback) => {
271
- try { return JSON.parse(any); }
272
- catch (e) { return isSet(fallback) ? fallback : {}; }
270
+ const parseJson = (any, fallback, options) => {
271
+ try {
272
+ return JSON.parse(any, options?.reviver || ((key, value) => {
273
+ if (value && value.type === 'Buffer' && Array.isArray(value.data)) {
274
+ return Buffer.from(value.data);
275
+ }
276
+ return value;
277
+
278
+ }));
279
+ } catch (e) { return isSet(fallback) ? fallback : {}; }
273
280
  };
274
281
 
275
282
  const extract = (...path) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "utilitas",
3
3
  "description": "Just another common utility for JavaScript.",
4
- "version": "1995.2.83",
4
+ "version": "1995.2.85",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/Leask/utilitas",
7
7
  "main": "index.mjs",