https://project.mdnd-it.cc/work_packages/94
This commit is contained in:
Donat committed 2025-08-23 04:25:28 +02:00
1 parent 725516ad6c
commit 19cfa031d0
25823 files changed
+1095586 -2801759

No files matched your search

+9
View File
@@ -0,0 +1,9 @@
/// <reference types="node" />
/// <reference types="node" />
import * as fs from 'node:fs';
import * as stream from 'node:stream';
export { promises as fsp } from 'node:fs';
export declare const streamPromise: {
pipeline: typeof stream.pipeline.__promisify__;
};
export declare const fstat: typeof fs.fstat.__promisify__;
+14
View File
@@ -0,0 +1,14 @@
// promise helper for stdlib
import * as fs from "fs";
import * as stream from "stream";
import { promisify } from "util";
// TODO: use "node:fs/promise" directly after we stop testing on nodejs 12
export { promises as fsp } from 'node:fs';
export const streamPromise = {
// node:stream/promises Added in: v15.0.0
pipeline: promisify(stream.pipeline)
};
export const fstat = promisify(fs.fstat);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmcyIsInN0cmVhbSIsInByb21pc2lmeSIsInByb21pc2VzIiwiZnNwIiwic3RyZWFtUHJvbWlzZSIsInBpcGVsaW5lIiwiZnN0YXQiXSwic291cmNlcyI6WyJhc3luYy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBwcm9taXNlIGhlbHBlciBmb3Igc3RkbGliXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ25vZGU6ZnMnXG5pbXBvcnQgKiBhcyBzdHJlYW0gZnJvbSAnbm9kZTpzdHJlYW0nXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICdub2RlOnV0aWwnXG5cbi8vIFRPRE86IHVzZSBcIm5vZGU6ZnMvcHJvbWlzZVwiIGRpcmVjdGx5IGFmdGVyIHdlIHN0b3AgdGVzdGluZyBvbiBub2RlanMgMTJcbmV4cG9ydCB7IHByb21pc2VzIGFzIGZzcCB9IGZyb20gJ25vZGU6ZnMnXG5leHBvcnQgY29uc3Qgc3RyZWFtUHJvbWlzZSA9IHtcbiAgLy8gbm9kZTpzdHJlYW0vcHJvbWlzZXMgQWRkZWQgaW46IHYxNS4wLjBcbiAgcGlwZWxpbmU6IHByb21pc2lmeShzdHJlYW0ucGlwZWxpbmUpLFxufVxuXG5leHBvcnQgY29uc3QgZnN0YXQgPSBwcm9taXNpZnkoZnMuZnN0YXQpXG4iXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBLE9BQU8sS0FBS0EsRUFBRTtBQUNkLE9BQU8sS0FBS0MsTUFBTTtBQUNsQixTQUFTQyxTQUFTOztBQUVsQjtBQUNBLFNBQVNDLFFBQVEsSUFBSUMsR0FBRyxRQUFRLFNBQVM7QUFDekMsT0FBTyxNQUFNQyxhQUFhLEdBQUc7RUFDM0I7RUFDQUMsUUFBUSxFQUFFSixTQUFTLENBQUNELE1BQU0sQ0FBQ0ssUUFBUTtBQUNyQyxDQUFDO0FBRUQsT0FBTyxNQUFNQyxLQUFLLEdBQUdMLFNBQVMsQ0FBQ0YsRUFBRSxDQUFDTyxLQUFLLENBQUMifQ==
@@ -0,0 +1,15 @@
// wrapper an async function that support callback style API.
// It will preserve 'this'.
export function callbackify(fn) {
return function () {
const args = [...arguments];
const callback = args.pop();
// If the last argument is a function, assume it's the callback.
if (typeof callback === 'function') {
return fn.apply(this, args).then(result => callback(null, result), err => callback(err));
}
return fn.apply(this, arguments);
};
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjYWxsYmFja2lmeSIsImZuIiwiYXJncyIsImFyZ3VtZW50cyIsImNhbGxiYWNrIiwicG9wIiwiYXBwbHkiLCJ0aGVuIiwicmVzdWx0IiwiZXJyIl0sInNvdXJjZXMiOlsiY2FsbGJhY2tpZnkuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gd3JhcHBlciBhbiBhc3luYyBmdW5jdGlvbiB0aGF0IHN1cHBvcnQgY2FsbGJhY2sgc3R5bGUgQVBJLlxuLy8gSXQgd2lsbCBwcmVzZXJ2ZSAndGhpcycuXG5leHBvcnQgZnVuY3Rpb24gY2FsbGJhY2tpZnkoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBhcmdzID0gWy4uLmFyZ3VtZW50c11cbiAgICBjb25zdCBjYWxsYmFjayA9IGFyZ3MucG9wKClcblxuICAgIC8vIElmIHRoZSBsYXN0IGFyZ3VtZW50IGlzIGEgZnVuY3Rpb24sIGFzc3VtZSBpdCdzIHRoZSBjYWxsYmFjay5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJncykudGhlbihcbiAgICAgICAgKHJlc3VsdCkgPT4gY2FsbGJhY2sobnVsbCwgcmVzdWx0KSxcbiAgICAgICAgKGVycikgPT4gY2FsbGJhY2soZXJyKSxcbiAgICAgIClcbiAgICB9XG5cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICB9XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQSxPQUFPLFNBQVNBLFdBQVdBLENBQUNDLEVBQUUsRUFBRTtFQUM5QixPQUFPLFlBQVk7SUFDakIsTUFBTUMsSUFBSSxHQUFHLENBQUMsR0FBR0MsU0FBUyxDQUFDO0lBQzNCLE1BQU1DLFFBQVEsR0FBR0YsSUFBSSxDQUFDRyxHQUFHLENBQUMsQ0FBQzs7SUFFM0I7SUFDQSxJQUFJLE9BQU9ELFFBQVEsS0FBSyxVQUFVLEVBQUU7TUFDbEMsT0FBT0gsRUFBRSxDQUFDSyxLQUFLLENBQUMsSUFBSSxFQUFFSixJQUFJLENBQUMsQ0FBQ0ssSUFBSSxDQUM3QkMsTUFBTSxJQUFLSixRQUFRLENBQUMsSUFBSSxFQUFFSSxNQUFNLENBQUMsRUFDakNDLEdBQUcsSUFBS0wsUUFBUSxDQUFDSyxHQUFHLENBQ3ZCLENBQUM7SUFDSDtJQUVBLE9BQU9SLEVBQUUsQ0FBQ0ssS0FBSyxDQUFDLElBQUksRUFBRUgsU0FBUyxDQUFDO0VBQ2xDLENBQUM7QUFDSCJ9
+359
View File
@@ -0,0 +1,359 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import * as http from 'node:http';
import * as https from 'node:https';
import * as stream from 'node:stream';
import { CredentialProvider } from "../CredentialProvider.mjs";
import type { SelectResults } from "../helpers.mjs";
import { CopyDestinationOptions, CopySourceOptions, LEGAL_HOLD_STATUS } from "../helpers.mjs";
import type { PostPolicyResult } from "../minio.mjs";
import { CopyConditions } from "./copy-conditions.mjs";
import { Extensions } from "./extensions.mjs";
import { PostPolicy } from "./post-policy.mjs";
import type { Region } from "./s3-endpoints.mjs";
import type { Binary, BucketItemFromList, BucketItemStat, BucketStream, BucketVersioningConfiguration, CopyObjectResult, EncryptionConfig, GetObjectLegalHoldOptions, GetObjectOpts, GetObjectRetentionOpts, IncompleteUploadedBucketItem, IRequest, ItemBucketMetadata, LifecycleConfig, LifeCycleConfigParam, ListObjectQueryOpts, ObjectInfo, ObjectLockInfo, ObjectMetaData, ObjectRetentionInfo, PreSignRequestParams, PutObjectLegalHoldOptions, RemoveObjectsParam, RemoveObjectsResponse, ReplicationConfig, ReplicationConfigOpts, RequestHeaders, ResultCallback, Retention, SelectOptions, StatObjectOpts, Tag, TaggingOpts, Tags, Transport, UploadedObjectInfo } from "./type.mjs";
import type { ListMultipartResult, UploadedPart } from "./xml-parser.mjs";
declare const requestOptionProperties: readonly ["agent", "ca", "cert", "ciphers", "clientCertEngine", "crl", "dhparam", "ecdhCurve", "family", "honorCipherOrder", "key", "passphrase", "pfx", "rejectUnauthorized", "secureOptions", "secureProtocol", "servername", "sessionIdContext"];
export interface ClientOptions {
endPoint: string;
accessKey?: string;
secretKey?: string;
useSSL?: boolean;
port?: number;
region?: Region;
transport?: Transport;
sessionToken?: string;
partSize?: number;
pathStyle?: boolean;
credentialsProvider?: CredentialProvider;
s3AccelerateEndpoint?: string;
transportAgent?: http.Agent;
}
export type RequestOption = Partial<IRequest> & {
method: string;
bucketName?: string;
objectName?: string;
query?: string;
pathStyle?: boolean;
};
export type NoResultCallback = (error: unknown) => void;
export interface MakeBucketOpt {
ObjectLocking?: boolean;
}
export interface RemoveOptions {
versionId?: string;
governanceBypass?: boolean;
forceDelete?: boolean;
}
export declare class TypedClient {
protected transport: Transport;
protected host: string;
protected port: number;
protected protocol: string;
protected accessKey: string;
protected secretKey: string;
protected sessionToken?: string;
protected userAgent: string;
protected anonymous: boolean;
protected pathStyle: boolean;
protected regionMap: Record<string, string>;
region?: string;
protected credentialsProvider?: CredentialProvider;
partSize: number;
protected overRidePartSize?: boolean;
protected maximumPartSize: number;
protected maxObjectSize: number;
enableSHA256: boolean;
protected s3AccelerateEndpoint?: string;
protected reqOptions: Record<string, unknown>;
protected transportAgent: http.Agent;
private readonly clientExtensions;
constructor(params: ClientOptions);
/**
* Minio extensions that aren't necessary present for Amazon S3 compatible storage servers
*/
get extensions(): Extensions;
/**
* @param endPoint - valid S3 acceleration end point
*/
setS3TransferAccelerate(endPoint: string): void;
/**
* Sets the supported request options.
*/
setRequestOptions(options: Pick<https.RequestOptions, (typeof requestOptionProperties)[number]>): void;
/**
* This is s3 Specific and does not hold validity in any other Object storage.
*/
private getAccelerateEndPointIfSet;
/**
* Set application specific information.
* Generates User-Agent in the following style.
* MinIO (OS; ARCH) LIB/VER APP/VER
*/
setAppInfo(appName: string, appVersion: string): void;
/**
* returns options object that can be used with http.request()
* Takes care of constructing virtual-host-style or path-style hostname
*/
protected getRequestOptions(opts: RequestOption & {
region: string;
}): IRequest & {
host: string;
headers: Record<string, string>;
};
setCredentialsProvider(credentialsProvider: CredentialProvider): Promise<void>;
private checkAndRefreshCreds;
private logStream?;
/**
* log the request, response, error
*/
private logHTTP;
/**
* Enable tracing
*/
traceOn(stream?: stream.Writable): void;
/**
* Disable tracing
*/
traceOff(): void;
/**
* makeRequest is the primitive used by the apis for making S3 requests.
* payload can be empty string in case of no payload.
* statusCode is the expected statusCode. If response.statusCode does not match
* we parse the XML error and call the callback with the error message.
*
* A valid region is passed by the calls - listBuckets, makeBucket and getBucketRegion.
*
* @internal
*/
makeRequestAsync(options: RequestOption, payload?: Binary, expectedCodes?: number[], region?: string): Promise<http.IncomingMessage>;
/**
* new request with promise
*
* No need to drain response, response body is not valid
*/
makeRequestAsyncOmit(options: RequestOption, payload?: Binary, statusCodes?: number[], region?: string): Promise<Omit<http.IncomingMessage, 'on'>>;
/**
* makeRequestStream will be used directly instead of makeRequest in case the payload
* is available as a stream. for ex. putObject
*
* @internal
*/
makeRequestStreamAsync(options: RequestOption, body: stream.Readable | Binary, sha256sum: string, statusCodes: number[], region: string): Promise<http.IncomingMessage>;
/**
* gets the region of the bucket
*
* @param bucketName
*
* @internal
*/
protected getBucketRegionAsync(bucketName: string): Promise<string>;
/**
* makeRequest is the primitive used by the apis for making S3 requests.
* payload can be empty string in case of no payload.
* statusCode is the expected statusCode. If response.statusCode does not match
* we parse the XML error and call the callback with the error message.
* A valid region is passed by the calls - listBuckets, makeBucket and
* getBucketRegion.
*
* @deprecated use `makeRequestAsync` instead
*/
makeRequest(options: RequestOption, payload: Binary | undefined, expectedCodes: number[] | undefined, region: string | undefined, returnResponse: boolean, cb: (cb: unknown, result: http.IncomingMessage) => void): void;
/**
* makeRequestStream will be used directly instead of makeRequest in case the payload
* is available as a stream. for ex. putObject
*
* @deprecated use `makeRequestStreamAsync` instead
*/
makeRequestStream(options: RequestOption, stream: stream.Readable | Buffer, sha256sum: string, statusCodes: number[], region: string, returnResponse: boolean, cb: (cb: unknown, result: http.IncomingMessage) => void): void;
/**
* @deprecated use `getBucketRegionAsync` instead
*/
getBucketRegion(bucketName: string, cb: (err: unknown, region: string) => void): Promise<void>;
/**
* Creates the bucket `bucketName`.
*
*/
makeBucket(bucketName: string, region?: Region, makeOpts?: MakeBucketOpt): Promise<void>;
/**
* To check if a bucket already exists.
*/
bucketExists(bucketName: string): Promise<boolean>;
removeBucket(bucketName: string): Promise<void>;
/**
* @deprecated use promise style API
*/
removeBucket(bucketName: string, callback: NoResultCallback): void;
/**
* Callback is called with readable stream of the object content.
*/
getObject(bucketName: string, objectName: string, getOpts?: GetObjectOpts): Promise<stream.Readable>;
/**
* Callback is called with readable stream of the partial object content.
* @param bucketName
* @param objectName
* @param offset
* @param length - length of the object that will be read in the stream (optional, if not specified we read the rest of the file from the offset)
* @param getOpts
*/
getPartialObject(bucketName: string, objectName: string, offset: number, length?: number, getOpts?: GetObjectOpts): Promise<stream.Readable>;
/**
* download object content to a file.
* This method will create a temp file named `${filename}.${base64(etag)}.part.minio` when downloading.
*
* @param bucketName - name of the bucket
* @param objectName - name of the object
* @param filePath - path to which the object data will be written to
* @param getOpts - Optional object get option
*/
fGetObject(bucketName: string, objectName: string, filePath: string, getOpts?: GetObjectOpts): Promise<void>;
/**
* Stat information of the object.
*/
statObject(bucketName: string, objectName: string, statOpts?: StatObjectOpts): Promise<BucketItemStat>;
removeObject(bucketName: string, objectName: string, removeOpts?: RemoveOptions): Promise<void>;
listIncompleteUploads(bucket: string, prefix: string, recursive: boolean): BucketStream<IncompleteUploadedBucketItem>;
/**
* Called by listIncompleteUploads to fetch a batch of incomplete uploads.
*/
listIncompleteUploadsQuery(bucketName: string, prefix: string, keyMarker: string, uploadIdMarker: string, delimiter: string): Promise<ListMultipartResult>;
/**
* Initiate a new multipart upload.
* @internal
*/
initiateNewMultipartUpload(bucketName: string, objectName: string, headers: RequestHeaders): Promise<string>;
/**
* Internal Method to abort a multipart upload request in case of any errors.
*
* @param bucketName - Bucket Name
* @param objectName - Object Name
* @param uploadId - id of a multipart upload to cancel during compose object sequence.
*/
abortMultipartUpload(bucketName: string, objectName: string, uploadId: string): Promise<void>;
findUploadId(bucketName: string, objectName: string): Promise<string | undefined>;
/**
* this call will aggregate the parts on the server into a single object.
*/
completeMultipartUpload(bucketName: string, objectName: string, uploadId: string, etags: {
part: number;
etag?: string;
}[]): Promise<{
etag: string;
versionId: string | null;
}>;
/**
* Get part-info of all parts of an incomplete upload specified by uploadId.
*/
protected listParts(bucketName: string, objectName: string, uploadId: string): Promise<UploadedPart[]>;
/**
* Called by listParts to fetch a batch of part-info
*/
private listPartsQuery;
listBuckets(): Promise<BucketItemFromList[]>;
/**
* Calculate part size given the object size. Part size will be atleast this.partSize
*/
calculatePartSize(size: number): number;
/**
* Uploads the object using contents from a file
*/
fPutObject(bucketName: string, objectName: string, filePath: string, metaData?: ObjectMetaData): Promise<UploadedObjectInfo>;
/**
* Uploading a stream, "Buffer" or "string".
* It's recommended to pass `size` argument with stream.
*/
putObject(bucketName: string, objectName: string, stream: stream.Readable | Buffer | string, size?: number, metaData?: ItemBucketMetadata): Promise<UploadedObjectInfo>;
/**
* method to upload buffer in one call
* @private
*/
private uploadBuffer;
/**
* upload stream with MultipartUpload
* @private
*/
private uploadStream;
removeBucketReplication(bucketName: string): Promise<void>;
removeBucketReplication(bucketName: string, callback: NoResultCallback): void;
setBucketReplication(bucketName: string, replicationConfig: ReplicationConfigOpts): void;
setBucketReplication(bucketName: string, replicationConfig: ReplicationConfigOpts): Promise<void>;
getBucketReplication(bucketName: string): void;
getBucketReplication(bucketName: string): Promise<ReplicationConfig>;
getObjectLegalHold(bucketName: string, objectName: string, getOpts?: GetObjectLegalHoldOptions, callback?: ResultCallback<LEGAL_HOLD_STATUS>): Promise<LEGAL_HOLD_STATUS>;
setObjectLegalHold(bucketName: string, objectName: string, setOpts?: PutObjectLegalHoldOptions): void;
/**
* Get Tags associated with a Bucket
*/
getBucketTagging(bucketName: string): Promise<Tag[]>;
/**
* Get the tags associated with a bucket OR an object
*/
getObjectTagging(bucketName: string, objectName: string, getOpts?: GetObjectOpts): Promise<Tag[]>;
/**
* Set the policy on a bucket or an object prefix.
*/
setBucketPolicy(bucketName: string, policy: string): Promise<void>;
/**
* Get the policy on a bucket or an object prefix.
*/
getBucketPolicy(bucketName: string): Promise<string>;
putObjectRetention(bucketName: string, objectName: string, retentionOpts?: Retention): Promise<void>;
getObjectLockConfig(bucketName: string, callback: ResultCallback<ObjectLockInfo>): void;
getObjectLockConfig(bucketName: string): void;
getObjectLockConfig(bucketName: string): Promise<ObjectLockInfo>;
setObjectLockConfig(bucketName: string, lockConfigOpts: Omit<ObjectLockInfo, 'objectLockEnabled'>): void;
setObjectLockConfig(bucketName: string, lockConfigOpts: Omit<ObjectLockInfo, 'objectLockEnabled'>): Promise<void>;
getBucketVersioning(bucketName: string): Promise<BucketVersioningConfiguration>;
setBucketVersioning(bucketName: string, versionConfig: BucketVersioningConfiguration): Promise<void>;
private setTagging;
private removeTagging;
setBucketTagging(bucketName: string, tags: Tags): Promise<void>;
removeBucketTagging(bucketName: string): Promise<void>;
setObjectTagging(bucketName: string, objectName: string, tags: Tags, putOpts?: TaggingOpts): Promise<void>;
removeObjectTagging(bucketName: string, objectName: string, removeOpts: TaggingOpts): Promise<void>;
selectObjectContent(bucketName: string, objectName: string, selectOpts: SelectOptions): Promise<SelectResults | undefined>;
private applyBucketLifecycle;
removeBucketLifecycle(bucketName: string): Promise<void>;
setBucketLifecycle(bucketName: string, lifeCycleConfig: LifeCycleConfigParam): Promise<void>;
getBucketLifecycle(bucketName: string): Promise<LifecycleConfig | null>;
setBucketEncryption(bucketName: string, encryptionConfig?: EncryptionConfig): Promise<void>;
getBucketEncryption(bucketName: string): Promise<any>;
removeBucketEncryption(bucketName: string): Promise<void>;
getObjectRetention(bucketName: string, objectName: string, getOpts?: GetObjectRetentionOpts): Promise<ObjectRetentionInfo | null | undefined>;
removeObjects(bucketName: string, objectsList: RemoveObjectsParam): Promise<RemoveObjectsResponse[]>;
removeIncompleteUpload(bucketName: string, objectName: string): Promise<void>;
private copyObjectV1;
private copyObjectV2;
copyObject(source: CopySourceOptions, dest: CopyDestinationOptions): Promise<CopyObjectResult>;
copyObject(targetBucketName: string, targetObjectName: string, sourceBucketNameAndObjectName: string, conditions?: CopyConditions): Promise<CopyObjectResult>;
uploadPart(partConfig: {
bucketName: string;
objectName: string;
uploadID: string;
partNumber: number;
headers: RequestHeaders;
}, payload?: Binary): Promise<{
etag: string;
key: string;
part: number;
}>;
composeObject(destObjConfig: CopyDestinationOptions, sourceObjList: CopySourceOptions[]): Promise<boolean | {
etag: string;
versionId: string | null;
} | Promise<void> | CopyObjectResult>;
presignedUrl(method: string, bucketName: string, objectName: string, expires?: number | PreSignRequestParams | undefined, reqParams?: PreSignRequestParams | Date, requestDate?: Date): Promise<string>;
presignedGetObject(bucketName: string, objectName: string, expires?: number, respHeaders?: PreSignRequestParams | Date, requestDate?: Date): Promise<string>;
presignedPutObject(bucketName: string, objectName: string, expires?: number): Promise<string>;
newPostPolicy(): PostPolicy;
presignedPostPolicy(postPolicy: PostPolicy): Promise<PostPolicyResult>;
listObjectsQuery(bucketName: string, prefix?: string, marker?: string, listQueryOpts?: ListObjectQueryOpts): Promise<{
objects: ObjectInfo[];
isTruncated?: boolean | undefined;
nextMarker?: string | undefined;
versionIdMarker?: string | undefined;
}>;
listObjects(bucketName: string, prefix?: string, recursive?: boolean, listOpts?: ListObjectQueryOpts | undefined): BucketStream<ObjectInfo>;
}
export {};
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,10 @@
export declare class CopyConditions {
modified: string;
unmodified: string;
matchETag: string;
matchETagExcept: string;
setModified(date: Date): void;
setUnmodified(date: Date): void;
setMatchETag(etag: string): void;
setMatchETagExcept(etag: string): void;
}
@@ -0,0 +1,25 @@
export class CopyConditions {
modified = '';
unmodified = '';
matchETag = '';
matchETagExcept = '';
setModified(date) {
if (!(date instanceof Date)) {
throw new TypeError('date must be of type Date');
}
this.modified = date.toUTCString();
}
setUnmodified(date) {
if (!(date instanceof Date)) {
throw new TypeError('date must be of type Date');
}
this.unmodified = date.toUTCString();
}
setMatchETag(etag) {
this.matchETag = etag;
}
setMatchETagExcept(etag) {
this.matchETagExcept = etag;
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDb3B5Q29uZGl0aW9ucyIsIm1vZGlmaWVkIiwidW5tb2RpZmllZCIsIm1hdGNoRVRhZyIsIm1hdGNoRVRhZ0V4Y2VwdCIsInNldE1vZGlmaWVkIiwiZGF0ZSIsIkRhdGUiLCJUeXBlRXJyb3IiLCJ0b1VUQ1N0cmluZyIsInNldFVubW9kaWZpZWQiLCJzZXRNYXRjaEVUYWciLCJldGFnIiwic2V0TWF0Y2hFVGFnRXhjZXB0Il0sInNvdXJjZXMiOlsiY29weS1jb25kaXRpb25zLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjbGFzcyBDb3B5Q29uZGl0aW9ucyB7XG4gIHB1YmxpYyBtb2RpZmllZCA9ICcnXG4gIHB1YmxpYyB1bm1vZGlmaWVkID0gJydcbiAgcHVibGljIG1hdGNoRVRhZyA9ICcnXG4gIHB1YmxpYyBtYXRjaEVUYWdFeGNlcHQgPSAnJ1xuXG4gIHNldE1vZGlmaWVkKGRhdGU6IERhdGUpOiB2b2lkIHtcbiAgICBpZiAoIShkYXRlIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2RhdGUgbXVzdCBiZSBvZiB0eXBlIERhdGUnKVxuICAgIH1cblxuICAgIHRoaXMubW9kaWZpZWQgPSBkYXRlLnRvVVRDU3RyaW5nKClcbiAgfVxuXG4gIHNldFVubW9kaWZpZWQoZGF0ZTogRGF0ZSk6IHZvaWQge1xuICAgIGlmICghKGRhdGUgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZGF0ZSBtdXN0IGJlIG9mIHR5cGUgRGF0ZScpXG4gICAgfVxuXG4gICAgdGhpcy51bm1vZGlmaWVkID0gZGF0ZS50b1VUQ1N0cmluZygpXG4gIH1cblxuICBzZXRNYXRjaEVUYWcoZXRhZzogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5tYXRjaEVUYWcgPSBldGFnXG4gIH1cblxuICBzZXRNYXRjaEVUYWdFeGNlcHQoZXRhZzogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5tYXRjaEVUYWdFeGNlcHQgPSBldGFnXG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNQSxjQUFjLENBQUM7RUFDbkJDLFFBQVEsR0FBRyxFQUFFO0VBQ2JDLFVBQVUsR0FBRyxFQUFFO0VBQ2ZDLFNBQVMsR0FBRyxFQUFFO0VBQ2RDLGVBQWUsR0FBRyxFQUFFO0VBRTNCQyxXQUFXQSxDQUFDQyxJQUFVLEVBQVE7SUFDNUIsSUFBSSxFQUFFQSxJQUFJLFlBQVlDLElBQUksQ0FBQyxFQUFFO01BQzNCLE1BQU0sSUFBSUMsU0FBUyxDQUFDLDJCQUEyQixDQUFDO0lBQ2xEO0lBRUEsSUFBSSxDQUFDUCxRQUFRLEdBQUdLLElBQUksQ0FBQ0csV0FBVyxDQUFDLENBQUM7RUFDcEM7RUFFQUMsYUFBYUEsQ0FBQ0osSUFBVSxFQUFRO0lBQzlCLElBQUksRUFBRUEsSUFBSSxZQUFZQyxJQUFJLENBQUMsRUFBRTtNQUMzQixNQUFNLElBQUlDLFNBQVMsQ0FBQywyQkFBMkIsQ0FBQztJQUNsRDtJQUVBLElBQUksQ0FBQ04sVUFBVSxHQUFHSSxJQUFJLENBQUNHLFdBQVcsQ0FBQyxDQUFDO0VBQ3RDO0VBRUFFLFlBQVlBLENBQUNDLElBQVksRUFBUTtJQUMvQixJQUFJLENBQUNULFNBQVMsR0FBR1MsSUFBSTtFQUN2QjtFQUVBQyxrQkFBa0JBLENBQUNELElBQVksRUFBUTtJQUNyQyxJQUFJLENBQUNSLGVBQWUsR0FBR1EsSUFBSTtFQUM3QjtBQUNGIn0=
@@ -0,0 +1,18 @@
import type { TypedClient } from "./client.mjs";
import type { BucketItemWithMetadata, BucketStream } from "./type.mjs";
export declare class Extensions {
private readonly client;
constructor(client: TypedClient);
/**
* List the objects in the bucket using S3 ListObjects V2 With Metadata
*
* @param bucketName - name of the bucket
* @param prefix - the prefix of the objects that should be listed (optional, default `''`)
* @param recursive - `true` indicates recursive style listing and `false` indicates directory style listing delimited by '/'. (optional, default `false`)
* @param startAfter - Specifies the key to start after when listing objects in a bucket. (optional, default `''`)
* @returns stream emitting the objects in the bucket, the object is of the format:
*/
listObjectsV2WithMetadata(bucketName: string, prefix?: string, recursive?: boolean, startAfter?: string): BucketStream<BucketItemWithMetadata>;
private listObjectsV2WithMetadataGen;
private listObjectsV2WithMetadataQuery;
}
+114
View File
@@ -0,0 +1,114 @@
/*
* MinIO Javascript Library for Amazon S3 Compatible Cloud Storage, (C) 2020 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as stream from "stream";
import * as errors from "../errors.mjs";
import { isBoolean, isString, isValidBucketName, isValidPrefix, uriEscape } from "./helper.mjs";
import { readAsString } from "./response.mjs";
import { parseListObjectsV2WithMetadata } from "./xml-parser.mjs";
export class Extensions {
constructor(client) {
this.client = client;
}
/**
* List the objects in the bucket using S3 ListObjects V2 With Metadata
*
* @param bucketName - name of the bucket
* @param prefix - the prefix of the objects that should be listed (optional, default `''`)
* @param recursive - `true` indicates recursive style listing and `false` indicates directory style listing delimited by '/'. (optional, default `false`)
* @param startAfter - Specifies the key to start after when listing objects in a bucket. (optional, default `''`)
* @returns stream emitting the objects in the bucket, the object is of the format:
*/
listObjectsV2WithMetadata(bucketName, prefix, recursive, startAfter) {
if (prefix === undefined) {
prefix = '';
}
if (recursive === undefined) {
recursive = false;
}
if (startAfter === undefined) {
startAfter = '';
}
if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError('Invalid bucket name: ' + bucketName);
}
if (!isValidPrefix(prefix)) {
throw new errors.InvalidPrefixError(`Invalid prefix : ${prefix}`);
}
if (!isString(prefix)) {
throw new TypeError('prefix should be of type "string"');
}
if (!isBoolean(recursive)) {
throw new TypeError('recursive should be of type "boolean"');
}
if (!isString(startAfter)) {
throw new TypeError('startAfter should be of type "string"');
}
// if recursive is false set delimiter to '/'
const delimiter = recursive ? '' : '/';
return stream.Readable.from(this.listObjectsV2WithMetadataGen(bucketName, prefix, delimiter, startAfter), {
objectMode: true
});
}
async *listObjectsV2WithMetadataGen(bucketName, prefix, delimiter, startAfter) {
let ended = false;
let continuationToken = '';
do {
const result = await this.listObjectsV2WithMetadataQuery(bucketName, prefix, continuationToken, delimiter, startAfter);
ended = !result.isTruncated;
continuationToken = result.nextContinuationToken;
for (const obj of result.objects) {
yield obj;
}
} while (!ended);
}
async listObjectsV2WithMetadataQuery(bucketName, prefix, continuationToken, delimiter, startAfter) {
const queries = [];
// Call for listing objects v2 API
queries.push(`list-type=2`);
queries.push(`encoding-type=url`);
// escape every value in query string, except maxKeys
queries.push(`prefix=${uriEscape(prefix)}`);
queries.push(`delimiter=${uriEscape(delimiter)}`);
queries.push(`metadata=true`);
if (continuationToken) {
continuationToken = uriEscape(continuationToken);
queries.push(`continuation-token=${continuationToken}`);
}
// Set start-after
if (startAfter) {
startAfter = uriEscape(startAfter);
queries.push(`start-after=${startAfter}`);
}
queries.push(`max-keys=1000`);
queries.sort();
let query = '';
if (queries.length > 0) {
query = `${queries.join('&')}`;
}
const method = 'GET';
const res = await this.client.makeRequestAsync({
method,
bucketName,
query
});
return parseListObjectsV2WithMetadata(await readAsString(res));
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzdHJlYW0iLCJlcnJvcnMiLCJpc0Jvb2xlYW4iLCJpc1N0cmluZyIsImlzVmFsaWRCdWNrZXROYW1lIiwiaXNWYWxpZFByZWZpeCIsInVyaUVzY2FwZSIsInJlYWRBc1N0cmluZyIsInBhcnNlTGlzdE9iamVjdHNWMldpdGhNZXRhZGF0YSIsIkV4dGVuc2lvbnMiLCJjb25zdHJ1Y3RvciIsImNsaWVudCIsImxpc3RPYmplY3RzVjJXaXRoTWV0YWRhdGEiLCJidWNrZXROYW1lIiwicHJlZml4IiwicmVjdXJzaXZlIiwic3RhcnRBZnRlciIsInVuZGVmaW5lZCIsIkludmFsaWRCdWNrZXROYW1lRXJyb3IiLCJJbnZhbGlkUHJlZml4RXJyb3IiLCJUeXBlRXJyb3IiLCJkZWxpbWl0ZXIiLCJSZWFkYWJsZSIsImZyb20iLCJsaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhR2VuIiwib2JqZWN0TW9kZSIsImVuZGVkIiwiY29udGludWF0aW9uVG9rZW4iLCJyZXN1bHQiLCJsaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhUXVlcnkiLCJpc1RydW5jYXRlZCIsIm5leHRDb250aW51YXRpb25Ub2tlbiIsIm9iaiIsIm9iamVjdHMiLCJxdWVyaWVzIiwicHVzaCIsInNvcnQiLCJxdWVyeSIsImxlbmd0aCIsImpvaW4iLCJtZXRob2QiLCJyZXMiLCJtYWtlUmVxdWVzdEFzeW5jIl0sInNvdXJjZXMiOlsiZXh0ZW5zaW9ucy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogTWluSU8gSmF2YXNjcmlwdCBMaWJyYXJ5IGZvciBBbWF6b24gUzMgQ29tcGF0aWJsZSBDbG91ZCBTdG9yYWdlLCAoQykgMjAyMCBNaW5JTywgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBzdHJlYW0gZnJvbSAnbm9kZTpzdHJlYW0nXG5cbmltcG9ydCAqIGFzIGVycm9ycyBmcm9tICcuLi9lcnJvcnMudHMnXG5pbXBvcnQgdHlwZSB7IFR5cGVkQ2xpZW50IH0gZnJvbSAnLi9jbGllbnQudHMnXG5pbXBvcnQgeyBpc0Jvb2xlYW4sIGlzU3RyaW5nLCBpc1ZhbGlkQnVja2V0TmFtZSwgaXNWYWxpZFByZWZpeCwgdXJpRXNjYXBlIH0gZnJvbSAnLi9oZWxwZXIudHMnXG5pbXBvcnQgeyByZWFkQXNTdHJpbmcgfSBmcm9tICcuL3Jlc3BvbnNlLnRzJ1xuaW1wb3J0IHR5cGUgeyBCdWNrZXRJdGVtV2l0aE1ldGFkYXRhLCBCdWNrZXRTdHJlYW0gfSBmcm9tICcuL3R5cGUudHMnXG5pbXBvcnQgeyBwYXJzZUxpc3RPYmplY3RzVjJXaXRoTWV0YWRhdGEgfSBmcm9tICcuL3htbC1wYXJzZXIudHMnXG5cbmV4cG9ydCBjbGFzcyBFeHRlbnNpb25zIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFR5cGVkQ2xpZW50KSB7fVxuXG4gIC8qKlxuICAgKiBMaXN0IHRoZSBvYmplY3RzIGluIHRoZSBidWNrZXQgdXNpbmcgUzMgTGlzdE9iamVjdHMgVjIgV2l0aCBNZXRhZGF0YVxuICAgKlxuICAgKiBAcGFyYW0gYnVja2V0TmFtZSAtIG5hbWUgb2YgdGhlIGJ1Y2tldFxuICAgKiBAcGFyYW0gcHJlZml4IC0gdGhlIHByZWZpeCBvZiB0aGUgb2JqZWN0cyB0aGF0IHNob3VsZCBiZSBsaXN0ZWQgKG9wdGlvbmFsLCBkZWZhdWx0IGAnJ2ApXG4gICAqIEBwYXJhbSByZWN1cnNpdmUgLSBgdHJ1ZWAgaW5kaWNhdGVzIHJlY3Vyc2l2ZSBzdHlsZSBsaXN0aW5nIGFuZCBgZmFsc2VgIGluZGljYXRlcyBkaXJlY3Rvcnkgc3R5bGUgbGlzdGluZyBkZWxpbWl0ZWQgYnkgJy8nLiAob3B0aW9uYWwsIGRlZmF1bHQgYGZhbHNlYClcbiAgICogQHBhcmFtIHN0YXJ0QWZ0ZXIgLSBTcGVjaWZpZXMgdGhlIGtleSB0byBzdGFydCBhZnRlciB3aGVuIGxpc3Rpbmcgb2JqZWN0cyBpbiBhIGJ1Y2tldC4gKG9wdGlvbmFsLCBkZWZhdWx0IGAnJ2ApXG4gICAqIEByZXR1cm5zIHN0cmVhbSBlbWl0dGluZyB0aGUgb2JqZWN0cyBpbiB0aGUgYnVja2V0LCB0aGUgb2JqZWN0IGlzIG9mIHRoZSBmb3JtYXQ6XG4gICAqL1xuICBwdWJsaWMgbGlzdE9iamVjdHNWMldpdGhNZXRhZGF0YShcbiAgICBidWNrZXROYW1lOiBzdHJpbmcsXG4gICAgcHJlZml4Pzogc3RyaW5nLFxuICAgIHJlY3Vyc2l2ZT86IGJvb2xlYW4sXG4gICAgc3RhcnRBZnRlcj86IHN0cmluZyxcbiAgKTogQnVja2V0U3RyZWFtPEJ1Y2tldEl0ZW1XaXRoTWV0YWRhdGE+IHtcbiAgICBpZiAocHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHByZWZpeCA9ICcnXG4gICAgfVxuICAgIGlmIChyZWN1cnNpdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVjdXJzaXZlID0gZmFsc2VcbiAgICB9XG4gICAgaWYgKHN0YXJ0QWZ0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc3RhcnRBZnRlciA9ICcnXG4gICAgfVxuICAgIGlmICghaXNWYWxpZEJ1Y2tldE5hbWUoYnVja2V0TmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEJ1Y2tldE5hbWVFcnJvcignSW52YWxpZCBidWNrZXQgbmFtZTogJyArIGJ1Y2tldE5hbWUpXG4gICAgfVxuICAgIGlmICghaXNWYWxpZFByZWZpeChwcmVmaXgpKSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRQcmVmaXhFcnJvcihgSW52YWxpZCBwcmVmaXggOiAke3ByZWZpeH1gKVxuICAgIH1cbiAgICBpZiAoIWlzU3RyaW5nKHByZWZpeCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ByZWZpeCBzaG91bGQgYmUgb2YgdHlwZSBcInN0cmluZ1wiJylcbiAgICB9XG4gICAgaWYgKCFpc0Jvb2xlYW4ocmVjdXJzaXZlKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVjdXJzaXZlIHNob3VsZCBiZSBvZiB0eXBlIFwiYm9vbGVhblwiJylcbiAgICB9XG4gICAgaWYgKCFpc1N0cmluZyhzdGFydEFmdGVyKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc3RhcnRBZnRlciBzaG91bGQgYmUgb2YgdHlwZSBcInN0cmluZ1wiJylcbiAgICB9XG5cbiAgICAvLyBpZiByZWN1cnNpdmUgaXMgZmFsc2Ugc2V0IGRlbGltaXRlciB0byAnLydcbiAgICBjb25zdCBkZWxpbWl0ZXIgPSByZWN1cnNpdmUgPyAnJyA6ICcvJ1xuICAgIHJldHVybiBzdHJlYW0uUmVhZGFibGUuZnJvbSh0aGlzLmxpc3RPYmplY3RzVjJXaXRoTWV0YWRhdGFHZW4oYnVja2V0TmFtZSwgcHJlZml4LCBkZWxpbWl0ZXIsIHN0YXJ0QWZ0ZXIpLCB7XG4gICAgICBvYmplY3RNb2RlOiB0cnVlLFxuICAgIH0pXG4gIH1cblxuICBwcml2YXRlIGFzeW5jICpsaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhR2VuKFxuICAgIGJ1Y2tldE5hbWU6IHN Line truncated
+173
View File
@@ -0,0 +1,173 @@
/// <reference types="node" />
/// <reference types="node" />
import * as stream from 'node:stream';
import _ from 'lodash';
import type { Binary, Encryption, ObjectMetaData, RequestHeaders, ResponseHeader } from "./type.mjs";
export declare function hashBinary(buf: Buffer, enableSHA256: boolean): {
md5sum: string;
sha256sum: string;
};
export declare function uriEscape(uriStr: string): string;
export declare function uriResourceEscape(string: string): string;
export declare function getScope(region: string, date: Date, serviceName?: string): string;
/**
* isAmazonEndpoint - true if endpoint is 's3.amazonaws.com' or 's3.cn-north-1.amazonaws.com.cn'
*/
export declare function isAmazonEndpoint(endpoint: string): boolean;
/**
* isVirtualHostStyle - verify if bucket name is support with virtual
* hosts. bucketNames with periods should be always treated as path
* style if the protocol is 'https:', this is due to SSL wildcard
* limitation. For all other buckets and Amazon S3 endpoint we will
* default to virtual host style.
*/
export declare function isVirtualHostStyle(endpoint: string, protocol: string, bucket: string, pathStyle: boolean): boolean;
export declare function isValidIP(ip: string): boolean;
/**
* @returns if endpoint is valid domain.
*/
export declare function isValidEndpoint(endpoint: string): boolean;
/**
* @returns if input host is a valid domain.
*/
export declare function isValidDomain(host: string): boolean;
/**
* Probes contentType using file extensions.
*
* @example
* ```
* // return 'image/png'
* probeContentType('file.png')
* ```
*/
export declare function probeContentType(path: string): string;
/**
* is input port valid.
*/
export declare function isValidPort(port: unknown): port is number;
export declare function isValidBucketName(bucket: unknown): boolean;
/**
* check if objectName is a valid object name
*/
export declare function isValidObjectName(objectName: unknown): boolean;
/**
* check if prefix is valid
*/
export declare function isValidPrefix(prefix: unknown): prefix is string;
/**
* check if typeof arg number
*/
export declare function isNumber(arg: unknown): arg is number;
export type AnyFunction = (...args: any[]) => any;
/**
* check if typeof arg function
*/
export declare function isFunction(arg: unknown): arg is AnyFunction;
/**
* check if typeof arg string
*/
export declare function isString(arg: unknown): arg is string;
/**
* check if typeof arg object
*/
export declare function isObject(arg: unknown): arg is object;
/**
* check if object is readable stream
*/
export declare function isReadableStream(arg: unknown): arg is stream.Readable;
/**
* check if arg is boolean
*/
export declare function isBoolean(arg: unknown): arg is boolean;
export declare function isEmpty(o: unknown): o is null | undefined;
export declare function isEmptyObject(o: Record<string, unknown>): boolean;
export declare function isDefined<T>(o: T): o is Exclude<T, null | undefined>;
/**
* check if arg is a valid date
*/
export declare function isValidDate(arg: unknown): arg is Date;
/**
* Create a Date string with format: 'YYYYMMDDTHHmmss' + Z
*/
export declare function makeDateLong(date?: Date): string;
/**
* Create a Date string with format: 'YYYYMMDD'
*/
export declare function makeDateShort(date?: Date): string;
/**
* pipesetup sets up pipe() from left to right os streams array
* pipesetup will also make sure that error emitted at any of the upstream Stream
* will be emitted at the last stream. This makes error handling simple
*/
export declare function pipesetup(...streams: [stream.Readable, ...stream.Duplex[], stream.Writable]): stream.Readable | stream.Duplex | stream.Writable;
/**
* return a Readable stream that emits data
*/
export declare function readableStream(data: unknown): stream.Readable;
/**
* Process metadata to insert appropriate value to `content-type` attribute
*/
export declare function insertContentType(metaData: ObjectMetaData, filePath: string): ObjectMetaData;
/**
* Function prepends metadata with the appropriate prefix if it is not already on
*/
export declare function prependXAMZMeta(metaData?: ObjectMetaData): RequestHeaders;
/**
* Checks if it is a valid header according to the AmazonS3 API
*/
export declare function isAmzHeader(key: string): boolean;
/**
* Checks if it is a supported Header
*/
export declare function isSupportedHeader(key: string): boolean;
/**
* Checks if it is a storage header
*/
export declare function isStorageClassHeader(key: string): boolean;
export declare function extractMetadata(headers: ResponseHeader): _.Dictionary<string>;
export declare function getVersionId(headers?: ResponseHeader): string | null;
export declare function getSourceVersionId(headers?: ResponseHeader): string | null;
export declare function sanitizeETag(etag?: string): string;
export declare function toMd5(payload: Binary): string;
export declare function toSha256(payload: Binary): string;
/**
* toArray returns a single element array with param being the element,
* if param is just a string, and returns 'param' back if it is an array
* So, it makes sure param is always an array
*/
export declare function toArray<T = unknown>(param: T | T[]): Array<T>;
export declare function sanitizeObjectKey(objectName: string): string;
export declare function sanitizeSize(size?: string): number | undefined;
export declare const PART_CONSTRAINTS: {
ABS_MIN_PART_SIZE: number;
MIN_PART_SIZE: number;
MAX_PARTS_COUNT: number;
MAX_PART_SIZE: number;
MAX_SINGLE_PUT_OBJECT_SIZE: number;
MAX_MULTIPART_PUT_OBJECT_SIZE: number;
};
/**
* Return Encryption headers
* @param encConfig
* @returns an object with key value pairs that can be used in headers.
*/
export declare function getEncryptionHeaders(encConfig: Encryption): RequestHeaders;
export declare function partsRequired(size: number): number;
/**
* calculateEvenSplits - computes splits for a source and returns
* start and end index slices. Splits happen evenly to be sure that no
* part is less than 5MiB, as that could fail the multipart request if
* it is not the last part.
*/
export declare function calculateEvenSplits<T extends {
Start?: number;
}>(size: number, objInfo: T): {
startIndex: number[];
objInfo: T;
endIndex: number[];
} | null;
export declare function parseXml(xml: string): any;
/**
* get content size of object content to upload
*/
export declare function getContentLength(s: stream.Readable | Buffer | string): Promise<number | null>;
+547
View File
@@ -0,0 +1,547 @@
/*
* MinIO Javascript Library for Amazon S3 Compatible Cloud Storage, (C) 2015 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as crypto from "crypto";
import * as stream from "stream";
import { XMLParser } from 'fast-xml-parser';
import ipaddr from 'ipaddr.js';
import _ from 'lodash';
import * as mime from 'mime-types';
import { fsp, fstat } from "./async.mjs";
import { ENCRYPTION_TYPES } from "./type.mjs";
const MetaDataHeaderPrefix = 'x-amz-meta-';
export function hashBinary(buf, enableSHA256) {
let sha256sum = '';
if (enableSHA256) {
sha256sum = crypto.createHash('sha256').update(buf).digest('hex');
}
const md5sum = crypto.createHash('md5').update(buf).digest('base64');
return {
md5sum,
sha256sum
};
}
// S3 percent-encodes some extra non-standard characters in a URI . So comply with S3.
const encodeAsHex = c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`;
export function uriEscape(uriStr) {
return encodeURIComponent(uriStr).replace(/[!'()*]/g, encodeAsHex);
}
export function uriResourceEscape(string) {
return uriEscape(string).replace(/%2F/g, '/');
}
export function getScope(region, date, serviceName = 's3') {
return `${makeDateShort(date)}/${region}/${serviceName}/aws4_request`;
}
/**
* isAmazonEndpoint - true if endpoint is 's3.amazonaws.com' or 's3.cn-north-1.amazonaws.com.cn'
*/
export function isAmazonEndpoint(endpoint) {
return endpoint === 's3.amazonaws.com' || endpoint === 's3.cn-north-1.amazonaws.com.cn';
}
/**
* isVirtualHostStyle - verify if bucket name is support with virtual
* hosts. bucketNames with periods should be always treated as path
* style if the protocol is 'https:', this is due to SSL wildcard
* limitation. For all other buckets and Amazon S3 endpoint we will
* default to virtual host style.
*/
export function isVirtualHostStyle(endpoint, protocol, bucket, pathStyle) {
if (protocol === 'https:' && bucket.includes('.')) {
return false;
}
return isAmazonEndpoint(endpoint) || !pathStyle;
}
export function isValidIP(ip) {
return ipaddr.isValid(ip);
}
/**
* @returns if endpoint is valid domain.
*/
export function isValidEndpoint(endpoint) {
return isValidDomain(endpoint) || isValidIP(endpoint);
}
/**
* @returns if input host is a valid domain.
*/
export function isValidDomain(host) {
if (!isString(host)) {
return false;
}
// See RFC 1035, RFC 3696.
if (host.length === 0 || host.length > 255) {
return false;
}
// Host cannot start or end with a '-'
if (host[0] === '-' || host.slice(-1) === '-') {
return false;
}
// Host cannot start or end with a '_'
if (host[0] === '_' || host.slice(-1) === '_') {
return false;
}
// Host cannot start with a '.'
if (host[0] === '.') {
return false;
}
const nonAlphaNumerics = '`~!@#$%^&*()+={}[]|\\"\';:><?/';
// All non alphanumeric characters are invalid.
for (const char of nonAlphaNumerics) {
if (host.includes(char)) {
return false;
}
}
// No need to regexp match, since the list is non-exhaustive.
// We let it be valid and fail later.
return true;
}
/**
* Probes contentType using file extensions.
*
* @example
* ```
* // return 'image/png'
* probeContentType('file.png')
* ```
*/
export function probeContentType(path) {
let contentType = mime.lookup(path);
if (!contentType) {
contentType = 'application/octet-stream';
}
return contentType;
}
/**
* is input port valid.
*/
export function isValidPort(port) {
// Convert string port to number if needed
const portNum = typeof port === 'string' ? parseInt(port, 10) : port;
// verify if port is a valid number
if (!isNumber(portNum) || isNaN(portNum)) {
return false;
}
// port `0` is valid and special case
return 0 <= portNum && portNum <= 65535;
}
export function isValidBucketName(bucket) {
if (!isString(bucket)) {
return false;
}
// bucket length should be less than and no more than 63
// characters long.
if (bucket.length < 3 || bucket.length > 63) {
return false;
}
// bucket with successive periods is invalid.
if (bucket.includes('..')) {
return false;
}
// bucket cannot have ip address style.
if (/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/.test(bucket)) {
return false;
}
// bucket should begin with alphabet/number and end with alphabet/number,
// with alphabet/number/.- in the middle.
if (/^[a-z0-9][a-z0-9.-]+[a-z0-9]$/.test(bucket)) {
return true;
}
return false;
}
/**
* check if objectName is a valid object name
*/
export function isValidObjectName(objectName) {
if (!isValidPrefix(objectName)) {
return false;
}
return objectName.length !== 0;
}
/**
* check if prefix is valid
*/
export function isValidPrefix(prefix) {
if (!isString(prefix)) {
return false;
}
if (prefix.length > 1024) {
return false;
}
return true;
}
/**
* check if typeof arg number
*/
export function isNumber(arg) {
return typeof arg === 'number';
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
/**
* check if typeof arg function
*/
export function isFunction(arg) {
return typeof arg === 'function';
}
/**
* check if typeof arg string
*/
export function isString(arg) {
return typeof arg === 'string';
}
/**
* check if typeof arg object
*/
export function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
/**
* check if object is readable stream
*/
export function isReadableStream(arg) {
// eslint-disable-next-line @typescript-eslint/unbound-method
return isObject(arg) && isFunction(arg._read);
}
/**
* check if arg is boolean
*/
export function isBoolean(arg) {
return typeof arg === 'boolean';
}
export function isEmpty(o) {
return _.isEmpty(o);
}
export function isEmptyObject(o) {
return Object.values(o).filter(x => x !== undefined).length !== 0;
}
export function isDefined(o) {
return o !== null && o !== undefined;
}
/**
* check if arg is a valid date
*/
export function isValidDate(arg) {
// @ts-expect-error checknew Date(Math.NaN)
return arg instanceof Date && !isNaN(arg);
}
/**
* Create a Date string with format: 'YYYYMMDDTHHmmss' + Z
*/
export function makeDateLong(date) {
date = date || new Date();
// Gives format like: '2017-08-07T16:28:59.889Z'
const s = date.toISOString();
return s.slice(0, 4) + s.slice(5, 7) + s.slice(8, 13) + s.slice(14, 16) + s.slice(17, 19) + 'Z';
}
/**
* Create a Date string with format: 'YYYYMMDD'
*/
export function makeDateShort(date) {
date = date || new Date();
// Gives format like: '2017-08-07T16:28:59.889Z'
const s = date.toISOString();
return s.slice(0, 4) + s.slice(5, 7) + s.slice(8, 10);
}
/**
* pipesetup sets up pipe() from left to right os streams array
* pipesetup will also make sure that error emitted at any of the upstream Stream
* will be emitted at the last stream. This makes error handling simple
*/
export function pipesetup(...streams) {
// @ts-expect-error ts can't narrow this
return streams.reduce((src, dst) => {
src.on('error', err => dst.emit('error', err));
return src.pipe(dst);
});
}
/**
* return a Readable stream that emits data
*/
export function readableStream(data) {
const s = new stream.Readable();
s._read = () => {};
s.push(data);
s.push(null);
return s;
}
/**
* Process metadata to insert appropriate value to `content-type` attribute
*/
export function insertContentType(metaData, filePath) {
// check if content-type attribute present in metaData
for (const key in metaData) {
if (key.toLowerCase() === 'content-type') {
return metaData;
}
}
// if `content-type` attribute is not present in metadata, then infer it from the extension in filePath
return {
...metaData,
'content-type': probeContentType(filePath)
};
}
/**
* Function prepends metadata with the appropriate prefix if it is not already on
*/
export function prependXAMZMeta(metaData) {
if (!metaData) {
return {};
}
return _.mapKeys(metaData, (value, key) => {
if (isAmzHeader(key) || isSupportedHeader(key) || isStorageClassHeader(key)) {
return key;
}
return MetaDataHeaderPrefix + key;
});
}
/**
* Checks if it is a valid header according to the AmazonS3 API
*/
export function isAmzHeader(key) {
const temp = key.toLowerCase();
return temp.startsWith(MetaDataHeaderPrefix) || temp === 'x-amz-acl' || temp.startsWith('x-amz-server-side-encryption-') || temp === 'x-amz-server-side-encryption';
}
/**
* Checks if it is a supported Header
*/
export function isSupportedHeader(key) {
const supported_headers = ['content-type', 'cache-control', 'content-encoding', 'content-disposition', 'content-language', 'x-amz-website-redirect-location', 'if-none-match', 'if-match'];
return supported_headers.includes(key.toLowerCase());
}
/**
* Checks if it is a storage header
*/
export function isStorageClassHeader(key) {
return key.toLowerCase() === 'x-amz-storage-class';
}
export function extractMetadata(headers) {
return _.mapKeys(_.pickBy(headers, (value, key) => isSupportedHeader(key) || isStorageClassHeader(key) || isAmzHeader(key)), (value, key) => {
const lower = key.toLowerCase();
if (lower.startsWith(MetaDataHeaderPrefix)) {
return lower.slice(MetaDataHeaderPrefix.length);
}
return key;
});
}
export function getVersionId(headers = {}) {
return headers['x-amz-version-id'] || null;
}
export function getSourceVersionId(headers = {}) {
return headers['x-amz-copy-source-version-id'] || null;
}
export function sanitizeETag(etag = '') {
const replaceChars = {
'"': '',
'&quot;': '',
'&#34;': '',
'&QUOT;': '',
'&#x00022': ''
};
return etag.replace(/^("|&quot;|&#34;)|("|&quot;|&#34;)$/g, m => replaceChars[m]);
}
export function toMd5(payload) {
// use string from browser and buffer from nodejs
// browser support is tested only against minio server
return crypto.createHash('md5').update(Buffer.from(payload)).digest().toString('base64');
}
export function toSha256(payload) {
return crypto.createHash('sha256').update(payload).digest('hex');
}
/**
* toArray returns a single element array with param being the element,
* if param is just a string, and returns 'param' back if it is an array
* So, it makes sure param is always an array
*/
export function toArray(param) {
if (!Array.isArray(param)) {
return [param];
}
return param;
}
export function sanitizeObjectKey(objectName) {
// + symbol characters are not decoded as spaces in JS. so replace them first and decode to get the correct result.
const asStrName = (objectName ? objectName.toString() : '').replace(/\+/g, ' ');
return decodeURIComponent(asStrName);
}
export function sanitizeSize(size) {
return size ? Number.parseInt(size) : undefined;
}
export const PART_CONSTRAINTS = {
// absMinPartSize - absolute minimum part size (5 MiB)
ABS_MIN_PART_SIZE: 1024 * 1024 * 5,
// MIN_PART_SIZE - minimum part size 16MiB per object after which
MIN_PART_SIZE: 1024 * 1024 * 16,
// MAX_PARTS_COUNT - maximum number of parts for a single multipart session.
MAX_PARTS_COUNT: 10000,
// MAX_PART_SIZE - maximum part size 5GiB for a single multipart upload
// operation.
MAX_PART_SIZE: 1024 * 1024 * 1024 * 5,
// MAX_SINGLE_PUT_OBJECT_SIZE - maximum size 5GiB of object per PUT
// operation.
MAX_SINGLE_PUT_OBJECT_SIZE: 1024 * 1024 * 1024 * 5,
// MAX_MULTIPART_PUT_OBJECT_SIZE - maximum size 5TiB of object for
// Multipart operation.
MAX_MULTIPART_PUT_OBJECT_SIZE: 1024 * 1024 * 1024 * 1024 * 5
};
const GENERIC_SSE_HEADER = 'X-Amz-Server-Side-Encryption';
const ENCRYPTION_HEADERS = {
// sseGenericHeader is the AWS SSE header used for SSE-S3 and SSE-KMS.
sseGenericHeader: GENERIC_SSE_HEADER,
// sseKmsKeyID is the AWS SSE-KMS key id.
sseKmsKeyID: GENERIC_SSE_HEADER + '-Aws-Kms-Key-Id'
};
/**
* Return Encryption headers
* @param encConfig
* @returns an object with key value pairs that can be used in headers.
*/
export function getEncryptionHeaders(encConfig) {
const encType = encConfig.type;
if (!isEmpty(encType)) {
if (encType === ENCRYPTION_TYPES.SSEC) {
return {
[ENCRYPTION_HEADERS.sseGenericHeader]: 'AES256'
};
} else if (encType === ENCRYPTION_TYPES.KMS) {
return {
[ENCRYPTION_HEADERS.sseGenericHeader]: encConfig.SSEAlgorithm,
[ENCRYPTION_HEADERS.sseKmsKeyID]: encConfig.KMSMasterKeyID
};
}
}
return {};
}
export function partsRequired(size) {
const maxPartSize = PART_CONSTRAINTS.MAX_MULTIPART_PUT_OBJECT_SIZE / (PART_CONSTRAINTS.MAX_PARTS_COUNT - 1);
let requiredPartSize = size / maxPartSize;
if (size % maxPartSize > 0) {
requiredPartSize++;
}
requiredPartSize = Math.trunc(requiredPartSize);
return requiredPartSize;
}
/**
* calculateEvenSplits - computes splits for a source and returns
* start and end index slices. Splits happen evenly to be sure that no
* part is less than 5MiB, as that could fail the multipart request if
* it is not the last part.
*/
export function calculateEvenSplits(size, objInfo) {
if (size === 0) {
return null;
}
const reqParts = partsRequired(size);
const startIndexParts = [];
const endIndexParts = [];
let start = objInfo.Start;
if (isEmpty(start) || start === -1) {
start = 0;
}
const divisorValue = Math.trunc(size / reqParts);
const reminderValue = size % reqParts;
let nextStart = start;
for (let i = 0; i < reqParts; i++) {
let curPartSize = divisorValue;
if (i < reminderValue) {
curPartSize++;
}
const currentStart = nextStart;
const currentEnd = currentStart + curPartSize - 1;
nextStart = currentEnd + 1;
startIndexParts.push(currentStart);
endIndexParts.push(currentEnd);
}
return {
startIndex: startIndexParts,
endIndex: endIndexParts,
objInfo: objInfo
};
}
const fxp = new XMLParser({
numberParseOptions: {
eNotation: false,
hex: true,
leadingZeros: true
}
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function parseXml(xml) {
const result = fxp.parse(xml);
if (result.Error) {
throw result.Error;
}
return result;
}
/**
* get content size of object content to upload
*/
export async function getContentLength(s) {
// use length property of string | Buffer
if (typeof s === 'string' || Buffer.isBuffer(s)) {
return s.length;
}
// property of `fs.ReadStream`
const filePath = s.path;
if (filePath && typeof filePath === 'string') {
const stat = await fsp.lstat(filePath);
return stat.size;
}
// property of `fs.ReadStream`
const fd = s.fd;
if (fd && typeof fd === 'number') {
const stat = await fstat(fd);
return stat.size;
}
return null;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjcnlwdG8iLCJzdHJlYW0iLCJYTUxQYXJzZXIiLCJpcGFkZHIiLCJfIiwibWltZSIsImZzcCIsImZzdGF0IiwiRU5DUllQVElPTl9UWVBFUyIsIk1ldGFEYXRhSGVhZGVyUHJlZml4IiwiaGFzaEJpbmFyeSIsImJ1ZiIsImVuYWJsZVNIQTI1NiIsInNoYTI1NnN1bSIsImNyZWF0ZUhhc2giLCJ1cGRhdGUiLCJkaWdlc3QiLCJtZDVzdW0iLCJlbmNvZGVBc0hleCIsImMiLCJjaGFyQ29kZUF0IiwidG9TdHJpbmciLCJ0b1VwcGVyQ2FzZSIsInVyaUVzY2FwZSIsInVyaVN0ciIsImVuY29kZVVSSUNvbXBvbmVudCIsInJlcGxhY2UiLCJ1cmlSZXNvdXJjZUVzY2FwZSIsInN0cmluZyIsImdldFNjb3BlIiwicmVnaW9uIiwiZGF0ZSIsInNlcnZpY2VOYW1lIiwibWFrZURhdGVTaG9ydCIsImlzQW1hem9uRW5kcG9pbnQiLCJlbmRwb2ludCIsImlzVmlydHVhbEhvc3RTdHlsZSIsInByb3RvY29sIiwiYnVja2V0IiwicGF0aFN0eWxlIiwiaW5jbHVkZXMiLCJpc1ZhbGlkSVAiLCJpcCIsImlzVmFsaWQiLCJpc1ZhbGlkRW5kcG9pbnQiLCJpc1ZhbGlkRG9tYWluIiwiaG9zdCIsImlzU3RyaW5nIiwibGVuZ3RoIiwic2xpY2UiLCJub25BbHBoYU51bWVyaWNzIiwiY2hhciIsInByb2JlQ29udGVudFR5cGUiLCJwYXRoIiwiY29udGVudFR5cGUiLCJsb29rdXAiLCJpc1ZhbGlkUG9ydCIsInBvcnQiLCJwb3J0TnVtIiwicGFyc2VJbnQiLCJpc051bWJlciIsImlzTmFOIiwiaXNWYWxpZEJ1Y2tldE5hbWUiLCJ0ZXN0IiwiaXNWYWxpZE9iamVjdE5hbWUiLCJvYmplY3ROYW1lIiwiaXNWYWxpZFByZWZpeCIsInByZWZpeCIsImFyZyIsImlzRnVuY3Rpb24iLCJpc09iamVjdCIsImlzUmVhZGFibGVTdHJlYW0iLCJfcmVhZCIsImlzQm9vbGVhbiIsImlzRW1wdHkiLCJvIiwiaXNFbXB0eU9iamVjdCIsIk9iamVjdCIsInZhbHVlcyIsImZpbHRlciIsIngiLCJ1bmRlZmluZWQiLCJpc0RlZmluZWQiLCJpc1ZhbGlkRGF0ZSIsIkRhdGUiLCJtYWtlRGF0ZUxvbmciLCJzIiwidG9JU09TdHJpbmciLCJwaXBlc2V0dXAiLCJzdHJlYW1zIiwicmVkdWNlIiwic3JjIiwiZHN0Iiwib24iLCJlcnIiLCJlbWl0IiwicGlwZSIsInJlYWRhYmxlU3RyZWFtIiwiZGF0YSIsIlJlYWRhYmxlIiwicHVzaCIsImluc2VydENvbnRlbnRUeXBlIiwibWV0YURhdGEiLCJmaWxlUGF0aCIsImtleSIsInRvTG93ZXJDYXNlIiwicHJlcGVuZFhBTVpNZXRhIiwibWFwS2V5cyIsInZhbHVlIiwiaXNBbXpIZWFkZXIiLCJpc1N1cHBvcnRlZEhlYWRlciIsImlzU3RvcmFnZUNsYXNzSGVhZGVyIiwidGVtcCIsInN0YXJ0c1dpdGgiLCJzdXBwb3J0ZWRfaGVhZGVycyIsImV4dHJhY3RNZXRhZGF0YSIsImhlYWRlcnMiLCJwaWNrQnkiLCJsb3dlciIsImdldFZlcnNpb25JZCIsImdldFNvdXJjZVZlcnNpb25JZCIsInNhbml0aXplRVRhZyIsImV0YWciLCJyZXBsYWNlQ2hhcnMiLCJtIiwidG9NZDUiLCJwYXlsb2FkIiwiQnVmZmVyIiwiZnJvbSIsInRvU2hhMjU2IiwidG9BcnJheSIsInBhcmFtIiwiQXJyYXkiLCJpc0FycmF5Iiwic2FuaXRpemVPYmplY3RLZXkiLCJhc1N0ck5hbWUiLCJkZWNvZGVVUklDb21wb25lbnQiLCJzYW5pdGl6ZVNpemUiLCJzaXplIiwiTnVtYmVyIiwiUEFSVF9DT05TVFJBSU5UUyIsIkFCU19NSU5fUEFSVF9TSVpFIiwiTUlOX1BBUlRfU0laRSIsIk1BWF9QQVJUU19DT1VOVCIsIk1BWF9QQVJUX1NJWkUiLCJNQVhfU0lOR0xFX1BVVF9PQkpFQ1RfU0laRSIsIk1BWF9NVUxUSVBBUlRfUFVUX09CSkVDVF9TSVpFIiwiR0VORVJJQ19TU0VfSEVBREVSIiwiRU5DUllQVElPTl9IRUFERVJTIiwic3NlR2VuZXJpY0hlYWRlciIsInNzZUttc0tleUlEIiwiZ2V0RW5jcnlwdGlvbkhlYWRlcnMiLCJlbmNDb25maWciLCJlbmNUeXBlIiwidHlwZSIsIlNTRUMiLCJLTVMiLCJTU0VBbGdvcml0aG0iLCJLTVNNYXN0ZXJLZXlJRCIsInBhcnRzUmVxdWlyZWQiLCJtYXhQYXJ0U2l6ZSIsInJlcXVpcmVkUGFydFNpemUiLCJNYXRoIiwidHJ1bmMiLCJjYWxjdWxhdGVFdmVuU3BsaXRzIiwib2JqSW5mbyIsInJlcVBhcnRzIiwic3RhcnRJbmRleFBhcnRzIiwiZW5kSW5kZXhQYXJ0cyIsInN0YXJ0IiwiU3RhcnQiLCJkaXZpc29yVmFsdWUiLCJyZW1pbmRlclZhbHVlIiwibmV4dFN0YXJ0IiwiaSIsImN1clBhcnRTaXplIiwiY3VycmVudFN0YXJ0IiwiY3VycmVudEVuZCIsInN0YXJ0SW5kZXgiLCJlbmRJbmRleCIsImZ4cCIsIm51bWJlclBhcnNlT3B0aW9ucyIsImVOb3RhdGlvbiIsImhleCIsImxlYWRpbmdaZXJvcyIsInBhcnNlWG1sIiwieG1sIiwicmVzdWx0IiwicGFyc2UiLCJFcnJvciIsImdldENvbnRlbnRMZW5ndGgiLCJpc0J1ZmZlciIsInN0YXQiLCJsc3RhdCIsImZkIl0sInNvdXJjZXMiOlsiaGVscGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBNaW5JTyBKYXZhc2NyaXB0IExpYnJhcnkgZm9yIEFtYXpvbiBTMyBDb21wYXRpYmxlIENsb3VkIFN0b3JhZ2UsIChDKSAyMDE1IE1pbklPLCBJbmMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdub2RlOmNyeXB0bydcbmltcG9ydCAqIGFzIHN0cmVhbSBmcm9tICdub2RlOnN0cmVhbSdcblxuaW1wb3J0IHsgWE1MUGFyc2VyIH0gZnJvbSAnZmFzdC14bWwtcGFyc2VyJ1xuaW1wb3J0IGlwYWRkciBmcm9tICdpcGFkZHIuanMnXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnXG5pbXBvcnQgKiBhcyBtaW1lIGZyb20gJ21pbWUtdHlwZXMnXG5cbmltcG9ydCB7IGZzcCwgZnN0YXQgfSBmcm9tICcuL2FzeW5jLnRzJ1xuaW1wb3J0IHR5cGUgeyBCaW5hcnksIEVuY3J5cHRpb24sIE9iamVjdE1ldGFEYXRhLCBSZXF1ZXN0SGVhZGVycywgUmVzcG9uc2VIZWFkZXIgfSBmcm9tICcuL3R5cGUudHMnXG5pbXBvcnQgeyBFTkNSWVBUSU9OX1RZUEVTIH0gZnJvbSAnLi90eXBlLnRzJ1xuXG5jb25zdCBNZXRhRGF0YUhlYWRlclByZWZpeCA9ICd4LWFtei1tZXRhLSdcblxuZXhwb3J0IGZ1bmN0aW9uIGhhc2hCaW5hcnkoYnVmOiBCdWZmZXIsIGVuYWJsZVNIQTI1NjogYm9vbGVhbikge1xuICBsZXQgc2hhMjU2c3VtID0gJydcbiAgaWYgKGVuYWJsZVNIQTI1Nikge1xuICAgIHNoYTI1NnN1bSA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoYnV Line truncated
@@ -0,0 +1,11 @@
/**
* joinHostPort combines host and port into a network address of the
* form "host:port". If host contains a colon, as found in literal
* IPv6 addresses, then JoinHostPort returns "[host]:port".
*
* @param host
* @param port
* @returns Cleaned up host
* @internal
*/
export declare function joinHostPort(host: string, port?: number): string;
@@ -0,0 +1,23 @@
/**
* joinHostPort combines host and port into a network address of the
* form "host:port". If host contains a colon, as found in literal
* IPv6 addresses, then JoinHostPort returns "[host]:port".
*
* @param host
* @param port
* @returns Cleaned up host
* @internal
*/
export function joinHostPort(host, port) {
if (port === undefined) {
return host;
}
// We assume that host is a literal IPv6 address if host has
// colons.
if (host.includes(':')) {
return `[${host}]:${port.toString()}`;
}
return `${host}:${port.toString()}`;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJqb2luSG9zdFBvcnQiLCJob3N0IiwicG9ydCIsInVuZGVmaW5lZCIsImluY2x1ZGVzIiwidG9TdHJpbmciXSwic291cmNlcyI6WyJqb2luLWhvc3QtcG9ydC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGpvaW5Ib3N0UG9ydCBjb21iaW5lcyBob3N0IGFuZCBwb3J0IGludG8gYSBuZXR3b3JrIGFkZHJlc3Mgb2YgdGhlXG4gKiBmb3JtIFwiaG9zdDpwb3J0XCIuIElmIGhvc3QgY29udGFpbnMgYSBjb2xvbiwgYXMgZm91bmQgaW4gbGl0ZXJhbFxuICogSVB2NiBhZGRyZXNzZXMsIHRoZW4gSm9pbkhvc3RQb3J0IHJldHVybnMgXCJbaG9zdF06cG9ydFwiLlxuICpcbiAqIEBwYXJhbSBob3N0XG4gKiBAcGFyYW0gcG9ydFxuICogQHJldHVybnMgQ2xlYW5lZCB1cCBob3N0XG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGpvaW5Ib3N0UG9ydChob3N0OiBzdHJpbmcsIHBvcnQ/OiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAocG9ydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGhvc3RcbiAgfVxuXG4gIC8vIFdlIGFzc3VtZSB0aGF0IGhvc3QgaXMgYSBsaXRlcmFsIElQdjYgYWRkcmVzcyBpZiBob3N0IGhhc1xuICAvLyBjb2xvbnMuXG4gIGlmIChob3N0LmluY2x1ZGVzKCc6JykpIHtcbiAgICByZXR1cm4gYFske2hvc3R9XToke3BvcnQudG9TdHJpbmcoKX1gXG4gIH1cblxuICByZXR1cm4gYCR7aG9zdH06JHtwb3J0LnRvU3RyaW5nKCl9YFxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBU0EsWUFBWUEsQ0FBQ0MsSUFBWSxFQUFFQyxJQUFhLEVBQVU7RUFDaEUsSUFBSUEsSUFBSSxLQUFLQyxTQUFTLEVBQUU7SUFDdEIsT0FBT0YsSUFBSTtFQUNiOztFQUVBO0VBQ0E7RUFDQSxJQUFJQSxJQUFJLENBQUNHLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUN0QixPQUFRLElBQUdILElBQUssS0FBSUMsSUFBSSxDQUFDRyxRQUFRLENBQUMsQ0FBRSxFQUFDO0VBQ3ZDO0VBRUEsT0FBUSxHQUFFSixJQUFLLElBQUdDLElBQUksQ0FBQ0csUUFBUSxDQUFDLENBQUUsRUFBQztBQUNyQyJ9
@@ -0,0 +1,17 @@
import type { ObjectMetaData } from "./type.mjs";
export declare class PostPolicy {
policy: {
conditions: (string | number)[][];
expiration?: string;
};
formData: Record<string, string>;
setExpires(date: Date): void;
setKey(objectName: string): void;
setKeyStartsWith(prefix: string): void;
setBucket(bucketName: string): void;
setContentType(type: string): void;
setContentTypeStartsWith(prefix: string): void;
setContentDisposition(value: string): void;
setContentLengthRange(min: number, max: number): void;
setUserMetaData(metaData: ObjectMetaData): void;
}
@@ -0,0 +1,98 @@
// Build PostPolicy object that can be signed by presignedPostPolicy
import * as errors from "../errors.mjs";
import { isObject, isValidBucketName, isValidObjectName, isValidPrefix } from "./helper.mjs";
export class PostPolicy {
policy = {
conditions: []
};
formData = {};
// set expiration date
setExpires(date) {
if (!date) {
throw new errors.InvalidDateError('Invalid date: cannot be null');
}
this.policy.expiration = date.toISOString();
}
// set object name
setKey(objectName) {
if (!isValidObjectName(objectName)) {
throw new errors.InvalidObjectNameError(`Invalid object name : ${objectName}`);
}
this.policy.conditions.push(['eq', '$key', objectName]);
this.formData.key = objectName;
}
// set object name prefix, i.e policy allows any keys with this prefix
setKeyStartsWith(prefix) {
if (!isValidPrefix(prefix)) {
throw new errors.InvalidPrefixError(`Invalid prefix : ${prefix}`);
}
this.policy.conditions.push(['starts-with', '$key', prefix]);
this.formData.key = prefix;
}
// set bucket name
setBucket(bucketName) {
if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError(`Invalid bucket name : ${bucketName}`);
}
this.policy.conditions.push(['eq', '$bucket', bucketName]);
this.formData.bucket = bucketName;
}
// set Content-Type
setContentType(type) {
if (!type) {
throw new Error('content-type cannot be null');
}
this.policy.conditions.push(['eq', '$Content-Type', type]);
this.formData['Content-Type'] = type;
}
// set Content-Type prefix, i.e image/ allows any image
setContentTypeStartsWith(prefix) {
if (!prefix) {
throw new Error('content-type cannot be null');
}
this.policy.conditions.push(['starts-with', '$Content-Type', prefix]);
this.formData['Content-Type'] = prefix;
}
// set Content-Disposition
setContentDisposition(value) {
if (!value) {
throw new Error('content-disposition cannot be null');
}
this.policy.conditions.push(['eq', '$Content-Disposition', value]);
this.formData['Content-Disposition'] = value;
}
// set minimum/maximum length of what Content-Length can be.
setContentLengthRange(min, max) {
if (min > max) {
throw new Error('min cannot be more than max');
}
if (min < 0) {
throw new Error('min should be > 0');
}
if (max < 0) {
throw new Error('max should be > 0');
}
this.policy.conditions.push(['content-length-range', min, max]);
}
// set user defined metadata
setUserMetaData(metaData) {
if (!isObject(metaData)) {
throw new TypeError('metadata should be of type "object"');
}
Object.entries(metaData).forEach(([key, value]) => {
const amzMetaDataKey = `x-amz-meta-${key}`;
this.policy.conditions.push(['eq', `$${amzMetaDataKey}`, value]);
this.formData[amzMetaDataKey] = value.toString();
});
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJlcnJvcnMiLCJpc09iamVjdCIsImlzVmFsaWRCdWNrZXROYW1lIiwiaXNWYWxpZE9iamVjdE5hbWUiLCJpc1ZhbGlkUHJlZml4IiwiUG9zdFBvbGljeSIsInBvbGljeSIsImNvbmRpdGlvbnMiLCJmb3JtRGF0YSIsInNldEV4cGlyZXMiLCJkYXRlIiwiSW52YWxpZERhdGVFcnJvciIsImV4cGlyYXRpb24iLCJ0b0lTT1N0cmluZyIsInNldEtleSIsIm9iamVjdE5hbWUiLCJJbnZhbGlkT2JqZWN0TmFtZUVycm9yIiwicHVzaCIsImtleSIsInNldEtleVN0YXJ0c1dpdGgiLCJwcmVmaXgiLCJJbnZhbGlkUHJlZml4RXJyb3IiLCJzZXRCdWNrZXQiLCJidWNrZXROYW1lIiwiSW52YWxpZEJ1Y2tldE5hbWVFcnJvciIsImJ1Y2tldCIsInNldENvbnRlbnRUeXBlIiwidHlwZSIsIkVycm9yIiwic2V0Q29udGVudFR5cGVTdGFydHNXaXRoIiwic2V0Q29udGVudERpc3Bvc2l0aW9uIiwidmFsdWUiLCJzZXRDb250ZW50TGVuZ3RoUmFuZ2UiLCJtaW4iLCJtYXgiLCJzZXRVc2VyTWV0YURhdGEiLCJtZXRhRGF0YSIsIlR5cGVFcnJvciIsIk9iamVjdCIsImVudHJpZXMiLCJmb3JFYWNoIiwiYW16TWV0YURhdGFLZXkiLCJ0b1N0cmluZyJdLCJzb3VyY2VzIjpbInBvc3QtcG9saWN5LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEJ1aWxkIFBvc3RQb2xpY3kgb2JqZWN0IHRoYXQgY2FuIGJlIHNpZ25lZCBieSBwcmVzaWduZWRQb3N0UG9saWN5XG5pbXBvcnQgKiBhcyBlcnJvcnMgZnJvbSAnLi4vZXJyb3JzLnRzJ1xuaW1wb3J0IHsgaXNPYmplY3QsIGlzVmFsaWRCdWNrZXROYW1lLCBpc1ZhbGlkT2JqZWN0TmFtZSwgaXNWYWxpZFByZWZpeCB9IGZyb20gJy4vaGVscGVyLnRzJ1xuaW1wb3J0IHR5cGUgeyBPYmplY3RNZXRhRGF0YSB9IGZyb20gJy4vdHlwZS50cydcblxuZXhwb3J0IGNsYXNzIFBvc3RQb2xpY3kge1xuICBwdWJsaWMgcG9saWN5OiB7IGNvbmRpdGlvbnM6IChzdHJpbmcgfCBudW1iZXIpW11bXTsgZXhwaXJhdGlvbj86IHN0cmluZyB9ID0ge1xuICAgIGNvbmRpdGlvbnM6IFtdLFxuICB9XG4gIHB1YmxpYyBmb3JtRGF0YTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9XG5cbiAgLy8gc2V0IGV4cGlyYXRpb24gZGF0ZVxuICBzZXRFeHBpcmVzKGRhdGU6IERhdGUpIHtcbiAgICBpZiAoIWRhdGUpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZERhdGVFcnJvcignSW52YWxpZCBkYXRlOiBjYW5ub3QgYmUgbnVsbCcpXG4gICAgfVxuICAgIHRoaXMucG9saWN5LmV4cGlyYXRpb24gPSBkYXRlLnRvSVNPU3RyaW5nKClcbiAgfVxuXG4gIC8vIHNldCBvYmplY3QgbmFtZVxuICBzZXRLZXkob2JqZWN0TmFtZTogc3RyaW5nKSB7XG4gICAgaWYgKCFpc1ZhbGlkT2JqZWN0TmFtZShvYmplY3ROYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IGVycm9ycy5JbnZhbGlkT2JqZWN0TmFtZUVycm9yKGBJbnZhbGlkIG9iamVjdCBuYW1lIDogJHtvYmplY3ROYW1lfWApXG4gICAgfVxuICAgIHRoaXMucG9saWN5LmNvbmRpdGlvbnMucHVzaChbJ2VxJywgJyRrZXknLCBvYmplY3ROYW1lXSlcbiAgICB0aGlzLmZvcm1EYXRhLmtleSA9IG9iamVjdE5hbWVcbiAgfVxuXG4gIC8vIHNldCBvYmplY3QgbmFtZSBwcmVmaXgsIGkuZSBwb2xpY3kgYWxsb3dzIGFueSBrZXlzIHdpdGggdGhpcyBwcmVmaXhcbiAgc2V0S2V5U3RhcnRzV2l0aChwcmVmaXg6IHN0cmluZykge1xuICAgIGlmICghaXNWYWxpZFByZWZpeChwcmVmaXgpKSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRQcmVmaXhFcnJvcihgSW52YWxpZCBwcmVmaXggOiAke3ByZWZpeH1gKVxuICAgIH1cbiAgICB0aGlzLnBvbGljeS5jb25kaXRpb25zLnB1c2goWydzdGFydHMtd2l0aCcsICcka2V5JywgcHJlZml4XSlcbiAgICB0aGlzLmZvcm1EYXRhLmtleSA9IHByZWZpeFxuICB9XG5cbiAgLy8gc2V0IGJ1Y2tldCBuYW1lXG4gIHNldEJ1Y2tldChidWNrZXROYW1lOiBzdHJpbmcpIHtcbiAgICBpZiAoIWlzVmFsaWRCdWNrZXROYW1lKGJ1Y2tldE5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRCdWNrZXROYW1lRXJyb3IoYEludmFsaWQgYnVja2V0IG5hbWUgOiAke2J1Y2tldE5hbWV9YClcbiAgICB9XG4gICAgdGhpcy5wb2xpY3kuY29uZGl0aW9ucy5wdXNoKFsnZXEnLCAnJGJ1Y2tldCcsIGJ1Y2tldE5hbWVdKVxuICAgIHRoaXMuZm9ybURhdGEuYnVja2V0ID0gYnVja2V0TmFtZVxuICB9XG5cbiAgLy8gc2V0IENvbnRlbnQtVHlwZVxuICBzZXRDb250ZW50VHlwZSh0eXBlOiBzdHJpbmcpIHtcbiAgICBpZiAoIXR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY29udGVudC10eXBlIGNhbm5vdCBiZSBudWxsJylcbiAgICB9XG4gICAgdGhpcy5wb2xpY3kuY29uZGl0aW9ucy5wdXNoKFsnZXEnLCAnJENvbnRlbnQtVHlwZScsIHR5cGVdKVxuICAgIHRoaXMuZm9ybURhdGFbJ0NvbnRlbnQtVHlwZSddID0gdHlwZVxuICB9XG5cbiAgLy8gc2V0IENvbnRlbnQtVHlwZSBwcmVmaXgsIGkuZSBpbWFnZS8gYWxsb3dzIGFueSBpbWFnZVxuICBzZXRDb250ZW50VHlwZVN0YXJ0c1dpdGgocHJlZml4OiBzdHJpbmcpIHtcbiAgICBpZiAoIXByZWZpeCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb250ZW50LXR5cGUgY2Fubm90IGJlIG51bGwnKVxuICAgIH1cbiAgICB0aGlzLnBvbGljeS5jb25kaXRpb25zLnB1c2goWydzdGFydHMtd2l0aCcsICckQ29udGVudC1UeXBlJywgcHJlZml4XSlcbiAgICB0aGlzLmZvcm1EYXRhWydDb250ZW50LVR5cGUnXSA9IHByZWZpeFxuICB9XG5cbiAgLy8gc2V0IENvbnRlbnQtRGlzcG9zaXRpb25cbiAgc2V0Q29udGVudERpc3Bvc2l0aW9uKHZhbHVlOiBzdHJpbmcpIHtcbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbnRlbnQtZGlzcG9zaXRpb24gY2Fubm90IGJlIG51bGwnKVxuICAgIH1cbiAgICB0aGlzLnBvbGljeS5jb25kaXRpb25zLnB1c2goWydlcScsICckQ29udGVudC1EaXNwb3NpdGlvbicsIHZhbHVlXSlcbiAgICB0aGlzLmZvcm1EYXRhWydDb250ZW50LURpc3Bvc2l0aW9uJ10gPSB2YWx1ZVxuICB9XG5cbiAgLy8gc2V0IG1pbmltdW0vbWF4aW11bSBsZW5ndGggb2Ygd2hhdCBDb250ZW50LUxlbmd0aCBjYW4gYmUuXG4gIHNldENvbnRlbnRMZW5ndGhSYW5nZShtaW46IG51bWJlciwgbWF4OiBudW1iZXIpIHtcbiAgICBpZiAobWluID4gbWF4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pbiBjYW5ub3QgYmUgbW9yZSB0aGFuIG1heCcpXG4gICAgfVxuICAgIGlmIChtaW4gPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pbiBzaG91bGQgYmUgPiAwJylcbiAgICB9XG4gICAgaWYgKG1heCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWF4IHNob3VsZCBiZSA+IDAnKVxuICAgIH1cbiAgICB0aGlzLnBvbGljeS5jb25kaXRpb25zLnB1c2goWydjb250ZW50LWxlbmd0aC1yYW5nZScsIG1pbiwgbWF4XSlcbiAgfVxuXG4gIC8vIHNldCB1c2VyIGRlZmluZWQgbWV0YWRhdGFcbiAgc2V0VXNlck1ldGFEYXRhKG1ldGFEYXRhOiBPYmplY3RNZXRhRGF0YSkge1xuICAgIGlmICghaXNPYmplY3QobWV0YURhdGEpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtZXRhZGF0YSBzaG91bGQgYmUgb2YgdHlwZSBcIm9iamVjdFwiJylcbiAgICB9XG4gICAgT2JqZWN0LmVudHJpZXMobWV Line truncated
+11
View File
@@ -0,0 +1,11 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import type * as http from 'node:http';
import type * as https from 'node:https';
import type * as stream from 'node:stream';
import type { Transport } from "./type.mjs";
export declare function request(transport: Transport, opt: https.RequestOptions, body?: Buffer | string | stream.Readable | null): Promise<http.IncomingMessage>;
export declare const retryHttpCodes: Record<string, boolean>;
export declare function requestWithRetry(transport: Transport, opt: https.RequestOptions, body?: Buffer | string | stream.Readable | null, maxRetries?: number): Promise<http.IncomingMessage>;
+75
View File
@@ -0,0 +1,75 @@
import { pipeline } from "stream";
import { promisify } from "util";
const pipelineAsync = promisify(pipeline);
export async function request(transport, opt, body = null) {
return new Promise((resolve, reject) => {
const requestObj = transport.request(opt, response => {
resolve(response);
});
requestObj.on('error', reject);
if (!body || Buffer.isBuffer(body) || typeof body === 'string') {
requestObj.end(body);
} else {
pipelineAsync(body, requestObj).catch(reject);
}
});
}
const MAX_RETRIES = 10;
const EXP_BACK_OFF_BASE_DELAY = 1000; // Base delay for exponential backoff
const ADDITIONAL_DELAY_FACTOR = 1.0; // to avoid synchronized retries
// Retryable error codes for HTTP ( ref: minio-go)
export const retryHttpCodes = {
408: true,
429: true,
499: true,
500: true,
502: true,
503: true,
504: true,
520: true
};
const isHttpRetryable = httpResCode => {
return retryHttpCodes[httpResCode] !== undefined;
};
const sleep = ms => {
return new Promise(resolve => setTimeout(resolve, ms));
};
const getExpBackOffDelay = retryCount => {
const backOffBy = EXP_BACK_OFF_BASE_DELAY * 2 ** retryCount;
const additionalDelay = Math.random() * backOffBy * ADDITIONAL_DELAY_FACTOR;
return backOffBy + additionalDelay;
};
export async function requestWithRetry(transport, opt, body = null, maxRetries = MAX_RETRIES) {
let attempt = 0;
let isRetryable = false;
while (attempt <= maxRetries) {
try {
const response = await request(transport, opt, body);
// Check if the HTTP status code is retryable
if (isHttpRetryable(response.statusCode)) {
isRetryable = true;
throw new Error(`Retryable HTTP status: ${response.statusCode}`); // trigger retry attempt with calculated delay
}
return response; // Success, return the raw response
} catch (err) {
if (isRetryable) {
attempt++;
isRetryable = false;
if (attempt > maxRetries) {
throw new Error(`Request failed after ${maxRetries} retries: ${err}`);
}
const delay = getExpBackOffDelay(attempt);
// eslint-disable-next-line no-console
console.warn(`${new Date().toLocaleString()} Retrying request (attempt ${attempt}/${maxRetries}) after ${delay}ms due to: ${err}`);
await sleep(delay);
} else {
throw err; // re-throw if any request, syntax errors
}
}
}
throw new Error(`${MAX_RETRIES} Retries exhausted, request failed.`);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJwaXBlbGluZSIsInByb21pc2lmeSIsInBpcGVsaW5lQXN5bmMiLCJyZXF1ZXN0IiwidHJhbnNwb3J0Iiwib3B0IiwiYm9keSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicmVxdWVzdE9iaiIsInJlc3BvbnNlIiwib24iLCJCdWZmZXIiLCJpc0J1ZmZlciIsImVuZCIsImNhdGNoIiwiTUFYX1JFVFJJRVMiLCJFWFBfQkFDS19PRkZfQkFTRV9ERUxBWSIsIkFERElUSU9OQUxfREVMQVlfRkFDVE9SIiwicmV0cnlIdHRwQ29kZXMiLCJpc0h0dHBSZXRyeWFibGUiLCJodHRwUmVzQ29kZSIsInVuZGVmaW5lZCIsInNsZWVwIiwibXMiLCJzZXRUaW1lb3V0IiwiZ2V0RXhwQmFja09mZkRlbGF5IiwicmV0cnlDb3VudCIsImJhY2tPZmZCeSIsImFkZGl0aW9uYWxEZWxheSIsIk1hdGgiLCJyYW5kb20iLCJyZXF1ZXN0V2l0aFJldHJ5IiwibWF4UmV0cmllcyIsImF0dGVtcHQiLCJpc1JldHJ5YWJsZSIsInN0YXR1c0NvZGUiLCJFcnJvciIsImVyciIsImRlbGF5IiwiY29uc29sZSIsIndhcm4iLCJEYXRlIiwidG9Mb2NhbGVTdHJpbmciXSwic291cmNlcyI6WyJyZXF1ZXN0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlICogYXMgaHR0cCBmcm9tICdub2RlOmh0dHAnXG5pbXBvcnQgdHlwZSAqIGFzIGh0dHBzIGZyb20gJ25vZGU6aHR0cHMnXG5pbXBvcnQgdHlwZSAqIGFzIHN0cmVhbSBmcm9tICdub2RlOnN0cmVhbSdcbmltcG9ydCB7IHBpcGVsaW5lIH0gZnJvbSAnbm9kZTpzdHJlYW0nXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICdub2RlOnV0aWwnXG5cbmltcG9ydCB0eXBlIHsgVHJhbnNwb3J0IH0gZnJvbSAnLi90eXBlLnRzJ1xuXG5jb25zdCBwaXBlbGluZUFzeW5jID0gcHJvbWlzaWZ5KHBpcGVsaW5lKVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVxdWVzdChcbiAgdHJhbnNwb3J0OiBUcmFuc3BvcnQsXG4gIG9wdDogaHR0cHMuUmVxdWVzdE9wdGlvbnMsXG4gIGJvZHk6IEJ1ZmZlciB8IHN0cmluZyB8IHN0cmVhbS5SZWFkYWJsZSB8IG51bGwgPSBudWxsLFxuKTogUHJvbWlzZTxodHRwLkluY29taW5nTWVzc2FnZT4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8aHR0cC5JbmNvbWluZ01lc3NhZ2U+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCByZXF1ZXN0T2JqID0gdHJhbnNwb3J0LnJlcXVlc3Qob3B0LCAocmVzcG9uc2UpID0+IHtcbiAgICAgIHJlc29sdmUocmVzcG9uc2UpXG4gICAgfSlcblxuICAgIHJlcXVlc3RPYmoub24oJ2Vycm9yJywgcmVqZWN0KVxuXG4gICAgaWYgKCFib2R5IHx8IEJ1ZmZlci5pc0J1ZmZlcihib2R5KSB8fCB0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJlcXVlc3RPYmouZW5kKGJvZHkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHBpcGVsaW5lQXN5bmMoYm9keSwgcmVxdWVzdE9iaikuY2F0Y2gocmVqZWN0KVxuICAgIH1cbiAgfSlcbn1cblxuY29uc3QgTUFYX1JFVFJJRVMgPSAxMFxuY29uc3QgRVhQX0JBQ0tfT0ZGX0JBU0VfREVMQVkgPSAxMDAwIC8vIEJhc2UgZGVsYXkgZm9yIGV4cG9uZW50aWFsIGJhY2tvZmZcbmNvbnN0IEFERElUSU9OQUxfREVMQVlfRkFDVE9SID0gMS4wIC8vIHRvIGF2b2lkIHN5bmNocm9uaXplZCByZXRyaWVzXG5cbi8vIFJldHJ5YWJsZSBlcnJvciBjb2RlcyBmb3IgSFRUUCAoIHJlZjogbWluaW8tZ28pXG5leHBvcnQgY29uc3QgcmV0cnlIdHRwQ29kZXM6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+ID0ge1xuICA0MDg6IHRydWUsXG4gIDQyOTogdHJ1ZSxcbiAgNDk5OiB0cnVlLFxuICA1MDA6IHRydWUsXG4gIDUwMjogdHJ1ZSxcbiAgNTAzOiB0cnVlLFxuICA1MDQ6IHRydWUsXG4gIDUyMDogdHJ1ZSxcbn1cblxuY29uc3QgaXNIdHRwUmV0cnlhYmxlID0gKGh0dHBSZXNDb2RlOiBudW1iZXIpID0+IHtcbiAgcmV0dXJuIHJldHJ5SHR0cENvZGVzW2h0dHBSZXNDb2RlXSAhPT0gdW5kZWZpbmVkXG59XG5cbmNvbnN0IHNsZWVwID0gKG1zOiBudW1iZXIpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSlcbn1cblxuY29uc3QgZ2V0RXhwQmFja09mZkRlbGF5ID0gKHJldHJ5Q291bnQ6IG51bWJlcikgPT4ge1xuICBjb25zdCBiYWNrT2ZmQnkgPSBFWFBfQkFDS19PRkZfQkFTRV9ERUxBWSAqIDIgKiogcmV0cnlDb3VudFxuICBjb25zdCBhZGRpdGlvbmFsRGVsYXkgPSBNYXRoLnJhbmRvbSgpICogYmFja09mZkJ5ICogQURESVRJT05BTF9ERUxBWV9GQUNUT1JcbiAgcmV0dXJuIGJhY2tPZmZCeSArIGFkZGl0aW9uYWxEZWxheVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVxdWVzdFdpdGhSZXRyeShcbiAgdHJhbnNwb3J0OiBUcmFuc3BvcnQsXG4gIG9wdDogaHR0cHMuUmVxdWVzdE9wdGlvbnMsXG4gIGJvZHk6IEJ1ZmZlciB8IHN0cmluZyB8IHN0cmVhbS5SZWFkYWJsZSB8IG51bGwgPSBudWxsLFxuICBtYXhSZXRyaWVzOiBudW1iZXIgPSBNQVhfUkVUUklFUyxcbik6IFByb21pc2U8aHR0cC5JbmNvbWluZ01lc3NhZ2U+IHtcbiAgbGV0IGF0dGVtcHQgPSAwXG4gIGxldCBpc1JldHJ5YWJsZSA9IGZhbHNlXG4gIHdoaWxlIChhdHRlbXB0IDw9IG1heFJldHJpZXMpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0KHRyYW5zcG9ydCwgb3B0LCBib2R5KVxuICAgICAgLy8gQ2hlY2sgaWYgdGhlIEhUVFAgc3RhdHVzIGNvZGUgaXMgcmV0cnlhYmxlXG4gICAgICBpZiAoaXNIdHRwUmV0cnlhYmxlKHJlc3BvbnNlLnN0YXR1c0NvZGUgYXMgbnVtYmVyKSkge1xuICAgICAgICBpc1JldHJ5YWJsZSA9IHRydWVcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXRyeWFibGUgSFRUUCBzdGF0dXM6ICR7cmVzcG9uc2Uuc3RhdHVzQ29kZX1gKSAvLyB0cmlnZ2VyIHJldHJ5IGF0dGVtcHQgd2l0aCBjYWxjdWxhdGVkIGRlbGF5XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNwb25zZSAvLyBTdWNjZXNzLCByZXR1cm4gdGhlIHJhdyByZXNwb25zZVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGlzUmV0cnlhYmxlKSB7XG4gICAgICAgIGF0dGVtcHQrK1xuICAgICAgICBpc1JldHJ5YWJsZSA9IGZhbHNlXG5cbiAgICAgICAgaWYgKGF0dGVtcHQgPiBtYXhSZXRyaWVzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXF1ZXN0IGZhaWxlZCBhZnRlciAke21heFJldHJpZXN9IHJldHJpZXM6ICR7ZXJyfWApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVsYXkgPSBnZXRFeHBCYWNrT2ZmRGVsYXkoYXR0ZW1wdClcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGAke25ldyBEYXRlKCkudG9Mb2NhbGVTdHJpbmcoKX0gUmV0cnlpbmcgcmVxdWVzdCAoYXR0ZW1wdCAke2F0dGVtcHR9LyR7bWF4UmV0cmllc30pIGFmdGVyICR7ZGVsYXl9bXMgZHVlIHRvOiAke2Vycn1gLFxuICAgICAgICApXG4gICAgICAgIGF3YWl0IHNsZWVwKGRlbGF5KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyIC8vIHJlLXRocm93IGlmIGFueSByZXF1ZXN0LCBzeW50YXggZXJyb3JzXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGAke01BWF9SRVRSSUVTfSBSZXRyaWVzIGV4aGF1c3RlZCwgcmVxdWVzdCBmYWl Line truncated
@@ -0,0 +1,8 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import type http from 'node:http';
import type stream from 'node:stream';
export declare function readAsBuffer(res: stream.Readable): Promise<Buffer>;
export declare function readAsString(res: http.IncomingMessage): Promise<string>;
export declare function drainResponse(res: stream.Readable): Promise<void>;
+16
View File
@@ -0,0 +1,16 @@
export async function readAsBuffer(res) {
return new Promise((resolve, reject) => {
const body = [];
res.on('data', chunk => body.push(chunk)).on('error', e => reject(e)).on('end', () => resolve(Buffer.concat(body)));
});
}
export async function readAsString(res) {
const body = await readAsBuffer(res);
return body.toString();
}
export async function drainResponse(res) {
return new Promise((resolve, reject) => {
res.on('data', () => {}).on('error', e => reject(e)).on('end', () => resolve());
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJyZWFkQXNCdWZmZXIiLCJyZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImJvZHkiLCJvbiIsImNodW5rIiwicHVzaCIsImUiLCJCdWZmZXIiLCJjb25jYXQiLCJyZWFkQXNTdHJpbmciLCJ0b1N0cmluZyIsImRyYWluUmVzcG9uc2UiXSwic291cmNlcyI6WyJyZXNwb25zZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSBodHRwIGZyb20gJ25vZGU6aHR0cCdcbmltcG9ydCB0eXBlIHN0cmVhbSBmcm9tICdub2RlOnN0cmVhbSdcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRBc0J1ZmZlcihyZXM6IHN0cmVhbS5SZWFkYWJsZSk6IFByb21pc2U8QnVmZmVyPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgYm9keTogQnVmZmVyW10gPSBbXVxuICAgIHJlc1xuICAgICAgLm9uKCdkYXRhJywgKGNodW5rOiBCdWZmZXIpID0+IGJvZHkucHVzaChjaHVuaykpXG4gICAgICAub24oJ2Vycm9yJywgKGUpID0+IHJlamVjdChlKSlcbiAgICAgIC5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGJvZHkpKSlcbiAgfSlcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRBc1N0cmluZyhyZXM6IGh0dHAuSW5jb21pbmdNZXNzYWdlKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgYm9keSA9IGF3YWl0IHJlYWRBc0J1ZmZlcihyZXMpXG4gIHJldHVybiBib2R5LnRvU3RyaW5nKClcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRyYWluUmVzcG9uc2UocmVzOiBzdHJlYW0uUmVhZGFibGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICByZXNcbiAgICAgIC5vbignZGF0YScsICgpID0+IHt9KVxuICAgICAgLm9uKCdlcnJvcicsIChlKSA9PiByZWplY3QoZSkpXG4gICAgICAub24oJ2VuZCcsICgpID0+IHJlc29sdmUoKSlcbiAgfSlcbn1cbiJdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxlQUFlQSxZQUFZQSxDQUFDQyxHQUFvQixFQUFtQjtFQUN4RSxPQUFPLElBQUlDLE9BQU8sQ0FBQyxDQUFDQyxPQUFPLEVBQUVDLE1BQU0sS0FBSztJQUN0QyxNQUFNQyxJQUFjLEdBQUcsRUFBRTtJQUN6QkosR0FBRyxDQUNBSyxFQUFFLENBQUMsTUFBTSxFQUFHQyxLQUFhLElBQUtGLElBQUksQ0FBQ0csSUFBSSxDQUFDRCxLQUFLLENBQUMsQ0FBQyxDQUMvQ0QsRUFBRSxDQUFDLE9BQU8sRUFBR0csQ0FBQyxJQUFLTCxNQUFNLENBQUNLLENBQUMsQ0FBQyxDQUFDLENBQzdCSCxFQUFFLENBQUMsS0FBSyxFQUFFLE1BQU1ILE9BQU8sQ0FBQ08sTUFBTSxDQUFDQyxNQUFNLENBQUNOLElBQUksQ0FBQyxDQUFDLENBQUM7RUFDbEQsQ0FBQyxDQUFDO0FBQ0o7QUFFQSxPQUFPLGVBQWVPLFlBQVlBLENBQUNYLEdBQXlCLEVBQW1CO0VBQzdFLE1BQU1JLElBQUksR0FBRyxNQUFNTCxZQUFZLENBQUNDLEdBQUcsQ0FBQztFQUNwQyxPQUFPSSxJQUFJLENBQUNRLFFBQVEsQ0FBQyxDQUFDO0FBQ3hCO0FBRUEsT0FBTyxlQUFlQyxhQUFhQSxDQUFDYixHQUFvQixFQUFpQjtFQUN2RSxPQUFPLElBQUlDLE9BQU8sQ0FBQyxDQUFDQyxPQUFPLEVBQUVDLE1BQU0sS0FBSztJQUN0Q0gsR0FBRyxDQUNBSyxFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FDcEJBLEVBQUUsQ0FBQyxPQUFPLEVBQUdHLENBQUMsSUFBS0wsTUFBTSxDQUFDSyxDQUFDLENBQUMsQ0FBQyxDQUM3QkgsRUFBRSxDQUFDLEtBQUssRUFBRSxNQUFNSCxPQUFPLENBQUMsQ0FBQyxDQUFDO0VBQy9CLENBQUMsQ0FBQztBQUNKIn0=
@@ -0,0 +1,38 @@
declare const awsS3Endpoint: {
'af-south-1': string;
'ap-east-1': string;
'ap-south-1': string;
'ap-south-2': string;
'ap-southeast-1': string;
'ap-southeast-2': string;
'ap-southeast-3': string;
'ap-southeast-4': string;
'ap-southeast-5': string;
'ap-northeast-1': string;
'ap-northeast-2': string;
'ap-northeast-3': string;
'ca-central-1': string;
'ca-west-1': string;
'cn-north-1': string;
'eu-central-1': string;
'eu-central-2': string;
'eu-north-1': string;
'eu-south-1': string;
'eu-south-2': string;
'eu-west-1': string;
'eu-west-2': string;
'eu-west-3': string;
'il-central-1': string;
'me-central-1': string;
'me-south-1': string;
'sa-east-1': string;
'us-east-1': string;
'us-east-2': string;
'us-west-1': string;
'us-west-2': string;
'us-gov-east-1': string;
'us-gov-west-1': string;
};
export type Region = keyof typeof awsS3Endpoint | string;
export declare function getS3Endpoint(region: Region): string;
export {};
@@ -0,0 +1,68 @@
/*
* MinIO Javascript Library for Amazon S3 Compatible Cloud Storage, (C) 2015, 2016 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { isString } from "./helper.mjs";
// List of currently supported endpoints.
const awsS3Endpoint = {
'af-south-1': 's3.af-south-1.amazonaws.com',
'ap-east-1': 's3.ap-east-1.amazonaws.com',
'ap-south-1': 's3.ap-south-1.amazonaws.com',
'ap-south-2': 's3.ap-south-2.amazonaws.com',
'ap-southeast-1': 's3.ap-southeast-1.amazonaws.com',
'ap-southeast-2': 's3.ap-southeast-2.amazonaws.com',
'ap-southeast-3': 's3.ap-southeast-3.amazonaws.com',
'ap-southeast-4': 's3.ap-southeast-4.amazonaws.com',
'ap-southeast-5': 's3.ap-southeast-5.amazonaws.com',
'ap-northeast-1': 's3.ap-northeast-1.amazonaws.com',
'ap-northeast-2': 's3.ap-northeast-2.amazonaws.com',
'ap-northeast-3': 's3.ap-northeast-3.amazonaws.com',
'ca-central-1': 's3.ca-central-1.amazonaws.com',
'ca-west-1': 's3.ca-west-1.amazonaws.com',
'cn-north-1': 's3.cn-north-1.amazonaws.com.cn',
'eu-central-1': 's3.eu-central-1.amazonaws.com',
'eu-central-2': 's3.eu-central-2.amazonaws.com',
'eu-north-1': 's3.eu-north-1.amazonaws.com',
'eu-south-1': 's3.eu-south-1.amazonaws.com',
'eu-south-2': 's3.eu-south-2.amazonaws.com',
'eu-west-1': 's3.eu-west-1.amazonaws.com',
'eu-west-2': 's3.eu-west-2.amazonaws.com',
'eu-west-3': 's3.eu-west-3.amazonaws.com',
'il-central-1': 's3.il-central-1.amazonaws.com',
'me-central-1': 's3.me-central-1.amazonaws.com',
'me-south-1': 's3.me-south-1.amazonaws.com',
'sa-east-1': 's3.sa-east-1.amazonaws.com',
'us-east-1': 's3.us-east-1.amazonaws.com',
'us-east-2': 's3.us-east-2.amazonaws.com',
'us-west-1': 's3.us-west-1.amazonaws.com',
'us-west-2': 's3.us-west-2.amazonaws.com',
'us-gov-east-1': 's3.us-gov-east-1.amazonaws.com',
'us-gov-west-1': 's3.us-gov-west-1.amazonaws.com'
// Add new endpoints here.
};
// getS3Endpoint get relevant endpoint for the region.
export function getS3Endpoint(region) {
if (!isString(region)) {
throw new TypeError(`Invalid region: ${region}`);
}
const endpoint = awsS3Endpoint[region];
if (endpoint) {
return endpoint;
}
return 's3.amazonaws.com';
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJpc1N0cmluZyIsImF3c1MzRW5kcG9pbnQiLCJnZXRTM0VuZHBvaW50IiwicmVnaW9uIiwiVHlwZUVycm9yIiwiZW5kcG9pbnQiXSwic291cmNlcyI6WyJzMy1lbmRwb2ludHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIE1pbklPIEphdmFzY3JpcHQgTGlicmFyeSBmb3IgQW1hem9uIFMzIENvbXBhdGlibGUgQ2xvdWQgU3RvcmFnZSwgKEMpIDIwMTUsIDIwMTYgTWluSU8sIEluYy5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tICcuL2hlbHBlci50cydcblxuLy8gTGlzdCBvZiBjdXJyZW50bHkgc3VwcG9ydGVkIGVuZHBvaW50cy5cbmNvbnN0IGF3c1MzRW5kcG9pbnQgPSB7XG4gICdhZi1zb3V0aC0xJzogJ3MzLmFmLXNvdXRoLTEuYW1hem9uYXdzLmNvbScsXG4gICdhcC1lYXN0LTEnOiAnczMuYXAtZWFzdC0xLmFtYXpvbmF3cy5jb20nLFxuICAnYXAtc291dGgtMSc6ICdzMy5hcC1zb3V0aC0xLmFtYXpvbmF3cy5jb20nLFxuICAnYXAtc291dGgtMic6ICdzMy5hcC1zb3V0aC0yLmFtYXpvbmF3cy5jb20nLFxuICAnYXAtc291dGhlYXN0LTEnOiAnczMuYXAtc291dGhlYXN0LTEuYW1hem9uYXdzLmNvbScsXG4gICdhcC1zb3V0aGVhc3QtMic6ICdzMy5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tJyxcbiAgJ2FwLXNvdXRoZWFzdC0zJzogJ3MzLmFwLXNvdXRoZWFzdC0zLmFtYXpvbmF3cy5jb20nLFxuICAnYXAtc291dGhlYXN0LTQnOiAnczMuYXAtc291dGhlYXN0LTQuYW1hem9uYXdzLmNvbScsXG4gICdhcC1zb3V0aGVhc3QtNSc6ICdzMy5hcC1zb3V0aGVhc3QtNS5hbWF6b25hd3MuY29tJyxcbiAgJ2FwLW5vcnRoZWFzdC0xJzogJ3MzLmFwLW5vcnRoZWFzdC0xLmFtYXpvbmF3cy5jb20nLFxuICAnYXAtbm9ydGhlYXN0LTInOiAnczMuYXAtbm9ydGhlYXN0LTIuYW1hem9uYXdzLmNvbScsXG4gICdhcC1ub3J0aGVhc3QtMyc6ICdzMy5hcC1ub3J0aGVhc3QtMy5hbWF6b25hd3MuY29tJyxcbiAgJ2NhLWNlbnRyYWwtMSc6ICdzMy5jYS1jZW50cmFsLTEuYW1hem9uYXdzLmNvbScsXG4gICdjYS13ZXN0LTEnOiAnczMuY2Etd2VzdC0xLmFtYXpvbmF3cy5jb20nLFxuICAnY24tbm9ydGgtMSc6ICdzMy5jbi1ub3J0aC0xLmFtYXpvbmF3cy5jb20uY24nLFxuICAnZXUtY2VudHJhbC0xJzogJ3MzLmV1LWNlbnRyYWwtMS5hbWF6b25hd3MuY29tJyxcbiAgJ2V1LWNlbnRyYWwtMic6ICdzMy5ldS1jZW50cmFsLTIuYW1hem9uYXdzLmNvbScsXG4gICdldS1ub3J0aC0xJzogJ3MzLmV1LW5vcnRoLTEuYW1hem9uYXdzLmNvbScsXG4gICdldS1zb3V0aC0xJzogJ3MzLmV1LXNvdXRoLTEuYW1hem9uYXdzLmNvbScsXG4gICdldS1zb3V0aC0yJzogJ3MzLmV1LXNvdXRoLTIuYW1hem9uYXdzLmNvbScsXG4gICdldS13ZXN0LTEnOiAnczMuZXUtd2VzdC0xLmFtYXpvbmF3cy5jb20nLFxuICAnZXUtd2VzdC0yJzogJ3MzLmV1LXdlc3QtMi5hbWF6b25hd3MuY29tJyxcbiAgJ2V1LXdlc3QtMyc6ICdzMy5ldS13ZXN0LTMuYW1hem9uYXdzLmNvbScsXG4gICdpbC1jZW50cmFsLTEnOiAnczMuaWwtY2VudHJhbC0xLmFtYXpvbmF3cy5jb20nLFxuICAnbWUtY2VudHJhbC0xJzogJ3MzLm1lLWNlbnRyYWwtMS5hbWF6b25hd3MuY29tJyxcbiAgJ21lLXNvdXRoLTEnOiAnczMubWUtc291dGgtMS5hbWF6b25hd3MuY29tJyxcbiAgJ3NhLWVhc3QtMSc6ICdzMy5zYS1lYXN0LTEuYW1hem9uYXdzLmNvbScsXG4gICd1cy1lYXN0LTEnOiAnczMudXMtZWFzdC0xLmFtYXpvbmF3cy5jb20nLFxuICAndXMtZWFzdC0yJzogJ3MzLnVzLWVhc3QtMi5hbWF6b25hd3MuY29tJyxcbiAgJ3VzLXdlc3QtMSc6ICdzMy51cy13ZXN0LTEuYW1hem9uYXdzLmNvbScsXG4gICd1cy13ZXN0LTInOiAnczMudXMtd2VzdC0yLmFtYXpvbmF3cy5jb20nLFxuICAndXMtZ292LWVhc3QtMSc6ICdzMy51cy1nb3YtZWFzdC0xLmFtYXpvbmF3cy5jb20nLFxuICAndXMtZ292LXdlc3QtMSc6ICdzMy51cy1nb3Ytd2VzdC0xLmFtYXpvbmF3cy5jb20nLFxuICAvLyBBZGQgbmV3IGVuZHBvaW50cyBoZXJlLlxufVxuXG5leHBvcnQgdHlwZSBSZWdpb24gPSBrZXlvZiB0eXBlb2YgYXdzUzNFbmRwb2ludCB8IHN0cmluZ1xuXG4vLyBnZXRTM0VuZHBvaW50IGdldCByZWxldmFudCBlbmRwb2ludCBmb3IgdGhlIHJlZ2lvbi5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTM0VuZHBvaW50KHJlZ2lvbjogUmVnaW9uKTogc3RyaW5nIHtcbiAgaWYgKCFpc1N0cmluZyhyZWdpb24pKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCByZWdpb246ICR7cmVnaW9ufWApXG4gIH1cblxuICBjb25zdCBlbmRwb2ludCA9IChhd3NTM0VuZHBvaW50IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pW3JlZ2lvbl1cbiAgaWYgKGVuZHBvaW50KSB7XG4gICAgcmV0dXJuIGVuZHBvaW50XG4gIH1cbiAgcmV0dXJuICdzMy5hbWF6b25hd3MuY29tJ1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBU0EsUUFBUSxRQUFRLGNBQWE7O0FBRXRDO0FBQ0EsTUFBTUMsYUFBYSxHQUFHO0VBQ3BCLFlBQVksRUFBRSw2QkFBNkI7RUFDM0MsV0FBVyxFQUFFLDRCQUE0QjtFQUN6QyxZQUFZLEVBQUUsNkJBQTZCO0VBQzNDLFlBQVksRUFBRSw2QkFBNkI7RUFDM0MsZ0JBQWdCLEVBQUUsaUNBQWlDO0VBQ25ELGdCQUFnQixFQUFFLGlDQUFpQztFQUNuRCxnQkFBZ0IsRUFBRSxpQ0FBaUM7RUFDbkQsZ0JBQWdCLEVBQUUsaUNBQWlDO0VBQ25ELGdCQUFnQixFQUFFLGlDQUFpQztFQUNuRCxnQkFBZ0IsRUFBRSxpQ0FBaUM7RUFDbkQsZ0JBQWdCLEVBQUUsaUNBQWlDO0VBQ25ELGdCQUFnQixFQUFFLGlDQUFpQztFQUNuRCxjQUFjLEVBQUUsK0JBQStCO0VBQy9DLFdBQVcsRUFBRSw0QkFBNEI7RUFDekMsWUFBWSxFQUFFLGdDQUFnQztFQUM5QyxjQUFjLEVBQUUsK0JBQStCO0VBQy9DLGNBQWMsRUFBRSwrQkFBK0I7RUFDL0MsWUFBWSxFQUFFLDZCQUE2QjtFQUMzQyxZQUFZLEVBQUUsNkJBQTZCO0VBQzNDLFlBQVksRUFBRSw2QkFBNkI7RUFDM0MsV0FBVyxFQUFFLDRCQUE0QjtFQUN6QyxXQUFXLEV Line truncated
+447
View File
@@ -0,0 +1,447 @@
/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import type * as http from 'node:http';
import type { Readable as ReadableStream } from 'node:stream';
import type { CopyDestinationOptions, CopySourceOptions } from "../helpers.mjs";
import type { CopyConditions } from "./copy-conditions.mjs";
export type VersionIdentificator = {
versionId?: string;
};
export type GetObjectOpts = VersionIdentificator & {
SSECustomerAlgorithm?: string;
SSECustomerKey?: string;
SSECustomerKeyMD5?: string;
};
export type Binary = string | Buffer;
export type ResponseHeader = Record<string, string>;
export type ObjectMetaData = Record<string, string | number>;
export type RequestHeaders = Record<string, string | boolean | number | undefined>;
export type Encryption = {
type: ENCRYPTION_TYPES.SSEC;
} | {
type: ENCRYPTION_TYPES.KMS;
SSEAlgorithm?: string;
KMSMasterKeyID?: string;
};
export type EnabledOrDisabledStatus = 'Enabled' | 'Disabled';
export declare enum ENCRYPTION_TYPES {
/**
* SSEC represents server-side-encryption with customer provided keys
*/
SSEC = "SSE-C",
/**
* KMS represents server-side-encryption with managed keys
*/
KMS = "KMS",
}
export declare enum RETENTION_MODES {
GOVERNANCE = "GOVERNANCE",
COMPLIANCE = "COMPLIANCE",
}
export declare enum RETENTION_VALIDITY_UNITS {
DAYS = "Days",
YEARS = "Years",
}
export declare enum LEGAL_HOLD_STATUS {
ENABLED = "ON",
DISABLED = "OFF",
}
export type Transport = Pick<typeof http, 'request'>;
export interface IRequest {
protocol: string;
port?: number | string;
method: string;
path: string;
headers: RequestHeaders;
}
export type ICanonicalRequest = string;
export interface IncompleteUploadedBucketItem {
key: string;
uploadId: string;
size: number;
}
export interface MetadataItem {
Key: string;
Value: string;
}
export interface ItemBucketMetadataList {
Items: MetadataItem[];
}
export interface ItemBucketMetadata {
[key: string]: any;
}
export interface ItemBucketTags {
[key: string]: any;
}
export interface BucketItemFromList {
name: string;
creationDate: Date;
}
export interface BucketItemCopy {
etag: string;
lastModified: Date;
}
export type BucketItem = {
name: string;
size: number;
etag: string;
prefix?: never;
lastModified: Date;
} | {
name?: never;
etag?: never;
lastModified?: never;
prefix: string;
size: 0;
};
export type BucketItemWithMetadata = BucketItem & {
metadata?: ItemBucketMetadata | ItemBucketMetadataList;
tags?: ItemBucketTags;
};
export interface BucketStream<T> extends ReadableStream {
on(event: 'data', listener: (item: T) => void): this;
on(event: 'end' | 'pause' | 'readable' | 'resume' | 'close', listener: () => void): this;
on(event: 'error', listener: (err: Error) => void): this;
on(event: string | symbol, listener: (...args: any[]) => void): this;
}
export interface BucketItemStat {
size: number;
etag: string;
lastModified: Date;
metaData: ItemBucketMetadata;
versionId?: string | null;
}
export type StatObjectOpts = {
versionId?: string;
};
export type ReplicationRuleStatus = {
Status: EnabledOrDisabledStatus;
};
export type Tag = {
Key: string;
Value: string;
};
export type Tags = Record<string, string>;
export type ReplicationRuleDestination = {
Bucket: string;
StorageClass: string;
};
export type ReplicationRuleAnd = {
Prefix: string;
Tags: Tag[];
};
export type ReplicationRuleFilter = {
Prefix: string;
And: ReplicationRuleAnd;
Tag: Tag;
};
export type ReplicaModifications = {
Status: ReplicationRuleStatus;
};
export type SourceSelectionCriteria = {
ReplicaModifications: ReplicaModifications;
};
export type ExistingObjectReplication = {
Status: ReplicationRuleStatus;
};
export type ReplicationRule = {
ID: string;
Status: ReplicationRuleStatus;
Priority: number;
DeleteMarkerReplication: ReplicationRuleStatus;
DeleteReplication: ReplicationRuleStatus;
Destination: ReplicationRuleDestination;
Filter: ReplicationRuleFilter;
SourceSelectionCriteria: SourceSelectionCriteria;
ExistingObjectReplication: ExistingObjectReplication;
};
export type ReplicationConfigOpts = {
role: string;
rules: ReplicationRule[];
};
export type ReplicationConfig = {
ReplicationConfiguration: ReplicationConfigOpts;
};
export type ResultCallback<T> = (error: Error | null, result: T) => void;
export type GetObjectLegalHoldOptions = {
versionId: string;
};
/**
* @deprecated keep for backward compatible, use `LEGAL_HOLD_STATUS` instead
*/
export type LegalHoldStatus = LEGAL_HOLD_STATUS;
export type PutObjectLegalHoldOptions = {
versionId?: string;
status: LEGAL_HOLD_STATUS;
};
export interface UploadedObjectInfo {
etag: string;
versionId: string | null;
}
export interface RetentionOptions {
versionId: string;
mode?: RETENTION_MODES;
retainUntilDate?: IsoDate;
governanceBypass?: boolean;
}
export type Retention = RetentionOptions | EmptyObject;
export type IsoDate = string;
export type EmptyObject = Record<string, never>;
export type ObjectLockInfo = {
objectLockEnabled: EnabledOrDisabledStatus;
mode: RETENTION_MODES;
unit: RETENTION_VALIDITY_UNITS;
validity: number;
} | EmptyObject;
export type ObjectLockConfigParam = {
ObjectLockEnabled?: 'Enabled' | undefined;
Rule?: {
DefaultRetention: {
Mode: RETENTION_MODES;
Days: number;
Years: number;
} | EmptyObject;
} | EmptyObject;
};
export type VersioningEnabled = 'Enabled';
export type VersioningSuspended = 'Suspended';
export type TaggingOpts = {
versionId: string;
};
export type PutTaggingParams = {
bucketName: string;
objectName?: string;
tags: Tags;
putOpts?: TaggingOpts;
};
export type RemoveTaggingParams = {
bucketName: string;
objectName?: string;
removeOpts?: TaggingOpts;
};
export type InputSerialization = {
CompressionType?: 'NONE' | 'GZIP' | 'BZIP2';
CSV?: {
AllowQuotedRecordDelimiter?: boolean;
Comments?: string;
FieldDelimiter?: string;
FileHeaderInfo?: 'NONE' | 'IGNORE' | 'USE';
QuoteCharacter?: string;
QuoteEscapeCharacter?: string;
RecordDelimiter?: string;
};
JSON?: {
Type: 'DOCUMENT' | 'LINES';
};
Parquet?: EmptyObject;
};
export type OutputSerialization = {
CSV?: {
FieldDelimiter?: string;
QuoteCharacter?: string;
QuoteEscapeCharacter?: string;
QuoteFields?: string;
RecordDelimiter?: string;
};
JSON?: {
RecordDelimiter?: string;
};
};
export type SelectProgress = {
Enabled: boolean;
};
export type ScanRange = {
Start: number;
End: number;
};
export type SelectOptions = {
expression: string;
expressionType?: string;
inputSerialization: InputSerialization;
outputSerialization: OutputSerialization;
requestProgress?: SelectProgress;
scanRange?: ScanRange;
};
export type Expiration = {
Date?: string;
Days: number;
DeleteMarker?: boolean;
DeleteAll?: boolean;
};
export type RuleFilterAnd = {
Prefix: string;
Tags: Tag[];
};
export type RuleFilter = {
And?: RuleFilterAnd;
Prefix: string;
Tag?: Tag[];
};
export type NoncurrentVersionExpiration = {
NoncurrentDays: number;
NewerNoncurrentVersions?: number;
};
export type NoncurrentVersionTransition = {
StorageClass: string;
NoncurrentDays?: number;
NewerNoncurrentVersions?: number;
};
export type Transition = {
Date?: string;
StorageClass: string;
Days: number;
};
export type AbortIncompleteMultipartUpload = {
DaysAfterInitiation: number;
};
export type LifecycleRule = {
AbortIncompleteMultipartUpload?: AbortIncompleteMultipartUpload;
ID: string;
Prefix?: string;
Status?: string;
Expiration?: Expiration;
Filter?: RuleFilter;
NoncurrentVersionExpiration?: NoncurrentVersionExpiration;
NoncurrentVersionTransition?: NoncurrentVersionTransition;
Transition?: Transition;
};
export type LifecycleConfig = {
Rule: LifecycleRule[];
};
export type LifeCycleConfigParam = LifecycleConfig | null | undefined | '';
export type ApplySSEByDefault = {
KmsMasterKeyID?: string;
SSEAlgorithm: string;
};
export type EncryptionRule = {
ApplyServerSideEncryptionByDefault?: ApplySSEByDefault;
};
export type EncryptionConfig = {
Rule: EncryptionRule[];
};
export type GetObjectRetentionOpts = {
versionId: string;
};
export type ObjectRetentionInfo = {
mode: RETENTION_MODES;
retainUntilDate: string;
};
export type RemoveObjectsEntry = {
name: string;
versionId?: string;
};
export type ObjectName = string;
export type RemoveObjectsParam = ObjectName[] | RemoveObjectsEntry[];
export type RemoveObjectsRequestEntry = {
Key: string;
VersionId?: string;
};
export type RemoveObjectsResponse = null | undefined | {
Error?: {
Code?: string;
Message?: string;
Key?: string;
VersionId?: string;
};
};
export type CopyObjectResultV1 = {
etag: string;
lastModified: string | Date;
};
export type CopyObjectResultV2 = {
Bucket?: string;
Key?: string;
LastModified: string | Date;
MetaData?: ResponseHeader;
VersionId?: string | null;
SourceVersionId?: string | null;
Etag?: string;
Size?: number;
};
export type CopyObjectResult = CopyObjectResultV1 | CopyObjectResultV2;
export type CopyObjectParams = [CopySourceOptions, CopyDestinationOptions] | [string, string, string, CopyConditions?];
export type ExcludedPrefix = {
Prefix: string;
};
export type BucketVersioningConfiguration = {
Status: VersioningEnabled | VersioningSuspended;
MFADelete?: string;
ExcludedPrefixes?: ExcludedPrefix[];
ExcludeFolders?: boolean;
};
export type UploadPartConfig = {
bucketName: string;
objectName: string;
uploadID: string;
partNumber: number;
headers: RequestHeaders;
sourceObj: string;
};
export type PreSignRequestParams = {
[key: string]: string;
};
/** List object api types **/
export type CommonPrefix = {
Prefix: string;
};
export type Owner = {
ID: string;
DisplayName: string;
};
export type Metadata = {
Items: MetadataItem[];
};
export type ObjectInfo = {
key?: string;
name?: string;
lastModified?: Date;
etag?: string;
owner?: Owner;
storageClass?: string;
userMetadata?: Metadata;
userTags?: string;
prefix?: string;
size?: number;
};
export type ListObjectQueryRes = {
isTruncated?: boolean;
nextMarker?: string;
versionIdMarker?: string;
objects?: ObjectInfo[];
};
export type ListObjectQueryOpts = {
Delimiter?: string;
MaxKeys?: number;
IncludeVersion?: boolean;
};
/** List object api types **/
export type ObjectVersionEntry = {
IsLatest?: string;
VersionId?: string;
};
export type ObjectRowEntry = ObjectVersionEntry & {
Key: string;
LastModified?: Date | undefined;
ETag?: string;
Size?: string;
Owner?: Owner;
StorageClass?: string;
};
export interface ListBucketResultV1 {
Name?: string;
Prefix?: string;
ContinuationToken?: string;
KeyCount?: string;
Marker?: string;
MaxKeys?: string;
Delimiter?: string;
IsTruncated?: boolean;
Contents?: ObjectRowEntry[];
NextKeyMarker?: string;
CommonPrefixes?: CommonPrefix[];
Version?: ObjectRowEntry[];
DeleteMarker?: ObjectRowEntry[];
VersionIdMarker?: string;
NextVersionIdMarker?: string;
}
+34
View File
@@ -0,0 +1,34 @@
// nodejs IncomingHttpHeaders is Record<string, string | string[]>, but it's actually this:
export let ENCRYPTION_TYPES = /*#__PURE__*/function (ENCRYPTION_TYPES) {
ENCRYPTION_TYPES["SSEC"] = "SSE-C";
ENCRYPTION_TYPES["KMS"] = "KMS";
return ENCRYPTION_TYPES;
}({});
export let RETENTION_MODES = /*#__PURE__*/function (RETENTION_MODES) {
RETENTION_MODES["GOVERNANCE"] = "GOVERNANCE";
RETENTION_MODES["COMPLIANCE"] = "COMPLIANCE";
return RETENTION_MODES;
}({});
export let RETENTION_VALIDITY_UNITS = /*#__PURE__*/function (RETENTION_VALIDITY_UNITS) {
RETENTION_VALIDITY_UNITS["DAYS"] = "Days";
RETENTION_VALIDITY_UNITS["YEARS"] = "Years";
return RETENTION_VALIDITY_UNITS;
}({});
export let LEGAL_HOLD_STATUS = /*#__PURE__*/function (LEGAL_HOLD_STATUS) {
LEGAL_HOLD_STATUS["ENABLED"] = "ON";
LEGAL_HOLD_STATUS["DISABLED"] = "OFF";
return LEGAL_HOLD_STATUS;
}({});
/* Replication Config types */
/* Replication Config types */
/**
* @deprecated keep for backward compatible, use `LEGAL_HOLD_STATUS` instead
*/
/** List object api types **/ // Common types
/** List object api types **/
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFTkNSWVBUSU9OX1RZUEVTIiwiUkVURU5USU9OX01PREVTIiwiUkVURU5USU9OX1ZBTElESVRZX1VOSVRTIiwiTEVHQUxfSE9MRF9TVEFUVVMiXSwic291cmNlcyI6WyJ0eXBlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlICogYXMgaHR0cCBmcm9tICdub2RlOmh0dHAnXG5pbXBvcnQgdHlwZSB7IFJlYWRhYmxlIGFzIFJlYWRhYmxlU3RyZWFtIH0gZnJvbSAnbm9kZTpzdHJlYW0nXG5cbmltcG9ydCB0eXBlIHsgQ29weURlc3RpbmF0aW9uT3B0aW9ucywgQ29weVNvdXJjZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzLnRzJ1xuaW1wb3J0IHR5cGUgeyBDb3B5Q29uZGl0aW9ucyB9IGZyb20gJy4vY29weS1jb25kaXRpb25zLnRzJ1xuXG5leHBvcnQgdHlwZSBWZXJzaW9uSWRlbnRpZmljYXRvciA9IHtcbiAgdmVyc2lvbklkPzogc3RyaW5nXG59XG5cbmV4cG9ydCB0eXBlIEdldE9iamVjdE9wdHMgPSBWZXJzaW9uSWRlbnRpZmljYXRvciAmIHtcbiAgU1NFQ3VzdG9tZXJBbGdvcml0aG0/OiBzdHJpbmdcbiAgU1NFQ3VzdG9tZXJLZXk/OiBzdHJpbmdcbiAgU1NFQ3VzdG9tZXJLZXlNRDU/OiBzdHJpbmdcbn1cblxuZXhwb3J0IHR5cGUgQmluYXJ5ID0gc3RyaW5nIHwgQnVmZmVyXG5cbi8vIG5vZGVqcyBJbmNvbWluZ0h0dHBIZWFkZXJzIGlzIFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHN0cmluZ1tdPiwgYnV0IGl0J3MgYWN0dWFsbHkgdGhpczpcbmV4cG9ydCB0eXBlIFJlc3BvbnNlSGVhZGVyID0gUmVjb3JkPHN0cmluZywgc3RyaW5nPlxuXG5leHBvcnQgdHlwZSBPYmplY3RNZXRhRGF0YSA9IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlcj5cblxuZXhwb3J0IHR5cGUgUmVxdWVzdEhlYWRlcnMgPSBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBib29sZWFuIHwgbnVtYmVyIHwgdW5kZWZpbmVkPlxuXG5leHBvcnQgdHlwZSBFbmNyeXB0aW9uID1cbiAgfCB7XG4gICAgICB0eXBlOiBFTkNSWVBUSU9OX1RZUEVTLlNTRUNcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogRU5DUllQVElPTl9UWVBFUy5LTVNcbiAgICAgIFNTRUFsZ29yaXRobT86IHN0cmluZ1xuICAgICAgS01TTWFzdGVyS2V5SUQ/OiBzdHJpbmdcbiAgICB9XG5cbmV4cG9ydCB0eXBlIEVuYWJsZWRPckRpc2FibGVkU3RhdHVzID0gJ0VuYWJsZWQnIHwgJ0Rpc2FibGVkJ1xuZXhwb3J0IGVudW0gRU5DUllQVElPTl9UWVBFUyB7XG4gIC8qKlxuICAgKiBTU0VDIHJlcHJlc2VudHMgc2VydmVyLXNpZGUtZW5jcnlwdGlvbiB3aXRoIGN1c3RvbWVyIHByb3ZpZGVkIGtleXNcbiAgICovXG4gIFNTRUMgPSAnU1NFLUMnLFxuICAvKipcbiAgICogS01TIHJlcHJlc2VudHMgc2VydmVyLXNpZGUtZW5jcnlwdGlvbiB3aXRoIG1hbmFnZWQga2V5c1xuICAgKi9cbiAgS01TID0gJ0tNUycsXG59XG5cbmV4cG9ydCBlbnVtIFJFVEVOVElPTl9NT0RFUyB7XG4gIEdPVkVSTkFOQ0UgPSAnR09WRVJOQU5DRScsXG4gIENPTVBMSUFOQ0UgPSAnQ09NUExJQU5DRScsXG59XG5cbmV4cG9ydCBlbnVtIFJFVEVOVElPTl9WQUxJRElUWV9VTklUUyB7XG4gIERBWVMgPSAnRGF5cycsXG4gIFlFQVJTID0gJ1llYXJzJyxcbn1cblxuZXhwb3J0IGVudW0gTEVHQUxfSE9MRF9TVEFUVVMge1xuICBFTkFCTEVEID0gJ09OJyxcbiAgRElTQUJMRUQgPSAnT0ZGJyxcbn1cblxuZXhwb3J0IHR5cGUgVHJhbnNwb3J0ID0gUGljazx0eXBlb2YgaHR0cCwgJ3JlcXVlc3QnPlxuXG5leHBvcnQgaW50ZXJmYWNlIElSZXF1ZXN0IHtcbiAgcHJvdG9jb2w6IHN0cmluZ1xuICBwb3J0PzogbnVtYmVyIHwgc3RyaW5nXG4gIG1ldGhvZDogc3RyaW5nXG4gIHBhdGg6IHN0cmluZ1xuICBoZWFkZXJzOiBSZXF1ZXN0SGVhZGVyc1xufVxuXG5leHBvcnQgdHlwZSBJQ2Fub25pY2FsUmVxdWVzdCA9IHN0cmluZ1xuXG5leHBvcnQgaW50ZXJmYWNlIEluY29tcGxldGVVcGxvYWRlZEJ1Y2tldEl0ZW0ge1xuICBrZXk6IHN0cmluZ1xuICB1cGxvYWRJZDogc3RyaW5nXG4gIHNpemU6IG51bWJlclxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1ldGFkYXRhSXRlbSB7XG4gIEtleTogc3RyaW5nXG4gIFZhbHVlOiBzdHJpbmdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJdGVtQnVja2V0TWV0YWRhdGFMaXN0IHtcbiAgSXRlbXM6IE1ldGFkYXRhSXRlbVtdXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSXRlbUJ1Y2tldE1ldGFkYXRhIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgW2tleTogc3RyaW5nXTogYW55XG59XG5leHBvcnQgaW50ZXJmYWNlIEl0ZW1CdWNrZXRUYWdzIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgW2tleTogc3RyaW5nXTogYW55XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVja2V0SXRlbUZyb21MaXN0IHtcbiAgbmFtZTogc3RyaW5nXG4gIGNyZWF0aW9uRGF0ZTogRGF0ZVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1Y2tldEl0ZW1Db3B5IHtcbiAgZXRhZzogc3RyaW5nXG4gIGxhc3RNb2RpZmllZDogRGF0ZVxufVxuXG5leHBvcnQgdHlwZSBCdWNrZXRJdGVtID1cbiAgfCB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIHNpemU6IG51bWJlclxuICAgICAgZXRhZzogc3RyaW5nXG4gICAgICBwcmVmaXg/OiBuZXZlclxuICAgICAgbGFzdE1vZGlmaWVkOiBEYXRlXG4gICAgfVxuICB8IHtcbiAgICAgIG5hbWU/OiBuZXZlclxuICAgICAgZXRhZz86IG5ldmVyXG4gICAgICBsYXN0TW9kaWZpZWQ/OiBuZXZlclxuICAgICAgcHJlZml4OiBzdHJpbmdcbiAgICAgIHNpemU6IDBcbiAgICB9XG5cbmV4cG9ydCB0eXBlIEJ1Y2tldEl0ZW1XaXRoTWV0YWRhdGEgPSBCdWNrZXRJdGVtICYge1xuICBtZXRhZGF0YT86IEl0ZW1CdWNrZXRNZXRhZGF0YSB8IEl0ZW1CdWNrZXRNZXRhZGF0YUxpc3RcbiAgdGFncz86IEl0ZW1CdWNrZXRUYWdzXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVja2V0U3RyZWFtPFQ+IGV4dGVuZHMgUmVhZGFibGVTdHJlYW0ge1xuICBvbihldmVudDogJ2RhdGEnLCBsaXN0ZW5lcjogKGl0ZW06IFQpID0+IHZvaWQpOiB0aGlzXG5cbiAgb24oZXZlbnQ6ICdlbmQnIHwgJ3BhdXNlJyB8ICdyZWFkYWJsZScgfCAncmVzdW1lJyB8ICdjbG9zZScsIGxpc3RlbmVyOiAoKSA9PiB2b2lkKTogdGhpc1xuXG4gIG9uKGV2ZW50OiAnZXJyb3InLCBsaXN0ZW5lcjogKGVycjogRXJyb3IpID0+IHZvaWQpOiB0aGlzXG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgb24oZXZlbnQ6IHN0cmluZyB8IHN5bWJvbCwgbGlzdGVuZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCk6IHRoaXNcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCdWNrZXRJdGVtU3RhdCB7XG4gIHNpemU6IG51bWJlclxuICBldGFnOiBzdHJpbmdcbiAgbGFzdE1vZGlmaWVkOiBEYXRlXG4gIG1ldGFEYXRhOiBJdGVtQnVja2V0TWV0YWRhdGFcbiAgdmVyc2lvbklkPzogc3RyaW5nIHwgbnVsbFxufVxuXG5leHBvcnQgdHlwZSBTdGF0T2JqZWN0T3B0cyA9IHtcbiAgdmVyc2lvbklkPzogc3RyaW5nXG59XG5cbi8qIFJlcGxpY2F0aW9uIENvbmZpZyB0eXBlcyAqL1xuZXhwb3J0IHR5cGUgUmVwbGljYXRpb25SdWxlU3RhdHVzID0ge1x Line truncated
@@ -0,0 +1,90 @@
/// <reference types="node" />
/// <reference types="node" />
import type * as http from 'node:http';
import { SelectResults } from "../helpers.mjs";
import type { BucketItemFromList, BucketItemWithMetadata, CopyObjectResultV1, ObjectInfo, ObjectLockInfo, ReplicationConfig } from "./type.mjs";
export declare function parseBucketRegion(xml: string): string;
export declare function parseError(xml: string, headerInfo: Record<string, unknown>): Record<string, unknown>;
export declare function parseResponseError(response: http.IncomingMessage): Promise<Record<string, string>>;
/**
* parse XML response for list objects v2 with metadata in a bucket
*/
export declare function parseListObjectsV2WithMetadata(xml: string): {
objects: Array<BucketItemWithMetadata>;
isTruncated: boolean;
nextContinuationToken: string;
};
export type UploadedPart = {
part: number;
lastModified?: Date;
etag: string;
size: number;
};
export declare function parseListParts(xml: string): {
isTruncated: boolean;
marker: number;
parts: UploadedPart[];
};
export declare function parseListBucket(xml: string): BucketItemFromList[];
export declare function parseInitiateMultipart(xml: string): string;
export declare function parseReplicationConfig(xml: string): ReplicationConfig;
export declare function parseObjectLegalHoldConfig(xml: string): any;
export declare function parseTagging(xml: string): any;
export declare function parseCompleteMultipart(xml: string): {
location: any;
bucket: any;
key: any;
etag: any;
errCode?: undefined;
errMessage?: undefined;
} | {
errCode: any;
errMessage: any;
location?: undefined;
bucket?: undefined;
key?: undefined;
etag?: undefined;
} | undefined;
type UploadID = string;
export type ListMultipartResult = {
uploads: {
key: string;
uploadId: UploadID;
initiator?: {
id: string;
displayName: string;
};
owner?: {
id: string;
displayName: string;
};
storageClass: unknown;
initiated: Date;
}[];
prefixes: {
prefix: string;
}[];
isTruncated: boolean;
nextKeyMarker: string;
nextUploadIdMarker: string;
};
export declare function parseListMultipart(xml: string): ListMultipartResult;
export declare function parseObjectLockConfig(xml: string): ObjectLockInfo;
export declare function parseBucketVersioningConfig(xml: string): any;
export declare function parseSelectObjectContentResponse(res: Buffer): SelectResults | undefined;
export declare function parseLifecycleConfig(xml: string): any;
export declare function parseBucketEncryptionConfig(xml: string): any;
export declare function parseObjectRetentionConfig(xml: string): {
mode: any;
retainUntilDate: any;
};
export declare function removeObjectsParser(xml: string): any[];
export declare function parseCopyObject(xml: string): CopyObjectResultV1;
export declare function parseListObjects(xml: string): {
objects: ObjectInfo[];
isTruncated?: boolean | undefined;
nextMarker?: string | undefined;
versionIdMarker?: string | undefined;
};
export declare function uploadPartParser(xml: string): any;
export {};
+691
View File
@@ -0,0 +1,691 @@
import crc32 from 'buffer-crc32';
import { XMLParser } from 'fast-xml-parser';
import * as errors from "../errors.mjs";
import { SelectResults } from "../helpers.mjs";
import { isObject, parseXml, readableStream, sanitizeETag, sanitizeObjectKey, sanitizeSize, toArray } from "./helper.mjs";
import { readAsString } from "./response.mjs";
import { RETENTION_VALIDITY_UNITS } from "./type.mjs";
// parse XML response for bucket region
export function parseBucketRegion(xml) {
// return region information
return parseXml(xml).LocationConstraint;
}
const fxp = new XMLParser();
const fxpWithoutNumParser = new XMLParser({
// @ts-ignore
numberParseOptions: {
skipLike: /./
}
});
// Parse XML and return information as Javascript types
// parse error XML response
export function parseError(xml, headerInfo) {
let xmlErr = {};
const xmlObj = fxp.parse(xml);
if (xmlObj.Error) {
xmlErr = xmlObj.Error;
}
const e = new errors.S3Error();
Object.entries(xmlErr).forEach(([key, value]) => {
e[key.toLowerCase()] = value;
});
Object.entries(headerInfo).forEach(([key, value]) => {
e[key] = value;
});
return e;
}
// Generates an Error object depending on http statusCode and XML body
export async function parseResponseError(response) {
const statusCode = response.statusCode;
let code = '',
message = '';
if (statusCode === 301) {
code = 'MovedPermanently';
message = 'Moved Permanently';
} else if (statusCode === 307) {
code = 'TemporaryRedirect';
message = 'Are you using the correct endpoint URL?';
} else if (statusCode === 403) {
code = 'AccessDenied';
message = 'Valid and authorized credentials required';
} else if (statusCode === 404) {
code = 'NotFound';
message = 'Not Found';
} else if (statusCode === 405) {
code = 'MethodNotAllowed';
message = 'Method Not Allowed';
} else if (statusCode === 501) {
code = 'MethodNotAllowed';
message = 'Method Not Allowed';
} else if (statusCode === 503) {
code = 'SlowDown';
message = 'Please reduce your request rate.';
} else {
const hErrCode = response.headers['x-minio-error-code'];
const hErrDesc = response.headers['x-minio-error-desc'];
if (hErrCode && hErrDesc) {
code = hErrCode;
message = hErrDesc;
}
}
const headerInfo = {};
// A value created by S3 compatible server that uniquely identifies the request.
headerInfo.amzRequestid = response.headers['x-amz-request-id'];
// A special token that helps troubleshoot API replies and issues.
headerInfo.amzId2 = response.headers['x-amz-id-2'];
// Region where the bucket is located. This header is returned only
// in HEAD bucket and ListObjects response.
headerInfo.amzBucketRegion = response.headers['x-amz-bucket-region'];
const xmlString = await readAsString(response);
if (xmlString) {
throw parseError(xmlString, headerInfo);
}
// Message should be instantiated for each S3Errors.
const e = new errors.S3Error(message, {
cause: headerInfo
});
// S3 Error code.
e.code = code;
Object.entries(headerInfo).forEach(([key, value]) => {
// @ts-expect-error force set error properties
e[key] = value;
});
throw e;
}
/**
* parse XML response for list objects v2 with metadata in a bucket
*/
export function parseListObjectsV2WithMetadata(xml) {
const result = {
objects: [],
isTruncated: false,
nextContinuationToken: ''
};
let xmlobj = parseXml(xml);
if (!xmlobj.ListBucketResult) {
throw new errors.InvalidXMLError('Missing tag: "ListBucketResult"');
}
xmlobj = xmlobj.ListBucketResult;
if (xmlobj.IsTruncated) {
result.isTruncated = xmlobj.IsTruncated;
}
if (xmlobj.NextContinuationToken) {
result.nextContinuationToken = xmlobj.NextContinuationToken;
}
if (xmlobj.Contents) {
toArray(xmlobj.Contents).forEach(content => {
const name = sanitizeObjectKey(content.Key);
const lastModified = new Date(content.LastModified);
const etag = sanitizeETag(content.ETag);
const size = content.Size;
let tags = {};
if (content.UserTags != null) {
toArray(content.UserTags.split('&')).forEach(tag => {
const [key, value] = tag.split('=');
tags[key] = value;
});
} else {
tags = {};
}
let metadata;
if (content.UserMetadata != null) {
metadata = toArray(content.UserMetadata)[0];
} else {
metadata = null;
}
result.objects.push({
name,
lastModified,
etag,
size,
metadata,
tags
});
});
}
if (xmlobj.CommonPrefixes) {
toArray(xmlobj.CommonPrefixes).forEach(commonPrefix => {
result.objects.push({
prefix: sanitizeObjectKey(toArray(commonPrefix.Prefix)[0]),
size: 0
});
});
}
return result;
}
// parse XML response for list parts of an in progress multipart upload
export function parseListParts(xml) {
let xmlobj = parseXml(xml);
const result = {
isTruncated: false,
parts: [],
marker: 0
};
if (!xmlobj.ListPartsResult) {
throw new errors.InvalidXMLError('Missing tag: "ListPartsResult"');
}
xmlobj = xmlobj.ListPartsResult;
if (xmlobj.IsTruncated) {
result.isTruncated = xmlobj.IsTruncated;
}
if (xmlobj.NextPartNumberMarker) {
result.marker = toArray(xmlobj.NextPartNumberMarker)[0] || '';
}
if (xmlobj.Part) {
toArray(xmlobj.Part).forEach(p => {
const part = parseInt(toArray(p.PartNumber)[0], 10);
const lastModified = new Date(p.LastModified);
const etag = p.ETag.replace(/^"/g, '').replace(/"$/g, '').replace(/^&quot;/g, '').replace(/&quot;$/g, '').replace(/^&#34;/g, '').replace(/&#34;$/g, '');
result.parts.push({
part,
lastModified,
etag,
size: parseInt(p.Size, 10)
});
});
}
return result;
}
export function parseListBucket(xml) {
let result = [];
const listBucketResultParser = new XMLParser({
parseTagValue: true,
// Enable parsing of values
numberParseOptions: {
leadingZeros: false,
// Disable number parsing for values with leading zeros
hex: false,
// Disable hex number parsing - Invalid bucket name
skipLike: /^[0-9]+$/ // Skip number parsing if the value consists entirely of digits
},
tagValueProcessor: (tagName, tagValue = '') => {
// Ensure that the Name tag is always treated as a string
if (tagName === 'Name') {
return tagValue.toString();
}
return tagValue;
},
ignoreAttributes: false // Ensure that all attributes are parsed
});
const parsedXmlRes = listBucketResultParser.parse(xml);
if (!parsedXmlRes.ListAllMyBucketsResult) {
throw new errors.InvalidXMLError('Missing tag: "ListAllMyBucketsResult"');
}
const {
ListAllMyBucketsResult: {
Buckets = {}
} = {}
} = parsedXmlRes;
if (Buckets.Bucket) {
result = toArray(Buckets.Bucket).map((bucket = {}) => {
const {
Name: bucketName,
CreationDate
} = bucket;
const creationDate = new Date(CreationDate);
return {
name: bucketName,
creationDate
};
});
}
return result;
}
export function parseInitiateMultipart(xml) {
let xmlobj = parseXml(xml);
if (!xmlobj.InitiateMultipartUploadResult) {
throw new errors.InvalidXMLError('Missing tag: "InitiateMultipartUploadResult"');
}
xmlobj = xmlobj.InitiateMultipartUploadResult;
if (xmlobj.UploadId) {
return xmlobj.UploadId;
}
throw new errors.InvalidXMLError('Missing tag: "UploadId"');
}
export function parseReplicationConfig(xml) {
const xmlObj = parseXml(xml);
const {
Role,
Rule
} = xmlObj.ReplicationConfiguration;
return {
ReplicationConfiguration: {
role: Role,
rules: toArray(Rule)
}
};
}
export function parseObjectLegalHoldConfig(xml) {
const xmlObj = parseXml(xml);
return xmlObj.LegalHold;
}
export function parseTagging(xml) {
const xmlObj = parseXml(xml);
let result = [];
if (xmlObj.Tagging && xmlObj.Tagging.TagSet && xmlObj.Tagging.TagSet.Tag) {
const tagResult = xmlObj.Tagging.TagSet.Tag;
// if it is a single tag convert into an array so that the return value is always an array.
if (isObject(tagResult)) {
result.push(tagResult);
} else {
result = tagResult;
}
}
return result;
}
// parse XML response when a multipart upload is completed
export function parseCompleteMultipart(xml) {
const xmlobj = parseXml(xml).CompleteMultipartUploadResult;
if (xmlobj.Location) {
const location = toArray(xmlobj.Location)[0];
const bucket = toArray(xmlobj.Bucket)[0];
const key = xmlobj.Key;
const etag = xmlobj.ETag.replace(/^"/g, '').replace(/"$/g, '').replace(/^&quot;/g, '').replace(/&quot;$/g, '').replace(/^&#34;/g, '').replace(/&#34;$/g, '');
return {
location,
bucket,
key,
etag
};
}
// Complete Multipart can return XML Error after a 200 OK response
if (xmlobj.Code && xmlobj.Message) {
const errCode = toArray(xmlobj.Code)[0];
const errMessage = toArray(xmlobj.Message)[0];
return {
errCode,
errMessage
};
}
}
// parse XML response for listing in-progress multipart uploads
export function parseListMultipart(xml) {
const result = {
prefixes: [],
uploads: [],
isTruncated: false,
nextKeyMarker: '',
nextUploadIdMarker: ''
};
let xmlobj = parseXml(xml);
if (!xmlobj.ListMultipartUploadsResult) {
throw new errors.InvalidXMLError('Missing tag: "ListMultipartUploadsResult"');
}
xmlobj = xmlobj.ListMultipartUploadsResult;
if (xmlobj.IsTruncated) {
result.isTruncated = xmlobj.IsTruncated;
}
if (xmlobj.NextKeyMarker) {
result.nextKeyMarker = xmlobj.NextKeyMarker;
}
if (xmlobj.NextUploadIdMarker) {
result.nextUploadIdMarker = xmlobj.nextUploadIdMarker || '';
}
if (xmlobj.CommonPrefixes) {
toArray(xmlobj.CommonPrefixes).forEach(prefix => {
// @ts-expect-error index check
result.prefixes.push({
prefix: sanitizeObjectKey(toArray(prefix.Prefix)[0])
});
});
}
if (xmlobj.Upload) {
toArray(xmlobj.Upload).forEach(upload => {
const uploadItem = {
key: upload.Key,
uploadId: upload.UploadId,
storageClass: upload.StorageClass,
initiated: new Date(upload.Initiated)
};
if (upload.Initiator) {
uploadItem.initiator = {
id: upload.Initiator.ID,
displayName: upload.Initiator.DisplayName
};
}
if (upload.Owner) {
uploadItem.owner = {
id: upload.Owner.ID,
displayName: upload.Owner.DisplayName
};
}
result.uploads.push(uploadItem);
});
}
return result;
}
export function parseObjectLockConfig(xml) {
const xmlObj = parseXml(xml);
let lockConfigResult = {};
if (xmlObj.ObjectLockConfiguration) {
lockConfigResult = {
objectLockEnabled: xmlObj.ObjectLockConfiguration.ObjectLockEnabled
};
let retentionResp;
if (xmlObj.ObjectLockConfiguration && xmlObj.ObjectLockConfiguration.Rule && xmlObj.ObjectLockConfiguration.Rule.DefaultRetention) {
retentionResp = xmlObj.ObjectLockConfiguration.Rule.DefaultRetention || {};
lockConfigResult.mode = retentionResp.Mode;
}
if (retentionResp) {
const isUnitYears = retentionResp.Years;
if (isUnitYears) {
lockConfigResult.validity = isUnitYears;
lockConfigResult.unit = RETENTION_VALIDITY_UNITS.YEARS;
} else {
lockConfigResult.validity = retentionResp.Days;
lockConfigResult.unit = RETENTION_VALIDITY_UNITS.DAYS;
}
}
}
return lockConfigResult;
}
export function parseBucketVersioningConfig(xml) {
const xmlObj = parseXml(xml);
return xmlObj.VersioningConfiguration;
}
// Used only in selectObjectContent API.
// extractHeaderType extracts the first half of the header message, the header type.
function extractHeaderType(stream) {
const headerNameLen = Buffer.from(stream.read(1)).readUInt8();
const headerNameWithSeparator = Buffer.from(stream.read(headerNameLen)).toString();
const splitBySeparator = (headerNameWithSeparator || '').split(':');
return splitBySeparator.length >= 1 ? splitBySeparator[1] : '';
}
function extractHeaderValue(stream) {
const bodyLen = Buffer.from(stream.read(2)).readUInt16BE();
return Buffer.from(stream.read(bodyLen)).toString();
}
export function parseSelectObjectContentResponse(res) {
const selectResults = new SelectResults({}); // will be returned
const responseStream = readableStream(res); // convert byte array to a readable responseStream
// @ts-ignore
while (responseStream._readableState.length) {
// Top level responseStream read tracker.
let msgCrcAccumulator; // accumulate from start of the message till the message crc start.
const totalByteLengthBuffer = Buffer.from(responseStream.read(4));
msgCrcAccumulator = crc32(totalByteLengthBuffer);
const headerBytesBuffer = Buffer.from(responseStream.read(4));
msgCrcAccumulator = crc32(headerBytesBuffer, msgCrcAccumulator);
const calculatedPreludeCrc = msgCrcAccumulator.readInt32BE(); // use it to check if any CRC mismatch in header itself.
const preludeCrcBuffer = Buffer.from(responseStream.read(4)); // read 4 bytes i.e 4+4 =8 + 4 = 12 ( prelude + prelude crc)
msgCrcAccumulator = crc32(preludeCrcBuffer, msgCrcAccumulator);
const totalMsgLength = totalByteLengthBuffer.readInt32BE();
const headerLength = headerBytesBuffer.readInt32BE();
const preludeCrcByteValue = preludeCrcBuffer.readInt32BE();
if (preludeCrcByteValue !== calculatedPreludeCrc) {
// Handle Header CRC mismatch Error
throw new Error(`Header Checksum Mismatch, Prelude CRC of ${preludeCrcByteValue} does not equal expected CRC of ${calculatedPreludeCrc}`);
}
const headers = {};
if (headerLength > 0) {
const headerBytes = Buffer.from(responseStream.read(headerLength));
msgCrcAccumulator = crc32(headerBytes, msgCrcAccumulator);
const headerReaderStream = readableStream(headerBytes);
// @ts-ignore
while (headerReaderStream._readableState.length) {
const headerTypeName = extractHeaderType(headerReaderStream);
headerReaderStream.read(1); // just read and ignore it.
if (headerTypeName) {
headers[headerTypeName] = extractHeaderValue(headerReaderStream);
}
}
}
let payloadStream;
const payLoadLength = totalMsgLength - headerLength - 16;
if (payLoadLength > 0) {
const payLoadBuffer = Buffer.from(responseStream.read(payLoadLength));
msgCrcAccumulator = crc32(payLoadBuffer, msgCrcAccumulator);
// read the checksum early and detect any mismatch so we can avoid unnecessary further processing.
const messageCrcByteValue = Buffer.from(responseStream.read(4)).readInt32BE();
const calculatedCrc = msgCrcAccumulator.readInt32BE();
// Handle message CRC Error
if (messageCrcByteValue !== calculatedCrc) {
throw new Error(`Message Checksum Mismatch, Message CRC of ${messageCrcByteValue} does not equal expected CRC of ${calculatedCrc}`);
}
payloadStream = readableStream(payLoadBuffer);
}
const messageType = headers['message-type'];
switch (messageType) {
case 'error':
{
const errorMessage = headers['error-code'] + ':"' + headers['error-message'] + '"';
throw new Error(errorMessage);
}
case 'event':
{
const contentType = headers['content-type'];
const eventType = headers['event-type'];
switch (eventType) {
case 'End':
{
selectResults.setResponse(res);
return selectResults;
}
case 'Records':
{
var _payloadStream;
const readData = (_payloadStream = payloadStream) === null || _payloadStream === void 0 ? void 0 : _payloadStream.read(payLoadLength);
selectResults.setRecords(readData);
break;
}
case 'Progress':
{
switch (contentType) {
case 'text/xml':
{
var _payloadStream2;
const progressData = (_payloadStream2 = payloadStream) === null || _payloadStream2 === void 0 ? void 0 : _payloadStream2.read(payLoadLength);
selectResults.setProgress(progressData.toString());
break;
}
default:
{
const errorMessage = `Unexpected content-type ${contentType} sent for event-type Progress`;
throw new Error(errorMessage);
}
}
}
break;
case 'Stats':
{
switch (contentType) {
case 'text/xml':
{
var _payloadStream3;
const statsData = (_payloadStream3 = payloadStream) === null || _payloadStream3 === void 0 ? void 0 : _payloadStream3.read(payLoadLength);
selectResults.setStats(statsData.toString());
break;
}
default:
{
const errorMessage = `Unexpected content-type ${contentType} sent for event-type Stats`;
throw new Error(errorMessage);
}
}
}
break;
default:
{
// Continuation message: Not sure if it is supported. did not find a reference or any message in response.
// It does not have a payload.
const warningMessage = `Un implemented event detected ${messageType}.`;
// eslint-disable-next-line no-console
console.warn(warningMessage);
}
}
}
}
}
}
export function parseLifecycleConfig(xml) {
const xmlObj = parseXml(xml);
return xmlObj.LifecycleConfiguration;
}
export function parseBucketEncryptionConfig(xml) {
return parseXml(xml);
}
export function parseObjectRetentionConfig(xml) {
const xmlObj = parseXml(xml);
const retentionConfig = xmlObj.Retention;
return {
mode: retentionConfig.Mode,
retainUntilDate: retentionConfig.RetainUntilDate
};
}
export function removeObjectsParser(xml) {
const xmlObj = parseXml(xml);
if (xmlObj.DeleteResult && xmlObj.DeleteResult.Error) {
// return errors as array always. as the response is object in case of single object passed in removeObjects
return toArray(xmlObj.DeleteResult.Error);
}
return [];
}
// parse XML response for copy object
export function parseCopyObject(xml) {
const result = {
etag: '',
lastModified: ''
};
let xmlobj = parseXml(xml);
if (!xmlobj.CopyObjectResult) {
throw new errors.InvalidXMLError('Missing tag: "CopyObjectResult"');
}
xmlobj = xmlobj.CopyObjectResult;
if (xmlobj.ETag) {
result.etag = xmlobj.ETag.replace(/^"/g, '').replace(/"$/g, '').replace(/^&quot;/g, '').replace(/&quot;$/g, '').replace(/^&#34;/g, '').replace(/&#34;$/g, '');
}
if (xmlobj.LastModified) {
result.lastModified = new Date(xmlobj.LastModified);
}
return result;
}
const formatObjInfo = (content, opts = {}) => {
const {
Key,
LastModified,
ETag,
Size,
VersionId,
IsLatest
} = content;
if (!isObject(opts)) {
opts = {};
}
const name = sanitizeObjectKey(toArray(Key)[0] || '');
const lastModified = LastModified ? new Date(toArray(LastModified)[0] || '') : undefined;
const etag = sanitizeETag(toArray(ETag)[0] || '');
const size = sanitizeSize(Size || '');
return {
name,
lastModified,
etag,
size,
versionId: VersionId,
isLatest: IsLatest,
isDeleteMarker: opts.IsDeleteMarker ? opts.IsDeleteMarker : false
};
};
// parse XML response for list objects in a bucket
export function parseListObjects(xml) {
const result = {
objects: [],
isTruncated: false,
nextMarker: undefined,
versionIdMarker: undefined
};
let isTruncated = false;
let nextMarker, nextVersionKeyMarker;
const xmlobj = fxpWithoutNumParser.parse(xml);
const parseCommonPrefixesEntity = commonPrefixEntry => {
if (commonPrefixEntry) {
toArray(commonPrefixEntry).forEach(commonPrefix => {
result.objects.push({
prefix: sanitizeObjectKey(toArray(commonPrefix.Prefix)[0] || ''),
size: 0
});
});
}
};
const listBucketResult = xmlobj.ListBucketResult;
const listVersionsResult = xmlobj.ListVersionsResult;
if (listBucketResult) {
if (listBucketResult.IsTruncated) {
isTruncated = listBucketResult.IsTruncated;
}
if (listBucketResult.Contents) {
toArray(listBucketResult.Contents).forEach(content => {
const name = sanitizeObjectKey(toArray(content.Key)[0] || '');
const lastModified = new Date(toArray(content.LastModified)[0] || '');
const etag = sanitizeETag(toArray(content.ETag)[0] || '');
const size = sanitizeSize(content.Size || '');
result.objects.push({
name,
lastModified,
etag,
size
});
});
}
if (listBucketResult.Marker) {
nextMarker = listBucketResult.Marker;
} else if (isTruncated && result.objects.length > 0) {
var _result$objects;
nextMarker = (_result$objects = result.objects[result.objects.length - 1]) === null || _result$objects === void 0 ? void 0 : _result$objects.name;
}
if (listBucketResult.CommonPrefixes) {
parseCommonPrefixesEntity(listBucketResult.CommonPrefixes);
}
}
if (listVersionsResult) {
if (listVersionsResult.IsTruncated) {
isTruncated = listVersionsResult.IsTruncated;
}
if (listVersionsResult.Version) {
toArray(listVersionsResult.Version).forEach(content => {
result.objects.push(formatObjInfo(content));
});
}
if (listVersionsResult.DeleteMarker) {
toArray(listVersionsResult.DeleteMarker).forEach(content => {
result.objects.push(formatObjInfo(content, {
IsDeleteMarker: true
}));
});
}
if (listVersionsResult.NextKeyMarker) {
nextVersionKeyMarker = listVersionsResult.NextKeyMarker;
}
if (listVersionsResult.NextVersionIdMarker) {
result.versionIdMarker = listVersionsResult.NextVersionIdMarker;
}
if (listVersionsResult.CommonPrefixes) {
parseCommonPrefixesEntity(listVersionsResult.CommonPrefixes);
}
}
result.isTruncated = isTruncated;
if (isTruncated) {
result.nextMarker = nextVersionKeyMarker || nextMarker;
}
return result;
}
export function uploadPartParser(xml) {
const xmlObj = parseXml(xml);
const respEl = xmlObj.CopyPartResult;
return respEl;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjcmMzMiIsIlhNTFBhcnNlciIsImVycm9ycyIsIlNlbGVjdFJlc3VsdHMiLCJpc09iamVjdCIsInBhcnNlWG1sIiwicmVhZGFibGVTdHJlYW0iLCJzYW5pdGl6ZUVUYWciLCJzYW5pdGl6ZU9iamVjdEtleSIsInNhbml0aXplU2l6ZSIsInRvQXJyYXkiLCJyZWFkQXNTdHJpbmciLCJSRVRFTlRJT05fVkFMSURJVFlfVU5JVFMiLCJwYXJzZUJ1Y2tldFJlZ2lvbiIsInhtbCIsIkxvY2F0aW9uQ29uc3RyYWludCIsImZ4cCIsImZ4cFdpdGhvdXROdW1QYXJzZXIiLCJudW1iZXJQYXJzZU9wdGlvbnMiLCJza2lwTGlrZSIsInBhcnNlRXJyb3IiLCJoZWFkZXJJbmZvIiwieG1sRXJyIiwieG1sT2JqIiwicGFyc2UiLCJFcnJvciIsImUiLCJTM0Vycm9yIiwiT2JqZWN0IiwiZW50cmllcyIsImZvckVhY2giLCJrZXkiLCJ2YWx1ZSIsInRvTG93ZXJDYXNlIiwicGFyc2VSZXNwb25zZUVycm9yIiwicmVzcG9uc2UiLCJzdGF0dXNDb2RlIiwiY29kZSIsIm1lc3NhZ2UiLCJoRXJyQ29kZSIsImhlYWRlcnMiLCJoRXJyRGVzYyIsImFtelJlcXVlc3RpZCIsImFteklkMiIsImFtekJ1Y2tldFJlZ2lvbiIsInhtbFN0cmluZyIsImNhdXNlIiwicGFyc2VMaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhIiwicmVzdWx0Iiwib2JqZWN0cyIsImlzVHJ1bmNhdGVkIiwibmV4dENvbnRpbnVhdGlvblRva2VuIiwieG1sb2JqIiwiTGlzdEJ1Y2tldFJlc3VsdCIsIkludmFsaWRYTUxFcnJvciIsIklzVHJ1bmNhdGVkIiwiTmV4dENvbnRpbnVhdGlvblRva2VuIiwiQ29udGVudHMiLCJjb250ZW50IiwibmFtZSIsIktleSIsImxhc3RNb2RpZmllZCIsIkRhdGUiLCJMYXN0TW9kaWZpZWQiLCJldGFnIiwiRVRhZyIsInNpemUiLCJTaXplIiwidGFncyIsIlVzZXJUYWdzIiwic3BsaXQiLCJ0YWciLCJtZXRhZGF0YSIsIlVzZXJNZXRhZGF0YSIsInB1c2giLCJDb21tb25QcmVmaXhlcyIsImNvbW1vblByZWZpeCIsInByZWZpeCIsIlByZWZpeCIsInBhcnNlTGlzdFBhcnRzIiwicGFydHMiLCJtYXJrZXIiLCJMaXN0UGFydHNSZXN1bHQiLCJOZXh0UGFydE51bWJlck1hcmtlciIsIlBhcnQiLCJwIiwicGFydCIsInBhcnNlSW50IiwiUGFydE51bWJlciIsInJlcGxhY2UiLCJwYXJzZUxpc3RCdWNrZXQiLCJsaXN0QnVja2V0UmVzdWx0UGFyc2VyIiwicGFyc2VUYWdWYWx1ZSIsImxlYWRpbmdaZXJvcyIsImhleCIsInRhZ1ZhbHVlUHJvY2Vzc29yIiwidGFnTmFtZSIsInRhZ1ZhbHVlIiwidG9TdHJpbmciLCJpZ25vcmVBdHRyaWJ1dGVzIiwicGFyc2VkWG1sUmVzIiwiTGlzdEFsbE15QnVja2V0c1Jlc3VsdCIsIkJ1Y2tldHMiLCJCdWNrZXQiLCJtYXAiLCJidWNrZXQiLCJOYW1lIiwiYnVja2V0TmFtZSIsIkNyZWF0aW9uRGF0ZSIsImNyZWF0aW9uRGF0ZSIsInBhcnNlSW5pdGlhdGVNdWx0aXBhcnQiLCJJbml0aWF0ZU11bHRpcGFydFVwbG9hZFJlc3VsdCIsIlVwbG9hZElkIiwicGFyc2VSZXBsaWNhdGlvbkNvbmZpZyIsIlJvbGUiLCJSdWxlIiwiUmVwbGljYXRpb25Db25maWd1cmF0aW9uIiwicm9sZSIsInJ1bGVzIiwicGFyc2VPYmplY3RMZWdhbEhvbGRDb25maWciLCJMZWdhbEhvbGQiLCJwYXJzZVRhZ2dpbmciLCJUYWdnaW5nIiwiVGFnU2V0IiwiVGFnIiwidGFnUmVzdWx0IiwicGFyc2VDb21wbGV0ZU11bHRpcGFydCIsIkNvbXBsZXRlTXVsdGlwYXJ0VXBsb2FkUmVzdWx0IiwiTG9jYXRpb24iLCJsb2NhdGlvbiIsIkNvZGUiLCJNZXNzYWdlIiwiZXJyQ29kZSIsImVyck1lc3NhZ2UiLCJwYXJzZUxpc3RNdWx0aXBhcnQiLCJwcmVmaXhlcyIsInVwbG9hZHMiLCJuZXh0S2V5TWFya2VyIiwibmV4dFVwbG9hZElkTWFya2VyIiwiTGlzdE11bHRpcGFydFVwbG9hZHNSZXN1bHQiLCJOZXh0S2V5TWFya2VyIiwiTmV4dFVwbG9hZElkTWFya2VyIiwiVXBsb2FkIiwidXBsb2FkIiwidXBsb2FkSXRlbSIsInVwbG9hZElkIiwic3RvcmFnZUNsYXNzIiwiU3RvcmFnZUNsYXNzIiwiaW5pdGlhdGVkIiwiSW5pdGlhdGVkIiwiSW5pdGlhdG9yIiwiaW5pdGlhdG9yIiwiaWQiLCJJRCIsImRpc3BsYXlOYW1lIiwiRGlzcGxheU5hbWUiLCJPd25lciIsIm93bmVyIiwicGFyc2VPYmplY3RMb2NrQ29uZmlnIiwibG9ja0NvbmZpZ1Jlc3VsdCIsIk9iamVjdExvY2tDb25maWd1cmF0aW9uIiwib2JqZWN0TG9ja0VuYWJsZWQiLCJPYmplY3RMb2NrRW5hYmxlZCIsInJldGVudGlvblJlc3AiLCJEZWZhdWx0UmV0ZW50aW9uIiwibW9kZSIsIk1vZGUiLCJpc1VuaXRZZWFycyIsIlllYXJzIiwidmFsaWRpdHkiLCJ1bml0IiwiWUVBUlMiLCJEYXlzIiwiREFZUyIsInBhcnNlQnVja2V0VmVyc2lvbmluZ0NvbmZpZyIsIlZlcnNpb25pbmdDb25maWd1cmF0aW9uIiwiZXh0cmFjdEhlYWRlclR5cGUiLCJzdHJlYW0iLCJoZWFkZXJOYW1lTGVuIiwiQnVmZmVyIiwiZnJvbSIsInJlYWQiLCJyZWFkVUludDgiLCJoZWFkZXJOYW1lV2l0aFNlcGFyYXRvciIsInNwbGl0QnlTZXBhcmF0b3IiLCJsZW5ndGgiLCJleHRyYWN0SGVhZGVyVmFsdWUiLCJib2R5TGVuIiwicmVhZFVJbnQxNkJFIiwicGFyc2VTZWxlY3RPYmplY3RDb250ZW50UmVzcG9uc2UiLCJyZXMiLCJzZWxlY3RSZXN1bHRzIiwicmVzcG9uc2VTdHJlYW0iLCJfcmVhZGFibGVTdGF0ZSIsIm1zZ0NyY0FjY3VtdWxhdG9yIiwidG90YWxCeXRlTGVuZ3RoQnVmZmVyIiwiaGVhZGVyQnl0ZXNCdWZmZXIiLCJjYWxjdWxhdGVkUHJlbHVkZUNyYyIsInJlYWRJbnQzMkJFIiwicHJlbHVkZUNyY0J1ZmZlciIsInRvdGFsTXNnTGVuZ3RoIiwiaGVhZGVyTGVuZ3RoIiwicHJlbHVkZUNyY0J5dGVWYWx1ZSIsImhlYWRlckJ5dGVzIiwiaGVhZGVyUmVhZGVyU3RyZWFtIiwiaGVhZGVyVHlwZU5hbWUiLCJwYXlsb2FkU3RyZWFtIiwicGF5TG9hZExlbmd0aCIsInBheUxvYWRCdWZmZXIiLCJtZXNzYWdlQ3JjQnl0ZVZhbHVlIiwiY2FsY3VsYXRlZENyYyIsIm1lc3NhZ2VUeXBlIiwiZXJyb3JNZXNzYWdlIiwiY29udGVudFR5cGUiLCJldmVudFR5cGUiLCJzZXRSZXNwb25zZSIsIl9wYXlsb2FkU3RyZWFtIiwicmVhZERhdGEiLCJzZXRSZWNvcmRzIiwiX3BheWxvYWRTdHJlYW0yIiwicHJvZ3Jlc3NEYXRhIiwic2V0UHJvZ3Jlc3MiLCJfcGF5bG9hZFN0cmVhbTMiLCJzdGF0c0RhdGEiLCJzZXRTdGF0cyIsIndhcm5pbmdNZXNzYWdlIiwiY29uc29sZSIsIndhcm4iLCJwYXJzZUxpZmVjeWNsZUNvbmZpZyIsIkxpZmVjeWNsZUNvbmZpZ3VyYXRpb24iLCJwYXJzZUJ1Y2tldEVuY3J5cHRpb25Db25maWciLCJwYXJzZU9iamVjdFJldGVudGlvbkNvbmZpZyIsInJldGVudGlvbkNvbmZpZyIsIlJldGVudGlvbiIsInJldGFpblVudGlsRGF0ZSIsIlJldGFpblVudGlsRGF0ZSIsInJlbW92ZU9iamVjdHNQYXJzZXIiLCJEZWxldGVSZXN1bHQiLCJwYXJzZUNvcHlPYmplY3QiLCJDb3B5T2JqZWN0UmVzdWx0IiwiZm9ybWF0T2JqSW5mbyIsIm9wdHMiLCJWZXJzaW9uSWQiLCJJc0xhdGVzdCIsInVuZGVmaW5lZCIsInZlcnNpb25JZCIsImlzTGF0ZXN0IiwiaXNEZWxldGVNYXJrZXIiLCJJc0RlbGV0ZU1hcmtlciIsInBhcnNlTGlzdE9iamVjdHMiLCJuZXh0TWFya2VyIiwidmVyc2lvbklkTWFya2VyIiwibmV4dFZlcnNpb25LZXlNYXJrZXIiLCJwYXJzZUNvbW1vblByZWZpeGVzRW50aXR5IiwiY29tbW9uUHJlZml4RW50cnkiLCJsaXN0QnVja2V0UmVzdWx0IiwibGlzdFZlcnNpb25zUmVzdWx0IiwiTGlzdFZlcnNpb25zUmV Line truncated