@visulima/storage 1.0.0-alpha.1 → 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 +30 -0
- package/README.md +33 -14
- package/dist/adapter/nuxt/module.d.ts +39 -0
- package/dist/adapter/nuxt/module.js +93 -0
- package/dist/adapter/nuxt/package.json +20 -0
- package/dist/handler/base/base-handler-core.d.ts +91 -0
- package/dist/handler/base/base-handler-fetch.d.ts +76 -0
- package/dist/handler/base/base-handler-node.d.ts +137 -0
- package/dist/handler/http/fetch/index.d.ts +4 -0
- package/dist/handler/http/fetch/index.js +4 -0
- package/dist/handler/http/hono/index.d.ts +67 -0
- package/dist/handler/http/hono/index.js +65 -0
- package/dist/handler/http/nextjs/index.d.ts +61 -0
- package/dist/handler/http/nextjs/index.js +37 -0
- package/dist/handler/http/node/index.d.ts +4 -0
- package/dist/handler/http/node/index.js +4 -0
- package/dist/handler/http/solid-start/index.d.ts +60 -0
- package/dist/handler/http/solid-start/index.js +44 -0
- package/dist/handler/multipart/multipart-base.d.ts +84 -0
- package/dist/handler/multipart/multipart-fetch.d.ts +64 -0
- package/dist/handler/multipart/multipart.d.ts +49 -0
- package/dist/handler/rest/rest-base.d.ts +106 -0
- package/dist/handler/rest/rest-fetch.d.ts +88 -0
- package/dist/handler/rest/rest.d.ts +93 -0
- package/dist/handler/tus/tus-base.d.ts +152 -0
- package/dist/handler/tus/tus-fetch.d.ts +72 -0
- package/dist/handler/tus/tus.d.ts +78 -0
- package/dist/handler/types.d.ts +53 -0
- package/dist/handler/utils/request-parser.d.ts +72 -0
- package/dist/handler/utils/response-builder.d.ts +83 -0
- package/dist/handler/utils/storage-utils.d.ts +10 -0
- package/dist/handler/utils/stream-utils.d.ts +29 -0
- package/dist/handler/utils/upload-handlers.d.ts +76 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +13 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/no-op-metrics.d.ts +15 -0
- package/dist/metrics/opentelemetry-metrics.d.ts +55 -0
- package/dist/openapi/index.d.ts +5 -0
- package/dist/openapi/index.js +5 -0
- package/dist/openapi/rest.d.ts +7 -0
- package/dist/openapi/shared.d.ts +13 -0
- package/dist/openapi/transform.d.ts +3 -0
- package/dist/openapi/tus.d.ts +7 -0
- package/dist/openapi/xhr.d.ts +7 -0
- package/dist/packem_shared/AwsLightFile-tTneXZgG.js +11 -0
- package/dist/packem_shared/AwsLightMetaStorage-BWSOtVaN.js +4 -0
- package/dist/packem_shared/AwsLightStorage-Blv-GP4v.js +133 -0
- package/dist/packem_shared/AzureFile-CesgFzps.js +8 -0
- package/dist/packem_shared/AzureSMetaStorage-CFs-OYJT.js +88 -0
- package/dist/packem_shared/AzureStorage-B0v048hG.js +357 -0
- package/dist/packem_shared/BaseTransformer-C2gLib6v.js +82 -0
- package/dist/packem_shared/DiskStorage-BlltBst6.js +12 -0
- package/dist/packem_shared/DiskStorageWithChecksum-BJTmMklc.js +238 -0
- package/dist/packem_shared/ERRORS-D0apMqnc.js +97 -0
- package/dist/packem_shared/File-Bb3P23dr.js +69 -0
- package/dist/packem_shared/GCSConfig-vPP22kN6.js +11 -0
- package/dist/packem_shared/GCSFile-BIEunhAN.js +8 -0
- package/dist/packem_shared/GCSMetaStorage-BMFEdzJ7.js +7 -0
- package/dist/packem_shared/GCStorage-DnhiwaS9.js +406 -0
- package/dist/packem_shared/LocalMetaStorage-CZHhKkMd.js +7 -0
- package/dist/packem_shared/MediaTransformer-D6658DL1.js +1197 -0
- package/dist/packem_shared/MetaStorage-pECeFOad.js +46 -0
- package/dist/packem_shared/Metadata-DRLXeJ0F.js +89 -0
- package/dist/packem_shared/Multipart-CNFK_Okz.js +163 -0
- package/dist/packem_shared/Multipart-CtUL7BQw.js +128 -0
- package/dist/packem_shared/NetlifyBlobFile-CXzyjqrD.js +14 -0
- package/dist/packem_shared/NetlifyBlobMetaStorage-DxZ5aDvD.js +9 -0
- package/dist/packem_shared/NetlifyBlobStorage-CLPtjHqd.js +376 -0
- package/dist/packem_shared/NoOpMetrics-DhAk5rXc.js +10 -0
- package/dist/packem_shared/OpenTelemetryMetrics-BnxhqIaH.js +67 -0
- package/dist/packem_shared/Rest-CAOAEkOj.js +267 -0
- package/dist/packem_shared/Rest-DNuLwBrK.js +228 -0
- package/dist/packem_shared/S3File-DZiyk9Qt.js +11 -0
- package/dist/packem_shared/S3MetaStorage-Dz9aDabA.js +76 -0
- package/dist/packem_shared/S3Storage-DHmTk-hU.js +316 -0
- package/dist/packem_shared/TUS_RESUMABLE-GJzZ9R-f.js +434 -0
- package/dist/packem_shared/Tus-B8PmlMgR.js +200 -0
- package/dist/packem_shared/Tus-C4F1aYOl.js +195 -0
- package/dist/packem_shared/ValidationError-BfF1aE4h.js +26 -0
- package/dist/packem_shared/VercelBlobFile-BCg4aTEq.js +18 -0
- package/dist/packem_shared/VercelBlobMetaStorage-Bd9F-VFm.js +9 -0
- package/dist/packem_shared/VercelBlobStorage-DD9LMOS6.js +261 -0
- package/dist/packem_shared/_commonjsHelpers-B85MJLTf.js +5 -0
- package/dist/packem_shared/aws-light-meta-storage-DKJBgbR6.js +446 -0
- package/dist/packem_shared/backblaze-BlMnIcBC.js +20 -0
- package/dist/packem_shared/base-handler-core-BKuf4YLT.js +303 -0
- package/dist/packem_shared/base-handler-fetch-Cr0hLiqg.js +291 -0
- package/dist/packem_shared/base-handler-node-gk5aN9Cx.js +730 -0
- package/dist/packem_shared/cache-B88MXQ_2.js +18 -0
- package/dist/packem_shared/cloudflare-Bi1q8wXE.js +21 -0
- package/dist/packem_shared/defaultCloudStorageFileNameValidation-DUuacjWv.js +11 -0
- package/dist/packem_shared/digitalOcean-CWQRJM3L.js +21 -0
- package/dist/packem_shared/disk-storage-Bh2wy3YW.js +810 -0
- package/dist/packem_shared/gcs-meta-storage-0tgMNnPO.js +158 -0
- package/dist/packem_shared/has-content-CY66ehMK.js +3 -0
- package/dist/packem_shared/headers-DoS5nwM-.js +3220 -0
- package/dist/packem_shared/is-expired-CTThU1q5.js +8 -0
- package/dist/packem_shared/isRetryableError-Dycp7127.js +82 -0
- package/dist/packem_shared/isValidMediaType-BeDgiObq.js +35 -0
- package/dist/packem_shared/local-meta-storage-By-3SNBI.js +649 -0
- package/dist/packem_shared/minio-C2YBZQOw.js +22 -0
- package/dist/packem_shared/multipart-base-B3i67SSX.js +102 -0
- package/dist/packem_shared/part-match-BMNqHDYD.js +96 -0
- package/dist/packem_shared/path-CR6YkPXX-7R1-9CMk.js +161 -0
- package/dist/packem_shared/response-builder-BtnRiBUI.js +45 -0
- package/dist/packem_shared/rest-base-GRCcnan7.js +457 -0
- package/dist/packem_shared/restOpenApiSpec-CwcHHY2C.js +800 -0
- package/dist/packem_shared/s3-base-storage-C1DIHTYY.js +510 -0
- package/dist/packem_shared/sharedGet-Cpo7QUyu.js +1019 -0
- package/dist/packem_shared/storage-C6NSXb8h.js +1175 -0
- package/dist/packem_shared/tigris-Hac8TKnX.js +21 -0
- package/dist/packem_shared/transformOpenApiSpec-DWM5WtnN.js +975 -0
- package/dist/packem_shared/tusOpenApiSpec-6ohiToBy.js +740 -0
- package/dist/packem_shared/update-size-CCGm6i1J.js +8 -0
- package/dist/packem_shared/validator-BeX_lJet.js +78 -0
- package/dist/packem_shared/waitForStorage-Cscw85sx.js +18 -0
- package/dist/packem_shared/wasabi-DIyflHSd.js +21 -0
- package/dist/packem_shared/xhrOpenApiSpec-DS17brnx.js +264 -0
- package/dist/storage/aws/clients/backblaze.d.ts +12 -0
- package/dist/storage/aws/clients/cloudflare.d.ts +13 -0
- package/dist/storage/aws/clients/digital-ocean.d.ts +12 -0
- package/dist/storage/aws/clients/index.d.ts +6 -0
- package/dist/storage/aws/clients/index.js +6 -0
- package/dist/storage/aws/clients/minio.d.ts +13 -0
- package/dist/storage/aws/clients/tigris.d.ts +12 -0
- package/dist/storage/aws/clients/types.d.ts +95 -0
- package/dist/storage/aws/clients/wasabi.d.ts +12 -0
- package/dist/storage/aws/index.d.ts +4 -0
- package/dist/storage/aws/index.js +3 -0
- package/dist/storage/aws/s3-base-storage.d.ts +248 -0
- package/dist/storage/aws/s3-client-adapter.d.ts +110 -0
- package/dist/storage/aws/s3-file.d.ts +10 -0
- package/dist/storage/aws/s3-meta-storage.d.ts +15 -0
- package/dist/storage/aws/s3-storage.d.ts +70 -0
- package/dist/storage/aws/types.d.ts +119 -0
- package/dist/storage/aws-light/aws-light-api-adapter.d.ts +130 -0
- package/dist/storage/aws-light/aws-light-file.d.ts +10 -0
- package/dist/storage/aws-light/aws-light-meta-storage.d.ts +19 -0
- package/dist/storage/aws-light/aws-light-storage.d.ts +65 -0
- package/dist/storage/aws-light/index.d.ts +4 -0
- package/dist/storage/aws-light/index.js +3 -0
- package/dist/storage/aws-light/types.d.ts +37 -0
- package/dist/storage/azure/azure-file.d.ts +6 -0
- package/dist/storage/azure/azure-meta-storage.d.ts +15 -0
- package/dist/storage/azure/azure-storage.d.ts +69 -0
- package/dist/storage/azure/index.d.ts +4 -0
- package/dist/storage/azure/index.js +3 -0
- package/dist/storage/azure/types.d.ts +62 -0
- package/dist/storage/gcs/fetch-error.d.ts +11 -0
- package/dist/storage/gcs/gcs-config.d.ts +2 -0
- package/dist/storage/gcs/gcs-file.d.ts +6 -0
- package/dist/storage/gcs/gcs-meta-storage.d.ts +27 -0
- package/dist/storage/gcs/gcs-storage.d.ts +91 -0
- package/dist/storage/gcs/index.d.ts +5 -0
- package/dist/storage/gcs/index.js +4 -0
- package/dist/storage/gcs/types.d.ts +55 -0
- package/dist/storage/gcs/utils.d.ts +7 -0
- package/dist/storage/local/disk-storage-with-checksum.d.ts +15 -0
- package/dist/storage/local/disk-storage.d.ts +135 -0
- package/dist/storage/local/index.d.ts +4 -0
- package/dist/storage/local/index.js +3 -0
- package/dist/storage/local/local-meta-storage.d.ts +32 -0
- package/dist/storage/meta-storage.d.ts +30 -0
- package/dist/storage/netlify-blob/index.d.ts +4 -0
- package/dist/storage/netlify-blob/index.js +3 -0
- package/dist/storage/netlify-blob/netlify-blob-file.d.ts +12 -0
- package/dist/storage/netlify-blob/netlify-blob-meta-storage.d.ts +7 -0
- package/dist/storage/netlify-blob/netlify-blob-storage.d.ts +93 -0
- package/dist/storage/netlify-blob/types.d.ts +30 -0
- package/dist/storage/storage.d.ts +353 -0
- package/dist/storage/types.d.ts +221 -0
- package/dist/storage/utils/file/file.d.ts +25 -0
- package/dist/storage/utils/file/get-file-status.d.ts +9 -0
- package/dist/storage/utils/file/has-content.d.ts +9 -0
- package/dist/storage/utils/file/index.d.ts +10 -0
- package/dist/storage/utils/file/is-expired.d.ts +8 -0
- package/dist/storage/utils/file/metadata.d.ts +18 -0
- package/dist/storage/utils/file/part-match.d.ts +11 -0
- package/dist/storage/utils/file/types.d.ts +37 -0
- package/dist/storage/utils/file/update-metadata.d.ts +10 -0
- package/dist/storage/utils/file/update-size.d.ts +10 -0
- package/dist/storage/vercel-blob/index.d.ts +4 -0
- package/dist/storage/vercel-blob/index.js +3 -0
- package/dist/storage/vercel-blob/types.d.ts +32 -0
- package/dist/storage/vercel-blob/vercel-blob-file.d.ts +16 -0
- package/dist/storage/vercel-blob/vercel-blob-meta-storage.d.ts +7 -0
- package/dist/storage/vercel-blob/vercel-blob-storage.d.ts +76 -0
- package/dist/transformer/audio-transformer.d.ts +128 -0
- package/dist/transformer/audio-transformer.js +278 -0
- package/dist/transformer/base-transformer.d.ts +63 -0
- package/dist/transformer/image-transformer.d.ts +571 -0
- package/dist/transformer/image-transformer.js +1100 -0
- package/dist/transformer/index.d.ts +5 -0
- package/dist/transformer/index.js +4 -0
- package/dist/transformer/media-transformer.d.ts +332 -0
- package/dist/transformer/types.d.ts +652 -0
- package/dist/transformer/utils.d.ts +33 -0
- package/dist/transformer/validation-error.d.ts +23 -0
- package/dist/transformer/video-transformer.d.ts +145 -0
- package/dist/transformer/video-transformer.js +310 -0
- package/dist/utils/cache.d.ts +32 -0
- package/dist/utils/chunked-upload.d.ts +65 -0
- package/dist/utils/detect-file-type.d.ts +28 -0
- package/dist/utils/errors.d.ts +74 -0
- package/dist/utils/file-path-url-matcher.d.ts +18 -0
- package/dist/utils/headers.d.ts +111 -0
- package/dist/utils/http.d.ts +92 -0
- package/dist/utils/locker.d.ts +26 -0
- package/dist/utils/pipes/stream-checksum.d.ts +47 -0
- package/dist/utils/pipes/stream-length.d.ts +22 -0
- package/dist/utils/primitives/get-last-one.d.ts +3 -0
- package/dist/utils/primitives/is-record.d.ts +2 -0
- package/dist/utils/primitives/map-values.d.ts +9 -0
- package/dist/utils/primitives/pick.d.ts +2 -0
- package/dist/utils/primitives/to-milliseconds.d.ts +12 -0
- package/dist/utils/primitives/to-seconds.d.ts +12 -0
- package/dist/utils/range-checksum.d.ts +33 -0
- package/dist/utils/range-hasher.d.ts +46 -0
- package/dist/utils/retry.d.ts +64 -0
- package/dist/utils/types.d.ts +108 -0
- package/dist/utils/validation-error.d.ts +22 -0
- package/dist/utils/validator.d.ts +36 -0
- package/package.json +5 -5
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { c as createHttpError } from './headers-DoS5nwM-.js';
|
|
2
|
+
|
|
3
|
+
class MultipartBase {
|
|
4
|
+
/**
|
|
5
|
+
* Handle multipart POST (upload file).
|
|
6
|
+
* @param filePart File part from multipart parser
|
|
7
|
+
* @param filePart.bytes File bytes data
|
|
8
|
+
* @param filePart.filename Original filename
|
|
9
|
+
* @param filePart.mediaType Content type
|
|
10
|
+
* @param filePart.size File size in bytes
|
|
11
|
+
* @param metadataParts All parts from multipart parser (for extracting metadata)
|
|
12
|
+
* @param requestUrl Request URL for Location header
|
|
13
|
+
* @returns Promise resolving to ResponseFile with upload result
|
|
14
|
+
*/
|
|
15
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
16
|
+
async handlePost(filePart, metadataParts, requestUrl) {
|
|
17
|
+
const config = {
|
|
18
|
+
contentType: filePart.mediaType || "application/octet-stream",
|
|
19
|
+
metadata: {},
|
|
20
|
+
originalName: filePart.filename,
|
|
21
|
+
size: filePart.size
|
|
22
|
+
};
|
|
23
|
+
for (const part of metadataParts) {
|
|
24
|
+
if (!part.isFile && part.name) {
|
|
25
|
+
let data = {};
|
|
26
|
+
if (part.name === "metadata" && part.text) {
|
|
27
|
+
try {
|
|
28
|
+
data = JSON.parse(part.text);
|
|
29
|
+
} catch {
|
|
30
|
+
}
|
|
31
|
+
} else if (part.name) {
|
|
32
|
+
data = { [part.name]: part.text };
|
|
33
|
+
}
|
|
34
|
+
Object.assign(config.metadata, data);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const file = await this.storage.create(config);
|
|
38
|
+
const stream = this.createStreamFromBytes(filePart.bytes);
|
|
39
|
+
await this.storage.write({
|
|
40
|
+
body: stream,
|
|
41
|
+
contentLength: filePart.size,
|
|
42
|
+
id: file.id,
|
|
43
|
+
start: 0
|
|
44
|
+
});
|
|
45
|
+
const completedFile = await this.storage.write({
|
|
46
|
+
body: this.createEmptyStream(),
|
|
47
|
+
contentLength: 0,
|
|
48
|
+
id: file.id,
|
|
49
|
+
start: filePart.size
|
|
50
|
+
});
|
|
51
|
+
let finalFile = completedFile;
|
|
52
|
+
if (Object.keys(config.metadata).length > 0) {
|
|
53
|
+
const mergedMetadata = {
|
|
54
|
+
...completedFile.metadata,
|
|
55
|
+
...config.metadata
|
|
56
|
+
};
|
|
57
|
+
const updatedFile = await this.storage.update({ id: completedFile.id }, { metadata: mergedMetadata });
|
|
58
|
+
finalFile = { ...updatedFile, status: completedFile.status };
|
|
59
|
+
}
|
|
60
|
+
const locationUrl = this.buildFileUrl(requestUrl, finalFile);
|
|
61
|
+
return {
|
|
62
|
+
...finalFile,
|
|
63
|
+
headers: {
|
|
64
|
+
Location: locationUrl,
|
|
65
|
+
...finalFile.expiredAt === void 0 ? {} : { "X-Upload-Expires": finalFile.expiredAt.toString() },
|
|
66
|
+
...finalFile.ETag === void 0 ? {} : { ETag: finalFile.ETag }
|
|
67
|
+
},
|
|
68
|
+
statusCode: 200
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Handle DELETE (delete file).
|
|
73
|
+
* @param id File ID from URL
|
|
74
|
+
* @returns Promise resolving to ResponseFile with deletion result
|
|
75
|
+
*/
|
|
76
|
+
async handleDelete(id) {
|
|
77
|
+
const file = await this.storage.delete({ id });
|
|
78
|
+
if (file.status === void 0) {
|
|
79
|
+
throw createHttpError(404, "File not found");
|
|
80
|
+
}
|
|
81
|
+
return { ...file, headers: {}, statusCode: 204 };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Storage instance for file operations.
|
|
85
|
+
*/
|
|
86
|
+
// eslint-disable-next-line class-methods-use-this
|
|
87
|
+
get storage() {
|
|
88
|
+
throw new Error("storage must be implemented");
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Build file URL from request URL and file data.
|
|
92
|
+
* @param _requestUrl Request URL string
|
|
93
|
+
* @param _file File object containing ID and content type
|
|
94
|
+
* @returns Constructed file URL with extension based on content type
|
|
95
|
+
*/
|
|
96
|
+
// eslint-disable-next-line class-methods-use-this
|
|
97
|
+
buildFileUrl(_requestUrl, _file) {
|
|
98
|
+
throw new Error("buildFileUrl must be implemented");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { MultipartBase as M };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { PassThrough, Transform } from 'node:stream';
|
|
2
|
+
import { fileTypeFromBuffer } from 'file-type';
|
|
3
|
+
|
|
4
|
+
const detectFileTypeFromBuffer = async (buffer) => {
|
|
5
|
+
try {
|
|
6
|
+
return await fileTypeFromBuffer(buffer);
|
|
7
|
+
} catch {
|
|
8
|
+
return void 0;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const detectFileTypeFromStream = async (stream, options) => {
|
|
12
|
+
const sampleSize = 4100;
|
|
13
|
+
let fileType;
|
|
14
|
+
const chunks = [];
|
|
15
|
+
let totalLength = 0;
|
|
16
|
+
let detectionStarted = false;
|
|
17
|
+
let detectionPromise;
|
|
18
|
+
const outputStream = new PassThrough({ highWaterMark: 0 });
|
|
19
|
+
const peekStream = new Transform({
|
|
20
|
+
objectMode: false,
|
|
21
|
+
transform(chunk, _encoding, callback) {
|
|
22
|
+
if (!detectionStarted) {
|
|
23
|
+
chunks.push(chunk);
|
|
24
|
+
totalLength += chunk.length;
|
|
25
|
+
if (totalLength >= sampleSize || totalLength > 0) {
|
|
26
|
+
detectionStarted = true;
|
|
27
|
+
const buffer = Buffer.concat(chunks);
|
|
28
|
+
detectionPromise = fileTypeFromBuffer(buffer).then((detected) => {
|
|
29
|
+
fileType = detected;
|
|
30
|
+
return detected;
|
|
31
|
+
}).catch(() => void 0);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
callback(void 0, chunk);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
stream.pipe(peekStream).pipe(outputStream);
|
|
38
|
+
stream.on("error", (error) => {
|
|
39
|
+
peekStream.destroy(error);
|
|
40
|
+
outputStream.destroy(error);
|
|
41
|
+
});
|
|
42
|
+
peekStream.on("error", (error) => {
|
|
43
|
+
if (!outputStream.destroyed) {
|
|
44
|
+
outputStream.destroy(error);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
await Promise.race([
|
|
48
|
+
new Promise((resolve) => {
|
|
49
|
+
if (detectionStarted) {
|
|
50
|
+
resolve();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const timeout = setTimeout(() => resolve(), 10);
|
|
54
|
+
peekStream.once("data", () => {
|
|
55
|
+
clearTimeout(timeout);
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
peekStream.once("end", () => {
|
|
59
|
+
clearTimeout(timeout);
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
}),
|
|
63
|
+
new Promise((resolve) => {
|
|
64
|
+
setTimeout(() => resolve(), 10);
|
|
65
|
+
})
|
|
66
|
+
]);
|
|
67
|
+
if (detectionPromise) {
|
|
68
|
+
await Promise.race([
|
|
69
|
+
detectionPromise.then(() => void 0),
|
|
70
|
+
new Promise((resolve) => {
|
|
71
|
+
setTimeout(() => resolve(), 150);
|
|
72
|
+
})
|
|
73
|
+
]).catch(() => {
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return { fileType, stream: outputStream };
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const getFileStatus = (file) => {
|
|
80
|
+
if (file.bytesWritten === file.size) {
|
|
81
|
+
return "completed";
|
|
82
|
+
}
|
|
83
|
+
return file.createdAt ? "part" : "created";
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const partMatch = (part, file) => {
|
|
87
|
+
if (part.size !== void 0 && file.size !== void 0 && part.size > 0 && file.size > 0 && part.size > file.size) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
if (file.size === void 0) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return (part.start || 0) + (part.contentLength || 0) <= file.size;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export { detectFileTypeFromBuffer as a, detectFileTypeFromStream as d, getFileStatus as g, partMatch as p };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const DRIVE_LETTER_START_RE = /^[A-Z]:\//i;
|
|
2
|
+
const normalizeWindowsPath = (input = "") => {
|
|
3
|
+
if (!input) {
|
|
4
|
+
return input;
|
|
5
|
+
}
|
|
6
|
+
return input.replaceAll("\\", "/").replace(DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
|
|
7
|
+
};
|
|
8
|
+
const UNC_REGEX = /^[/\\]{2}/;
|
|
9
|
+
const IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Z]:[/\\]/i;
|
|
10
|
+
const DRIVE_LETTER_RE = /^[A-Z]:$/i;
|
|
11
|
+
const cwd = () => {
|
|
12
|
+
if (typeof process.cwd === "function") {
|
|
13
|
+
return process.cwd().replaceAll("\\", "/");
|
|
14
|
+
}
|
|
15
|
+
return "/";
|
|
16
|
+
};
|
|
17
|
+
const normalizeString = (path2, allowAboveRoot) => {
|
|
18
|
+
let result = "";
|
|
19
|
+
let lastSegmentLength = 0;
|
|
20
|
+
let lastSlash = -1;
|
|
21
|
+
let dots = 0;
|
|
22
|
+
let char;
|
|
23
|
+
for (let index = 0; index <= path2.length; ++index) {
|
|
24
|
+
if (index < path2.length) {
|
|
25
|
+
char = path2[index];
|
|
26
|
+
} else if (char === "/") {
|
|
27
|
+
break;
|
|
28
|
+
} else {
|
|
29
|
+
char = "/";
|
|
30
|
+
}
|
|
31
|
+
if (char === "/") {
|
|
32
|
+
if (lastSlash === index - 1 || dots === 1) ;
|
|
33
|
+
else if (dots === 2) {
|
|
34
|
+
if (result.length < 2 || lastSegmentLength !== 2 || !result.endsWith(".") || result.at(-2) !== ".") {
|
|
35
|
+
if (result.length > 2) {
|
|
36
|
+
const lastSlashIndex = result.lastIndexOf("/");
|
|
37
|
+
if (lastSlashIndex === -1) {
|
|
38
|
+
result = "";
|
|
39
|
+
lastSegmentLength = 0;
|
|
40
|
+
} else {
|
|
41
|
+
result = result.slice(0, lastSlashIndex);
|
|
42
|
+
lastSegmentLength = result.length - 1 - result.lastIndexOf("/");
|
|
43
|
+
}
|
|
44
|
+
lastSlash = index;
|
|
45
|
+
dots = 0;
|
|
46
|
+
continue;
|
|
47
|
+
} else if (result.length > 0) {
|
|
48
|
+
result = "";
|
|
49
|
+
lastSegmentLength = 0;
|
|
50
|
+
lastSlash = index;
|
|
51
|
+
dots = 0;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (allowAboveRoot) {
|
|
56
|
+
result += result.length > 0 ? "/.." : "..";
|
|
57
|
+
lastSegmentLength = 2;
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
if (result.length > 0) {
|
|
61
|
+
result += `/${path2.slice(lastSlash + 1, index)}`;
|
|
62
|
+
} else {
|
|
63
|
+
result = path2.slice(lastSlash + 1, index);
|
|
64
|
+
}
|
|
65
|
+
lastSegmentLength = index - lastSlash - 1;
|
|
66
|
+
}
|
|
67
|
+
lastSlash = index;
|
|
68
|
+
dots = 0;
|
|
69
|
+
} else if (char === "." && dots !== -1) {
|
|
70
|
+
++dots;
|
|
71
|
+
} else {
|
|
72
|
+
dots = -1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
};
|
|
77
|
+
const isAbsolute = (path2) => IS_ABSOLUTE_RE.test(path2);
|
|
78
|
+
const normalize = function(path2) {
|
|
79
|
+
if (path2.length === 0) {
|
|
80
|
+
return ".";
|
|
81
|
+
}
|
|
82
|
+
path2 = normalizeWindowsPath(path2);
|
|
83
|
+
const isUNCPath = UNC_REGEX.exec(path2);
|
|
84
|
+
const isPathAbsolute = isAbsolute(path2);
|
|
85
|
+
const trailingSeparator = path2.at(-1) === "/";
|
|
86
|
+
path2 = normalizeString(path2, !isPathAbsolute);
|
|
87
|
+
if (path2.length === 0) {
|
|
88
|
+
if (isPathAbsolute) {
|
|
89
|
+
return "/";
|
|
90
|
+
}
|
|
91
|
+
return trailingSeparator ? "./" : ".";
|
|
92
|
+
}
|
|
93
|
+
if (trailingSeparator) {
|
|
94
|
+
path2 += "/";
|
|
95
|
+
}
|
|
96
|
+
if (DRIVE_LETTER_RE.test(path2)) {
|
|
97
|
+
path2 += "/";
|
|
98
|
+
}
|
|
99
|
+
if (isUNCPath) {
|
|
100
|
+
if (!isPathAbsolute) {
|
|
101
|
+
return `//./${path2}`;
|
|
102
|
+
}
|
|
103
|
+
return `//${path2}`;
|
|
104
|
+
}
|
|
105
|
+
return isPathAbsolute && !isAbsolute(path2) ? `/${path2}` : path2;
|
|
106
|
+
};
|
|
107
|
+
const join = (...segments) => {
|
|
108
|
+
let path2 = "";
|
|
109
|
+
for (const seg of segments) {
|
|
110
|
+
if (!seg) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (path2.length > 0) {
|
|
114
|
+
const pathTrailing = path2[path2.length - 1] === "/";
|
|
115
|
+
const segLeading = seg[0] === "/";
|
|
116
|
+
const both = pathTrailing && segLeading;
|
|
117
|
+
if (both) {
|
|
118
|
+
path2 += seg.slice(1);
|
|
119
|
+
} else {
|
|
120
|
+
path2 += pathTrailing || segLeading ? seg : `/${seg}`;
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
path2 += seg;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return normalize(path2);
|
|
127
|
+
};
|
|
128
|
+
const resolve = function(...arguments_) {
|
|
129
|
+
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
|
|
130
|
+
let resolvedPath = "";
|
|
131
|
+
let resolvedAbsolute = false;
|
|
132
|
+
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
|
|
133
|
+
const path2 = index >= 0 ? arguments_[index] : cwd();
|
|
134
|
+
if (!path2 || path2.length === 0) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
resolvedPath = `${path2}/${resolvedPath}`;
|
|
138
|
+
resolvedAbsolute = isAbsolute(path2);
|
|
139
|
+
}
|
|
140
|
+
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
|
|
141
|
+
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
|
|
142
|
+
return `/${resolvedPath}`;
|
|
143
|
+
}
|
|
144
|
+
return resolvedPath.length > 0 ? resolvedPath : ".";
|
|
145
|
+
};
|
|
146
|
+
const dirname = (path2) => {
|
|
147
|
+
const segments = normalizeWindowsPath(path2).replace(/\/$/, "").split("/").slice(0, -1);
|
|
148
|
+
if (segments.length === 1 && DRIVE_LETTER_RE.test(segments[0])) {
|
|
149
|
+
segments[0] += "/";
|
|
150
|
+
}
|
|
151
|
+
return segments.join("/") || (isAbsolute(path2) ? "/" : ".");
|
|
152
|
+
};
|
|
153
|
+
const basename = (path2, extension) => {
|
|
154
|
+
const lastSegment = normalizeWindowsPath(path2).split("/").pop();
|
|
155
|
+
if (extension && lastSegment.endsWith(extension)) {
|
|
156
|
+
return lastSegment.slice(0, -extension.length);
|
|
157
|
+
}
|
|
158
|
+
return lastSegment;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export { normalizeWindowsPath as a, basename as b, dirname as d, isAbsolute as i, join as j, normalize as n, resolve as r };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import 'mime';
|
|
2
|
+
|
|
3
|
+
const buildResponseFile = (file, headers = {}, statusCode = 200) => ({
|
|
4
|
+
...file,
|
|
5
|
+
headers,
|
|
6
|
+
statusCode
|
|
7
|
+
});
|
|
8
|
+
const buildFileHeaders = (file, locationUrl, additionalHeaders = {}) => {
|
|
9
|
+
return {
|
|
10
|
+
Location: locationUrl,
|
|
11
|
+
...file.expiredAt === void 0 ? {} : { "X-Upload-Expires": file.expiredAt.toString() },
|
|
12
|
+
...file.ETag === void 0 ? {} : { ETag: file.ETag },
|
|
13
|
+
...additionalHeaders
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const buildChunkedUploadHeaders = (file, isComplete) => {
|
|
17
|
+
const metadata = file.metadata || {};
|
|
18
|
+
const headers = {
|
|
19
|
+
"x-chunked-upload": "true",
|
|
20
|
+
"x-upload-complete": isComplete ? "true" : "false",
|
|
21
|
+
"x-upload-offset": String(file.bytesWritten || 0)
|
|
22
|
+
};
|
|
23
|
+
if (Array.isArray(metadata._chunks) && metadata._chunks.length > 0) {
|
|
24
|
+
headers["x-received-chunks"] = JSON.stringify(metadata._chunks);
|
|
25
|
+
}
|
|
26
|
+
return headers;
|
|
27
|
+
};
|
|
28
|
+
const buildFileMetadataHeaders = (file) => {
|
|
29
|
+
return {
|
|
30
|
+
"Content-Length": String(file.size || 0),
|
|
31
|
+
"Content-Type": file.contentType,
|
|
32
|
+
...file.expiredAt === void 0 ? {} : { "X-Upload-Expires": file.expiredAt.toString() },
|
|
33
|
+
...file.modifiedAt === void 0 ? {} : { "Last-Modified": file.modifiedAt.toString() },
|
|
34
|
+
...file.ETag === void 0 ? {} : { ETag: file.ETag }
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const convertHeadersToString = (headers) => {
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
40
|
+
result[key] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { buildFileHeaders as a, buildResponseFile as b, buildChunkedUploadHeaders as c, buildFileMetadataHeaders as d, convertHeadersToString as e };
|