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/README.md +4 -2
- package/dist/utilitas.lite.mjs +1 -1
- package/dist/utilitas.lite.mjs.map +1 -1
- package/lib/horizon.mjs +5 -0
- package/lib/manifest.mjs +1 -1
- package/lib/storage.mjs +44 -9
- package/lib/utilitas.mjs +10 -3
- package/package.json +1 -1
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
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,
|
|
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
|
|
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
|
|
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
|
|
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) ||
|
|
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 {
|
|
272
|
-
|
|
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) => {
|