@visulima/storage 1.0.0-alpha.2 → 1.0.0-alpha.3
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/CHANGELOG.md +7 -0
- package/dist/index.js +3 -3
- package/dist/packem_shared/{AwsLightStorage-Cwkkc-z3.js → AwsLightStorage-Blv-GP4v.js} +1 -1
- package/dist/packem_shared/{AzureStorage-9MoV2W8q.js → AzureStorage-B0v048hG.js} +1 -1
- package/dist/packem_shared/{DiskStorage-CJtTzMQ3.js → DiskStorage-BlltBst6.js} +2 -2
- package/dist/packem_shared/{DiskStorageWithChecksum-BgrG8pvC.js → DiskStorageWithChecksum-BJTmMklc.js} +1 -1
- package/dist/packem_shared/{GCSMetaStorage-sYiSjLUx.js → GCSMetaStorage-BMFEdzJ7.js} +1 -1
- package/dist/packem_shared/{GCStorage-DPl1_DAm.js → GCStorage-DnhiwaS9.js} +2 -2
- package/dist/packem_shared/{NetlifyBlobStorage-C6AX-X0P.js → NetlifyBlobStorage-CLPtjHqd.js} +1 -1
- package/dist/packem_shared/{S3Storage-CgheE2yH.js → S3Storage-DHmTk-hU.js} +1 -1
- package/dist/packem_shared/{VercelBlobStorage-BbuEYhOz.js → VercelBlobStorage-DD9LMOS6.js} +1 -1
- package/dist/packem_shared/{defaultCloudStorageFileNameValidation-oVDgf-Sw.js → defaultCloudStorageFileNameValidation-DUuacjWv.js} +1 -1
- package/dist/packem_shared/{disk-storage-DkDoHnKB.js → disk-storage-Bh2wy3YW.js} +1 -1
- package/dist/packem_shared/{gcs-meta-storage-etw4wuh5.js → gcs-meta-storage-0tgMNnPO.js} +1 -1
- package/dist/packem_shared/{s3-base-storage-xw6NJFX7.js → s3-base-storage-C1DIHTYY.js} +3 -3
- package/dist/packem_shared/{storage-BwdYUHs3.js → storage-C6NSXb8h.js} +421 -110
- package/dist/storage/aws/index.js +1 -1
- package/dist/storage/aws-light/index.js +1 -1
- package/dist/storage/azure/index.js +1 -1
- package/dist/storage/gcs/index.js +2 -2
- package/dist/storage/local/index.js +2 -2
- package/dist/storage/netlify-blob/index.js +1 -1
- package/dist/storage/vercel-blob/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## @visulima/storage [1.0.0-alpha.3](https://github.com/visulima/visulima/compare/@visulima/storage@1.0.0-alpha.2...@visulima/storage@1.0.0-alpha.3) (2025-12-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Dependencies
|
|
5
|
+
|
|
6
|
+
* **@visulima/humanizer:** upgraded to 3.0.0-alpha.3
|
|
7
|
+
|
|
1
8
|
## @visulima/storage [1.0.0-alpha.2](https://github.com/visulima/visulima/compare/@visulima/storage@1.0.0-alpha.1...@visulima/storage@1.0.0-alpha.2) (2025-12-07)
|
|
2
9
|
|
|
3
10
|
### ⚠ BREAKING CHANGES
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { waitForStorage } from './packem_shared/waitForStorage-Cscw85sx.js';
|
|
2
|
-
export { D as DiskStorage } from './packem_shared/disk-storage-
|
|
3
|
-
export { default as DiskStorageWithChecksum } from './packem_shared/DiskStorageWithChecksum-
|
|
2
|
+
export { D as DiskStorage } from './packem_shared/disk-storage-Bh2wy3YW.js';
|
|
3
|
+
export { default as DiskStorageWithChecksum } from './packem_shared/DiskStorageWithChecksum-BJTmMklc.js';
|
|
4
4
|
export { L as LocalMetaStorage } from './packem_shared/local-meta-storage-By-3SNBI.js';
|
|
5
5
|
export { default as MetaStorage } from './packem_shared/MetaStorage-pECeFOad.js';
|
|
6
|
-
export { B as AbstractBaseStorage, d as defaultCloudStorageFileNameValidation, a as defaultFilesystemFileNameValidation } from './packem_shared/storage-
|
|
6
|
+
export { B as AbstractBaseStorage, d as defaultCloudStorageFileNameValidation, a as defaultFilesystemFileNameValidation } from './packem_shared/storage-C6NSXb8h.js';
|
|
7
7
|
export { ERRORS, ErrorMap, UploadError, isUploadError, throwErrorCode } from './packem_shared/ERRORS-D0apMqnc.js';
|
|
8
8
|
export { createRetryWrapper, isRetryableError, retry } from './packem_shared/isRetryableError-Dycp7127.js';
|
|
9
9
|
export { fileTypeFromBlob, fileTypeFromBuffer, fileTypeFromTokenizer, supportedExtensions, supportedMimeTypes } from 'file-type';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
|
-
import { S as S3BaseStorage } from './s3-base-storage-
|
|
2
|
+
import { S as S3BaseStorage } from './s3-base-storage-C1DIHTYY.js';
|
|
3
3
|
import { a as AwsLightApiAdapter, A as AwsLightMetaStorage } from './aws-light-meta-storage-DKJBgbR6.js';
|
|
4
4
|
import AwsLightFile from './AwsLightFile-tTneXZgG.js';
|
|
5
5
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BlobServiceClient, StorageSharedKeyCredential } from '@azure/storage-blob';
|
|
2
2
|
import { p as partMatch, d as detectFileTypeFromStream, g as getFileStatus } from './part-match-BMNqHDYD.js';
|
|
3
3
|
import { throwErrorCode, ERRORS } from './ERRORS-D0apMqnc.js';
|
|
4
|
-
import { B as BaseStorage, t as toMilliseconds } from './storage-
|
|
4
|
+
import { B as BaseStorage, t as toMilliseconds } from './storage-C6NSXb8h.js';
|
|
5
5
|
import { createRetryWrapper } from './isRetryableError-Dycp7127.js';
|
|
6
6
|
import { L as LocalMetaStorage } from './local-meta-storage-By-3SNBI.js';
|
|
7
7
|
import AzureFile from './AzureFile-CesgFzps.js';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import 'node:fs';
|
|
2
2
|
import 'node:fs/promises';
|
|
3
3
|
import 'node:stream';
|
|
4
|
-
export { D as default } from './disk-storage-
|
|
4
|
+
export { D as default } from './disk-storage-Bh2wy3YW.js';
|
|
5
5
|
import './part-match-BMNqHDYD.js';
|
|
6
6
|
import './ERRORS-D0apMqnc.js';
|
|
7
|
-
import './storage-
|
|
7
|
+
import './storage-C6NSXb8h.js';
|
|
8
8
|
import './local-meta-storage-By-3SNBI.js';
|
|
9
9
|
import './File-Bb3P23dr.js';
|
|
10
10
|
import './update-size-CCGm6i1J.js';
|
|
@@ -3,7 +3,7 @@ import { truncate } from 'node:fs/promises';
|
|
|
3
3
|
import { Transform, pipeline } from 'node:stream';
|
|
4
4
|
import { p as partMatch, d as detectFileTypeFromStream, g as getFileStatus } from './part-match-BMNqHDYD.js';
|
|
5
5
|
import { throwErrorCode, ERRORS } from './ERRORS-D0apMqnc.js';
|
|
6
|
-
import { D as DiskStorage, e as ensureFile, S as StreamLength, s as streamChecksum } from './disk-storage-
|
|
6
|
+
import { D as DiskStorage, e as ensureFile, S as StreamLength, s as streamChecksum } from './disk-storage-Bh2wy3YW.js';
|
|
7
7
|
import { LRUCache } from 'lru-cache';
|
|
8
8
|
import { createHash } from 'node:crypto';
|
|
9
9
|
import { r as remove } from './local-meta-storage-By-3SNBI.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'node:crypto';
|
|
2
2
|
import 'gaxios';
|
|
3
3
|
import 'google-auth-library';
|
|
4
|
-
export { G as default } from './gcs-meta-storage-
|
|
4
|
+
export { G as default } from './gcs-meta-storage-0tgMNnPO.js';
|
|
5
5
|
import './MetaStorage-pECeFOad.js';
|
|
6
6
|
import './Metadata-DRLXeJ0F.js';
|
|
7
7
|
import './GCSConfig-vPP22kN6.js';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { request } from 'gaxios';
|
|
3
3
|
import { GoogleAuth } from 'google-auth-library';
|
|
4
|
-
import { r as retryOptions, G as GCSMetaStorage, g as getRangeEnd, p as package_, b as buildContentRange } from './gcs-meta-storage-
|
|
4
|
+
import { r as retryOptions, G as GCSMetaStorage, g as getRangeEnd, p as package_, b as buildContentRange } from './gcs-meta-storage-0tgMNnPO.js';
|
|
5
5
|
import { p as partMatch, d as detectFileTypeFromStream, g as getFileStatus } from './part-match-BMNqHDYD.js';
|
|
6
6
|
import { throwErrorCode, ERRORS } from './ERRORS-D0apMqnc.js';
|
|
7
|
-
import { B as BaseStorage, t as toMilliseconds } from './storage-
|
|
7
|
+
import { B as BaseStorage, t as toMilliseconds } from './storage-C6NSXb8h.js';
|
|
8
8
|
import { L as LocalMetaStorage } from './local-meta-storage-By-3SNBI.js';
|
|
9
9
|
import GCSConfig from './GCSConfig-vPP22kN6.js';
|
|
10
10
|
import GCSFile from './GCSFile-BIEunhAN.js';
|
package/dist/packem_shared/{NetlifyBlobStorage-C6AX-X0P.js → NetlifyBlobStorage-CLPtjHqd.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getStore } from '@netlify/blobs';
|
|
2
2
|
import { g as getFileStatus, p as partMatch, a as detectFileTypeFromBuffer } from './part-match-BMNqHDYD.js';
|
|
3
|
-
import { B as BaseStorage, t as toMilliseconds, u as updateMetadata } from './storage-
|
|
3
|
+
import { B as BaseStorage, t as toMilliseconds, u as updateMetadata } from './storage-C6NSXb8h.js';
|
|
4
4
|
import { createRetryWrapper } from './isRetryableError-Dycp7127.js';
|
|
5
5
|
import { L as LocalMetaStorage } from './local-meta-storage-By-3SNBI.js';
|
|
6
6
|
import NetlifyBlobFile from './NetlifyBlobFile-CXzyjqrD.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { CreateMultipartUploadCommand, UploadPartCommand, CompleteMultipartUploadCommand, AbortMultipartUploadCommand, ListPartsCommand, GetObjectCommand, HeadObjectCommand, DeleteObjectCommand, CopyObjectCommand, ListObjectsV2Command, waitUntilBucketExists, S3Client } from '@aws-sdk/client-s3';
|
|
3
3
|
import { fromIni } from '@aws-sdk/credential-providers';
|
|
4
|
-
import { S as S3BaseStorage } from './s3-base-storage-
|
|
4
|
+
import { S as S3BaseStorage } from './s3-base-storage-C1DIHTYY.js';
|
|
5
5
|
import { ReadableStream } from 'node:stream/web';
|
|
6
6
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
7
7
|
import S3File from './S3File-DZiyk9Qt.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { put, del, copy, list } from '@vercel/blob';
|
|
2
2
|
import { g as getFileStatus, p as partMatch, a as detectFileTypeFromBuffer } from './part-match-BMNqHDYD.js';
|
|
3
|
-
import { B as BaseStorage, t as toMilliseconds } from './storage-
|
|
3
|
+
import { B as BaseStorage, t as toMilliseconds } from './storage-C6NSXb8h.js';
|
|
4
4
|
import { L as LocalMetaStorage } from './local-meta-storage-By-3SNBI.js';
|
|
5
5
|
import VercelBlobFile from './VercelBlobFile-BCg4aTEq.js';
|
|
6
6
|
import { u as updateSize } from './update-size-CCGm6i1J.js';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import 'node:stream';
|
|
2
2
|
import 'node:timers';
|
|
3
3
|
import 'node:util';
|
|
4
|
-
export { B as BaseStorage, d as defaultCloudStorageFileNameValidation, a as defaultFilesystemFileNameValidation } from './storage-BwdYUHs3.js';
|
|
5
4
|
import 'type-is';
|
|
6
5
|
import './NoOpMetrics-DhAk5rXc.js';
|
|
7
6
|
import './cache-B88MXQ_2.js';
|
|
8
7
|
import './ERRORS-D0apMqnc.js';
|
|
8
|
+
export { B as BaseStorage, d as defaultCloudStorageFileNameValidation, a as defaultFilesystemFileNameValidation } from './storage-C6NSXb8h.js';
|
|
9
9
|
import './validator-BeX_lJet.js';
|
|
10
10
|
import './path-CR6YkPXX-7R1-9CMk.js';
|
|
11
11
|
import './is-expired-CTThU1q5.js';
|
|
@@ -7,7 +7,7 @@ import require$$1 from 'fs';
|
|
|
7
7
|
import { g as getFileStatus, p as partMatch, d as detectFileTypeFromStream } from './part-match-BMNqHDYD.js';
|
|
8
8
|
import { throwErrorCode, isUploadError, ERRORS } from './ERRORS-D0apMqnc.js';
|
|
9
9
|
import { createHash } from 'node:crypto';
|
|
10
|
-
import { B as BaseStorage, a as defaultFilesystemFileNameValidation, t as toMilliseconds } from './storage-
|
|
10
|
+
import { B as BaseStorage, a as defaultFilesystemFileNameValidation, t as toMilliseconds } from './storage-C6NSXb8h.js';
|
|
11
11
|
import { a as assertValidFileOrDirectoryPath, g as getFileInfoType, e as ensureDir, t as toPath, i as isAccessible, L as LocalMetaStorage, b as readFile, r as remove } from './local-meta-storage-By-3SNBI.js';
|
|
12
12
|
import File from './File-Bb3P23dr.js';
|
|
13
13
|
import { createRequire } from 'node:module';
|
|
@@ -7,7 +7,7 @@ import GCSConfig from './GCSConfig-vPP22kN6.js';
|
|
|
7
7
|
import { h as hasContent } from './has-content-CY66ehMK.js';
|
|
8
8
|
|
|
9
9
|
var name = "@visulima/storage";
|
|
10
|
-
var version = "1.0.0-alpha.
|
|
10
|
+
var version = "1.0.0-alpha.2";
|
|
11
11
|
const package_ = {
|
|
12
12
|
name: name,
|
|
13
13
|
version: version};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
|
-
import { b as B, B as BaseStorage, N, t as toMilliseconds } from './storage-BwdYUHs3.js';
|
|
3
2
|
import { p as partMatch, d as detectFileTypeFromStream, g as getFileStatus } from './part-match-BMNqHDYD.js';
|
|
4
3
|
import { throwErrorCode, ERRORS } from './ERRORS-D0apMqnc.js';
|
|
4
|
+
import { p as parseDuration, B as BaseStorage, b as parseBytes, t as toMilliseconds } from './storage-C6NSXb8h.js';
|
|
5
5
|
import { createRetryWrapper } from './isRetryableError-Dycp7127.js';
|
|
6
6
|
import { L as LocalMetaStorage } from './local-meta-storage-By-3SNBI.js';
|
|
7
7
|
import { u as updateSize } from './update-size-CCGm6i1J.js';
|
|
@@ -20,7 +20,7 @@ const toSeconds = (value) => {
|
|
|
20
20
|
if (value === Number(value)) {
|
|
21
21
|
return value;
|
|
22
22
|
}
|
|
23
|
-
return (
|
|
23
|
+
return (parseDuration(value) ?? 0) / 1e3;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
const MIN_PART_SIZE = 5 * 1024 * 1024;
|
|
@@ -38,7 +38,7 @@ class S3BaseStorage extends BaseStorage {
|
|
|
38
38
|
constructor(config) {
|
|
39
39
|
super(config);
|
|
40
40
|
this.bucket = config.bucket;
|
|
41
|
-
this.partSize = typeof config.partSize === "string" ?
|
|
41
|
+
this.partSize = typeof config.partSize === "string" ? parseBytes(config.partSize) : config.partSize || PART_SIZE;
|
|
42
42
|
if (this.partSize < MIN_PART_SIZE) {
|
|
43
43
|
throw new Error("Minimum allowed partSize value is 5MB");
|
|
44
44
|
}
|
|
@@ -10,117 +10,428 @@ import { a as Validator } from './validator-BeX_lJet.js';
|
|
|
10
10
|
import { n as normalize, i as isAbsolute } from './path-CR6YkPXX-7R1-9CMk.js';
|
|
11
11
|
import { i as isExpired } from './is-expired-CTThU1q5.js';
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
13
|
+
const BYTE_SIZES = {
|
|
14
|
+
iec: [
|
|
15
|
+
{
|
|
16
|
+
long: "Bytes",
|
|
17
|
+
short: "B"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
long: "Kibibytes",
|
|
21
|
+
short: "KiB"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
long: "Mebibytes",
|
|
25
|
+
short: "MiB"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
long: "Gibibytes",
|
|
29
|
+
short: "GiB"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
long: "Tebibytes",
|
|
33
|
+
short: "TiB"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
long: "Pebibytes",
|
|
37
|
+
short: "PiB"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
long: "Exbibytes",
|
|
41
|
+
short: "EiB"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
long: "Zebibytes",
|
|
45
|
+
short: "ZiB"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
long: "Yobibytes",
|
|
49
|
+
short: "YiB"
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
iec_octet: [
|
|
53
|
+
{
|
|
54
|
+
long: "Octets",
|
|
55
|
+
short: "o"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
long: "Kibioctets",
|
|
59
|
+
short: "Kio"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
long: "Mebioctets",
|
|
63
|
+
short: "Mio"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
long: "Gibioctets",
|
|
67
|
+
short: "Gio"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
long: "Tebioctets",
|
|
71
|
+
short: "Tio"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
long: "Pebioctets",
|
|
75
|
+
short: "Pio"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
long: "Exbioctets",
|
|
79
|
+
short: "Eio"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
long: "Zebioctets",
|
|
83
|
+
short: "Zio"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
long: "Yobioctets",
|
|
87
|
+
short: "Yio"
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
metric: [
|
|
91
|
+
{
|
|
92
|
+
long: "Bytes",
|
|
93
|
+
short: "Bytes"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
long: "Kilobytes",
|
|
97
|
+
short: "KB"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
long: "Megabytes",
|
|
101
|
+
short: "MB"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
long: "Gigabytes",
|
|
105
|
+
short: "GB"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
long: "Terabytes",
|
|
109
|
+
short: "TB"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
long: "Petabytes",
|
|
113
|
+
short: "PB"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
long: "Exabytes",
|
|
117
|
+
short: "EB"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
long: "Zettabytes",
|
|
121
|
+
short: "ZB"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
long: "Yottabytes",
|
|
125
|
+
short: "YB"
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
metric_octet: [
|
|
129
|
+
{
|
|
130
|
+
long: "Octets",
|
|
131
|
+
short: "o"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
long: "Kilo-octets",
|
|
135
|
+
short: "ko"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
long: "Mega-octets",
|
|
139
|
+
short: "Mo"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
long: "Giga-octets",
|
|
143
|
+
short: "Go"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
long: "Tera-octets",
|
|
147
|
+
short: "To"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
long: "Peta-octets",
|
|
151
|
+
short: "Po"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
long: "Exa-octets",
|
|
155
|
+
short: "Eo"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
long: "Zetta-octets",
|
|
159
|
+
short: "Zo"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
long: "Yotta-octets",
|
|
163
|
+
short: "Yo"
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
};
|
|
167
|
+
const parseLocalizedNumber = (stringNumber, locale) => {
|
|
168
|
+
const thousandSeparator = new Intl.NumberFormat(locale).format(11111).replaceAll(new RegExp("\\p{Number}", "gu"), "");
|
|
169
|
+
const decimalSeparator = new Intl.NumberFormat(locale).format(1.1).replaceAll(new RegExp("\\p{Number}", "gu"), "");
|
|
170
|
+
return Number.parseFloat(stringNumber.replaceAll(new RegExp(`\\${thousandSeparator}`, "g"), "").replace(new RegExp(`\\${decimalSeparator}`), "."));
|
|
171
|
+
};
|
|
172
|
+
const fromBase = (base) => {
|
|
173
|
+
if (base === 2) {
|
|
174
|
+
return 1024;
|
|
175
|
+
}
|
|
176
|
+
if (base === 10) {
|
|
177
|
+
return 1e3;
|
|
178
|
+
}
|
|
179
|
+
throw new TypeError(`Unsupported base.`);
|
|
180
|
+
};
|
|
181
|
+
const parseBytes = (value, options) => {
|
|
182
|
+
const config = {
|
|
183
|
+
base: 2,
|
|
184
|
+
locale: "en-US",
|
|
185
|
+
units: "metric",
|
|
186
|
+
...options
|
|
187
|
+
};
|
|
188
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
189
|
+
throw new TypeError("Value is not a string or is empty.");
|
|
190
|
+
}
|
|
191
|
+
if (value.length > 100) {
|
|
192
|
+
throw new TypeError("Value exceeds the maximum length of 100 characters.");
|
|
193
|
+
}
|
|
194
|
+
const match = /^(?<value>-?(?:\d+(([.,])\d+)*)?[.,]?\d+) *(?<type>bytes?|b|kb|kib|mb|mib|gb|gib|tb|tib|pb|pib|eb|eib|zb|zib|yb|yib|(kilo|kibi|mega|mebi|giga|gibi|tera|tebi|peta|pebi|exa|exbi|zetta|zebi|yotta|yobi)?bytes)?$/i.exec(
|
|
195
|
+
value
|
|
196
|
+
);
|
|
197
|
+
const groups = match?.groups;
|
|
198
|
+
if (!groups) {
|
|
199
|
+
return Number.NaN;
|
|
200
|
+
}
|
|
201
|
+
const localizedNumber = parseLocalizedNumber(groups.value, config.locale);
|
|
202
|
+
const type = (groups.type ?? "Bytes").toUpperCase().replace(/^KIBI/, "KILO").replace(/^MIBI/, "MEGA").replace(/^GIBI/, "GIGA").replace(/^TEBI/, "TERA").replace(/^PEBI/, "PETA").replace(/^EXBI/, "EXA").replace(/^ZEBI/, "ZETTA").replace(/^YIBI/, "YOTTA").replace(/^(.)IB$/, "$1B");
|
|
203
|
+
const level = BYTE_SIZES[config.units].findIndex((unit) => unit.short[0].toUpperCase() === type[0]);
|
|
204
|
+
const base = fromBase(config.base);
|
|
205
|
+
return localizedNumber * base ** level;
|
|
206
|
+
};
|
|
46
207
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
208
|
+
const createDurationLanguage = (y, mo, w, d, h, m, s, ms, future, past, decimal, unitMap, groupSeparator, placeholderSeparator) => {
|
|
209
|
+
const result = {
|
|
210
|
+
d,
|
|
211
|
+
h,
|
|
212
|
+
m,
|
|
213
|
+
mo,
|
|
214
|
+
ms,
|
|
215
|
+
s,
|
|
216
|
+
w,
|
|
217
|
+
y
|
|
218
|
+
};
|
|
219
|
+
{
|
|
220
|
+
result.future = future;
|
|
221
|
+
}
|
|
222
|
+
{
|
|
223
|
+
result.past = past;
|
|
224
|
+
}
|
|
225
|
+
{
|
|
226
|
+
result.decimal = decimal;
|
|
227
|
+
}
|
|
228
|
+
if (unitMap !== void 0) {
|
|
229
|
+
result.unitMap = unitMap;
|
|
230
|
+
}
|
|
231
|
+
{
|
|
232
|
+
result.groupSeparator = groupSeparator;
|
|
233
|
+
}
|
|
234
|
+
{
|
|
235
|
+
result.placeholderSeparator = placeholderSeparator;
|
|
236
|
+
}
|
|
237
|
+
return result;
|
|
238
|
+
};
|
|
55
239
|
|
|
56
|
-
const
|
|
57
|
-
|
|
240
|
+
const englishUnitMap = {
|
|
241
|
+
d: "d",
|
|
242
|
+
day: "d",
|
|
243
|
+
days: "d",
|
|
244
|
+
h: "h",
|
|
245
|
+
hour: "h",
|
|
246
|
+
hours: "h",
|
|
247
|
+
hr: "h",
|
|
248
|
+
hrs: "h",
|
|
249
|
+
m: "m",
|
|
250
|
+
millisecond: "ms",
|
|
251
|
+
milliseconds: "ms",
|
|
252
|
+
min: "m",
|
|
253
|
+
mins: "m",
|
|
254
|
+
minute: "m",
|
|
255
|
+
minutes: "m",
|
|
256
|
+
mo: "mo",
|
|
257
|
+
month: "mo",
|
|
258
|
+
months: "mo",
|
|
259
|
+
ms: "ms",
|
|
260
|
+
s: "s",
|
|
261
|
+
sec: "s",
|
|
262
|
+
second: "s",
|
|
263
|
+
seconds: "s",
|
|
264
|
+
secs: "s",
|
|
265
|
+
w: "w",
|
|
266
|
+
week: "w",
|
|
267
|
+
weeks: "w",
|
|
268
|
+
y: "y",
|
|
269
|
+
year: "y",
|
|
270
|
+
years: "y",
|
|
271
|
+
yr: "y",
|
|
272
|
+
yrs: "y"
|
|
273
|
+
};
|
|
274
|
+
const durationLanguage = createDurationLanguage(
|
|
275
|
+
(counter) => `year${counter === 1 ? "" : "s"}`,
|
|
276
|
+
(counter) => `month${counter === 1 ? "" : "s"}`,
|
|
277
|
+
(counter) => `week${counter === 1 ? "" : "s"}`,
|
|
278
|
+
(counter) => `day${counter === 1 ? "" : "s"}`,
|
|
279
|
+
(counter) => `hour${counter === 1 ? "" : "s"}`,
|
|
280
|
+
(counter) => `minute${counter === 1 ? "" : "s"}`,
|
|
281
|
+
(counter) => `second${counter === 1 ? "" : "s"}`,
|
|
282
|
+
(counter) => `millisecond${counter === 1 ? "" : "s"}`,
|
|
283
|
+
"in %s",
|
|
284
|
+
"%s ago",
|
|
285
|
+
".",
|
|
286
|
+
// decimal
|
|
287
|
+
englishUnitMap,
|
|
288
|
+
",",
|
|
289
|
+
// groupSeparator
|
|
290
|
+
"_"
|
|
291
|
+
// placeholderSeparator
|
|
292
|
+
);
|
|
58
293
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (typeof
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
294
|
+
const validateDurationLanguage = (language) => {
|
|
295
|
+
const requiredProperties = ["y", "mo", "w", "d", "h", "m", "s", "ms", "future", "past"];
|
|
296
|
+
for (const property of requiredProperties) {
|
|
297
|
+
if (!Object.prototype.hasOwnProperty.call(language, property)) {
|
|
298
|
+
throw new TypeError(`Missing required property: ${property}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (typeof language.future !== "string" || typeof language.past !== "string") {
|
|
302
|
+
throw new TypeError("Properties future and past must be of type string");
|
|
303
|
+
}
|
|
304
|
+
for (const property of ["y", "mo", "w", "d", "h", "m", "s", "ms"]) {
|
|
305
|
+
if (typeof language[property] !== "string" && typeof language[property] !== "function") {
|
|
306
|
+
throw new TypeError(`Property ${property} must be of type string or function`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (language.decimal && typeof language.decimal !== "string") {
|
|
310
|
+
throw new TypeError("Property decimal must be of type string");
|
|
311
|
+
}
|
|
312
|
+
if (language.delimiter && typeof language.delimiter !== "string") {
|
|
313
|
+
throw new TypeError("Property delimiter must be of type string");
|
|
314
|
+
}
|
|
315
|
+
if (language._digitReplacements && !Array.isArray(language._digitReplacements)) {
|
|
316
|
+
throw new TypeError("Property _digitReplacements must be an array");
|
|
317
|
+
}
|
|
318
|
+
if (language._numberFirst && typeof language._numberFirst !== "boolean") {
|
|
319
|
+
throw new TypeError("Property _numberFirst must be of type boolean");
|
|
320
|
+
}
|
|
321
|
+
if (language.unitMap && typeof language.unitMap !== "object") {
|
|
322
|
+
throw new TypeError("Property unitMap must be an object");
|
|
323
|
+
}
|
|
324
|
+
if (language.unitMap && Object.values(language.unitMap).some((value) => typeof value !== "string")) {
|
|
325
|
+
throw new TypeError("All values in unitMap must be of type string");
|
|
326
|
+
}
|
|
327
|
+
};
|
|
75
328
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
329
|
+
const STANDARD_UNIT_MEASURES = {
|
|
330
|
+
d: 864e5,
|
|
331
|
+
h: 36e5,
|
|
332
|
+
m: 6e4,
|
|
333
|
+
mo: 2629746e3,
|
|
334
|
+
ms: 1,
|
|
335
|
+
s: 1e3,
|
|
336
|
+
w: 6048e5,
|
|
337
|
+
y: 31556952e3
|
|
338
|
+
};
|
|
339
|
+
const ESCAPE_REGEX = /[-/\\^$*+?.()|[\]{}]/g;
|
|
340
|
+
const ISO_FORMAT = /^PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/i;
|
|
341
|
+
const COLON_FORMAT = /^(?:(\d+):)?(?:(\d+):)?(\d+)$/;
|
|
342
|
+
const NUMERIC_STRING_REGEX = /^[+-]?\d+(?:\.\d+)?$/;
|
|
343
|
+
const parseDuration = (value, options) => {
|
|
344
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
345
|
+
return void 0;
|
|
346
|
+
}
|
|
347
|
+
const { defaultUnit = "ms", language = durationLanguage } = {};
|
|
348
|
+
validateDurationLanguage(language);
|
|
349
|
+
const decimalSeparator = language.decimal ?? ".";
|
|
350
|
+
const groupSeparator = language.groupSeparator ?? ",";
|
|
351
|
+
const placeholderSeparator = language.placeholderSeparator ?? "_";
|
|
352
|
+
const escapedDecimal = decimalSeparator.replaceAll(ESCAPE_REGEX, String.raw`\$&`);
|
|
353
|
+
const escapedGroup = groupSeparator.replaceAll(ESCAPE_REGEX, String.raw`\$&`);
|
|
354
|
+
const escapedPlaceholder = placeholderSeparator.replaceAll(ESCAPE_REGEX, String.raw`\$&`);
|
|
355
|
+
const currentUnitMap = language.unitMap ?? englishUnitMap;
|
|
356
|
+
let processedValue = value.replaceAll(new RegExp(String.raw`(\d)[${escapedPlaceholder}${escapedGroup}](\d)`, "g"), "$1$2");
|
|
357
|
+
if (decimalSeparator !== ".") {
|
|
358
|
+
processedValue = processedValue.replace(escapedDecimal, ".");
|
|
359
|
+
}
|
|
360
|
+
if (NUMERIC_STRING_REGEX.test(value)) {
|
|
361
|
+
const numberOnly = Number.parseFloat(processedValue.trim());
|
|
362
|
+
if (!Number.isNaN(numberOnly)) {
|
|
363
|
+
const unitKey = currentUnitMap[defaultUnit];
|
|
364
|
+
if (unitKey !== void 0) {
|
|
365
|
+
return numberOnly * STANDARD_UNIT_MEASURES[unitKey];
|
|
366
|
+
}
|
|
96
367
|
}
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
368
|
+
return void 0;
|
|
369
|
+
}
|
|
370
|
+
const isoMatch = ISO_FORMAT.exec(value);
|
|
371
|
+
if (isoMatch) {
|
|
372
|
+
const hours = Number.parseInt(isoMatch[1] ?? "0", 10);
|
|
373
|
+
const minutes = Number.parseInt(isoMatch[2] ?? "0", 10);
|
|
374
|
+
const seconds = Number.parseInt(isoMatch[3] ?? "0", 10);
|
|
375
|
+
return hours * 36e5 + minutes * 6e4 + seconds * 1e3;
|
|
376
|
+
}
|
|
377
|
+
const colonMatch = COLON_FORMAT.exec(value);
|
|
378
|
+
if (colonMatch) {
|
|
379
|
+
let hours = 0;
|
|
380
|
+
let minutes = 0;
|
|
381
|
+
let seconds = 0;
|
|
382
|
+
if (colonMatch[2] !== void 0) {
|
|
383
|
+
hours = Number.parseInt(colonMatch[1] ?? "0", 10);
|
|
384
|
+
minutes = Number.parseInt(colonMatch[2], 10);
|
|
385
|
+
} else if (colonMatch[1] !== void 0) {
|
|
386
|
+
minutes = Number.parseInt(colonMatch[1], 10);
|
|
387
|
+
}
|
|
388
|
+
seconds = Number.parseInt(colonMatch[3] ?? "0", 10);
|
|
389
|
+
return hours * 36e5 + minutes * 6e4 + seconds * 1e3;
|
|
390
|
+
}
|
|
391
|
+
const currentUnitMapKeys = Object.keys(currentUnitMap);
|
|
392
|
+
const regexKeys = currentUnitMapKeys.toSorted((a, b) => b.length - a.length).map((k) => k.replaceAll(ESCAPE_REGEX, String.raw`\$&`)).join("|");
|
|
393
|
+
const durationRegex = new RegExp(String.raw`(-?\d*\.?\d+)\s*(${regexKeys})`, "gi");
|
|
394
|
+
let totalMs = 0;
|
|
395
|
+
let match;
|
|
396
|
+
let unitsFound = false;
|
|
397
|
+
let firstMatchIndex = -1;
|
|
398
|
+
let lastMatchEndIndex = 0;
|
|
399
|
+
durationRegex.lastIndex = 0;
|
|
400
|
+
while ((match = durationRegex.exec(processedValue)) !== null) {
|
|
401
|
+
if (!unitsFound) {
|
|
402
|
+
firstMatchIndex = match.index;
|
|
403
|
+
}
|
|
404
|
+
unitsFound = true;
|
|
405
|
+
const numberString = match[1];
|
|
406
|
+
const unitString = match[2];
|
|
407
|
+
if (!numberString || !unitString) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
const trimmedNumberString = numberString.trim();
|
|
411
|
+
const sign = trimmedNumberString.startsWith("-") ? -1 : 1;
|
|
412
|
+
const absNumberString = trimmedNumberString.replace(/^[-+]/, "");
|
|
413
|
+
const parsedNumber = Number.parseFloat(absNumberString);
|
|
414
|
+
const unitKey = currentUnitMap[unitString.toLowerCase()];
|
|
415
|
+
if (unitKey === void 0) {
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
const unitValue = STANDARD_UNIT_MEASURES[unitKey];
|
|
419
|
+
if (Number.isNaN(parsedNumber)) {
|
|
420
|
+
return void 0;
|
|
421
|
+
}
|
|
422
|
+
totalMs += sign * parsedNumber * unitValue;
|
|
423
|
+
lastMatchEndIndex = durationRegex.lastIndex;
|
|
424
|
+
}
|
|
425
|
+
const leadingText = processedValue.slice(0, firstMatchIndex).trim();
|
|
426
|
+
const trailingText = processedValue.slice(lastMatchEndIndex).trim();
|
|
427
|
+
if (unitsFound && (leadingText.length > 0 || trailingText.length > 0)) {
|
|
428
|
+
return void 0;
|
|
429
|
+
}
|
|
430
|
+
if (!unitsFound) {
|
|
431
|
+
return void 0;
|
|
432
|
+
}
|
|
433
|
+
return totalMs;
|
|
434
|
+
};
|
|
124
435
|
|
|
125
436
|
const toMilliseconds = (value) => {
|
|
126
437
|
if (value === Number(value)) {
|
|
@@ -129,7 +440,7 @@ const toMilliseconds = (value) => {
|
|
|
129
440
|
if (!value) {
|
|
130
441
|
return void 0;
|
|
131
442
|
}
|
|
132
|
-
const parsed =
|
|
443
|
+
const parsed = parseDuration(value);
|
|
133
444
|
if (parsed === void 0) {
|
|
134
445
|
return void 0;
|
|
135
446
|
}
|
|
@@ -305,8 +616,8 @@ class BaseStorage {
|
|
|
305
616
|
this.onDelete = options.onDelete;
|
|
306
617
|
this.onError = options.onError;
|
|
307
618
|
this.namingFunction = options.filename;
|
|
308
|
-
this.maxUploadSize = typeof options.maxUploadSize === "string" ?
|
|
309
|
-
this.maxMetadataSize = typeof options.maxMetadataSize === "string" ?
|
|
619
|
+
this.maxUploadSize = typeof options.maxUploadSize === "string" ? parseBytes(options.maxUploadSize) : options.maxUploadSize;
|
|
620
|
+
this.maxMetadataSize = typeof options.maxMetadataSize === "string" ? parseBytes(options.maxMetadataSize) : options.maxMetadataSize;
|
|
310
621
|
this.expiration = options.expiration;
|
|
311
622
|
this.genericConfig = options;
|
|
312
623
|
if (options.assetFolder !== void 0) {
|
|
@@ -861,4 +1172,4 @@ class BaseStorage {
|
|
|
861
1172
|
}
|
|
862
1173
|
}
|
|
863
1174
|
|
|
864
|
-
export { BaseStorage as B,
|
|
1175
|
+
export { BaseStorage as B, defaultFilesystemFileNameValidation as a, parseBytes as b, defaultCloudStorageFileNameValidation as d, parseDuration as p, toMilliseconds as t, updateMetadata as u };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { default as S3File } from '../../packem_shared/S3File-DZiyk9Qt.js';
|
|
2
2
|
export { default as S3MetaStorage } from '../../packem_shared/S3MetaStorage-Dz9aDabA.js';
|
|
3
|
-
export { default as S3Storage } from '../../packem_shared/S3Storage-
|
|
3
|
+
export { default as S3Storage } from '../../packem_shared/S3Storage-DHmTk-hU.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { default as AwsLightFile } from '../../packem_shared/AwsLightFile-tTneXZgG.js';
|
|
2
2
|
export { A as AwsLightMetaStorage } from '../../packem_shared/aws-light-meta-storage-DKJBgbR6.js';
|
|
3
|
-
export { default as AwsLightStorage } from '../../packem_shared/AwsLightStorage-
|
|
3
|
+
export { default as AwsLightStorage } from '../../packem_shared/AwsLightStorage-Blv-GP4v.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { default as AzureFile } from '../../packem_shared/AzureFile-CesgFzps.js';
|
|
2
2
|
export { default as AzureSMetaStorage } from '../../packem_shared/AzureSMetaStorage-CFs-OYJT.js';
|
|
3
|
-
export { default as AzureStorage } from '../../packem_shared/AzureStorage-
|
|
3
|
+
export { default as AzureStorage } from '../../packem_shared/AzureStorage-B0v048hG.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as GCSConfig } from '../../packem_shared/GCSConfig-vPP22kN6.js';
|
|
2
2
|
export { default as GCSFile } from '../../packem_shared/GCSFile-BIEunhAN.js';
|
|
3
|
-
export { G as GCSMetaStorage } from '../../packem_shared/gcs-meta-storage-
|
|
4
|
-
export { default as GCStorage } from '../../packem_shared/GCStorage-
|
|
3
|
+
export { G as GCSMetaStorage } from '../../packem_shared/gcs-meta-storage-0tgMNnPO.js';
|
|
4
|
+
export { default as GCStorage } from '../../packem_shared/GCStorage-DnhiwaS9.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { D as DiskStorage } from '../../packem_shared/disk-storage-
|
|
2
|
-
export { default as DiskStorageWithChecksum } from '../../packem_shared/DiskStorageWithChecksum-
|
|
1
|
+
export { D as DiskStorage } from '../../packem_shared/disk-storage-Bh2wy3YW.js';
|
|
2
|
+
export { default as DiskStorageWithChecksum } from '../../packem_shared/DiskStorageWithChecksum-BJTmMklc.js';
|
|
3
3
|
export { L as LocalMetaStorage } from '../../packem_shared/local-meta-storage-By-3SNBI.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { default as NetlifyBlobFile } from '../../packem_shared/NetlifyBlobFile-CXzyjqrD.js';
|
|
2
2
|
export { default as NetlifyBlobMetaStorage } from '../../packem_shared/NetlifyBlobMetaStorage-DxZ5aDvD.js';
|
|
3
|
-
export { default as NetlifyBlobStorage } from '../../packem_shared/NetlifyBlobStorage-
|
|
3
|
+
export { default as NetlifyBlobStorage } from '../../packem_shared/NetlifyBlobStorage-CLPtjHqd.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { default as VercelBlobFile } from '../../packem_shared/VercelBlobFile-BCg4aTEq.js';
|
|
2
2
|
export { default as VercelBlobMetaStorage } from '../../packem_shared/VercelBlobMetaStorage-Bd9F-VFm.js';
|
|
3
|
-
export { default as VercelBlobStorage } from '../../packem_shared/VercelBlobStorage-
|
|
3
|
+
export { default as VercelBlobStorage } from '../../packem_shared/VercelBlobStorage-DD9LMOS6.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/storage",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.3",
|
|
4
4
|
"description": "Visulima upload - Store files in a web-accessible location via a simplified API. Can automatically scale and rotate images. Includes S3, Azure, GCS and local filesystem-based backends with the most convenient features of each.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"anolilab",
|