Skip to content

Commit

Permalink
Feat/upload progress (#529)
Browse files Browse the repository at this point in the history
* chore: Install superagent

* feat: Support upload progress

* feat: Compatibility with Nodejs and Browser

* chore: Update example

* Create lucky-insects-reply.md
  • Loading branch information
rrr523 authored Apr 23, 2024
1 parent bc1e2f9 commit e789764
Show file tree
Hide file tree
Showing 16 changed files with 484 additions and 103 deletions.
6 changes: 6 additions & 0 deletions .changeset/lucky-insects-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@demo/wallet": patch
"@bnb-chain/greenfield-js-sdk": patch
---

feat: Uploading progress
22 changes: 13 additions & 9 deletions examples/nextjs/src/components/feegrant/createObj.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { client } from '@/client';
import { ACCOUNT_PRIVATEKEY } from '@/config/env';
import {
bytesFromBase64,
GRNToString,
Long,
MsgCreateObjectTypeUrl,
newBucketGRN,
newObjectGRN,
PermissionTypes,
RedundancyType,
toTimestamp,
VisibilityType,
} from '@bnb-chain/greenfield-js-sdk';
import { Wallet } from '@ethersproject/wallet';
import { ChangeEvent, useState } from 'react';
Expand Down Expand Up @@ -135,16 +139,16 @@ export const CreateObj = () => {
creator: granteeAddr,
bucketName: bucketName,
objectName: objectName,
visibility: 'VISIBILITY_TYPE_PUBLIC_READ',
redundancyType: 'REDUNDANCY_EC_TYPE',
contentLength: fileBytes.byteLength,
expectCheckSums,
fileType: file.type,
},
{
type: 'ECDSA',
privateKey: privateKey,
visibility: VisibilityType.VISIBILITY_TYPE_PRIVATE,
redundancyType: RedundancyType.REDUNDANCY_EC_TYPE,
payloadSize: Long.fromInt(fileBytes.byteLength),
expectChecksums: expectCheckSums.map((x) => bytesFromBase64(x)),
contentType: file.type,
},
// {
// type: 'ECDSA',
// privateKey: privateKey,
// },
);

const simulateInfo = await createObjectTx.simulate({
Expand Down
8 changes: 8 additions & 0 deletions examples/nextjs/src/components/object/create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
RedundancyType,
VisibilityType,
} from '@bnb-chain/greenfield-js-sdk';
import { OnProgressEvent } from '@bnb-chain/greenfield-js-sdk/src/types/common';
import { ReedSolomon } from '@bnb-chain/reed-solomon';
import { ChangeEvent, useState } from 'react';
import { useAccount } from 'wagmi';
Expand Down Expand Up @@ -122,6 +123,9 @@ export const CreateObject = () => {
body: file,
txnHash: txHash,
duration: 20000,
onProgress: (e: OnProgressEvent) => {
console.log('progress: ', e.percent);
},
},
{
type: 'EDDSA',
Expand Down Expand Up @@ -197,6 +201,9 @@ export const CreateObject = () => {
delegatedOpts: {
visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,
},
onProgress: (e: OnProgressEvent) => {
console.log('progress: ', e.percent);
},
},
{
type: 'EDDSA',
Expand Down Expand Up @@ -230,6 +237,7 @@ export const CreateObject = () => {
bucketName: createObjectInfo.bucketName,
objectName: createObjectInfo.objectName,
body: file,
timeout: 20000,
delegatedOpts: {
visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,
},
Expand Down
4 changes: 4 additions & 0 deletions packages/js-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@
"lodash.set": "^4.3.2",
"lodash.sortby": "^4.7.0",
"long": "^5.2.1",
"mime-types": "^2.1.35",
"reflect-metadata": "^0.1.13",
"superagent": "^8.1.2",
"tsyringe": "^4.8.0"
},
"devDependencies": {
Expand All @@ -93,6 +95,8 @@
"@types/lodash.set": "^4.3.7",
"@types/lodash.sortby": "^4.7.7",
"@types/mime": "^3.0.1",
"@types/mime-types": "^2.1.4",
"@types/superagent": "^8.1.6",
"@types/xml2js": "^0.4.11",
"dotenv": "^16.0.3",
"jest": "^29.5.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/js-sdk/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default async () => {
],
},
{
input: './src/index.ts',
input: ['./src/index.ts', './src/node/adapter.ts'],
output: {
dir: './dist/cjs',
format: 'cjs',
Expand Down
93 changes: 58 additions & 35 deletions packages/js-sdk/src/api/objects.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
import {
getDelegatedCreateFolderMetaInfo,
parseDelegatedCreateFolderResponse,
} from '@/clients/spclient/spApis/delegatedCreateFolder';
import {
getObjectOffsetInfo,
parseObjectOffsetResponse,
} from '@/clients/spclient/spApis/getObjectOffset';
import {
getObjectStatusInfo,
parseObjectStatusResponse,
} from '@/clients/spclient/spApis/getObjectStatus';
import { getResumablePutObjectMetaInfo } from '@/clients/spclient/spApis/resumablePutObject';
import { DelegatedOpts } from '@/types/sp/Common';
import {
DelegateCreateFolderRepsonse,
DelegatedCreateFolderRequest,
} from '@/types/sp/DelegateCreateFolder';
import { DelegatedPubObjectRequest } from '@/types/sp/DelegatedPubObject';
import { UploadProgressResponse } from '@/types/sp/UploadProgress';
import { assertAuthType, assertStringRequire } from '@/utils/asserts/params';
import { DelegatedOpts, UploadFile } from '@/types/sp/Common';
import {
ActionType,
Principal,
Expand Down Expand Up @@ -56,16 +37,28 @@ import {
} from '..';
import { RpcQueryClient } from '../clients/queryclient';
import {
HTTPHeaderRegPubKey,
encodePath,
getAuthorization,
getSortQuery,
HTTPHeaderRegPubKey,
} from '../clients/spclient/auth';
import {
getDelegatedCreateFolderMetaInfo,
parseDelegatedCreateFolderResponse,
} from '../clients/spclient/spApis/delegatedCreateFolder';
import { getGetObjectMetaInfo } from '../clients/spclient/spApis/getObject';
import {
getObjectMetaInfo,
parseGetObjectMetaResponse,
} from '../clients/spclient/spApis/getObjectMeta';
import {
getObjectOffsetInfo,
parseObjectOffsetResponse,
} from '../clients/spclient/spApis/getObjectOffset';
import {
getObjectStatusInfo,
parseObjectStatusResponse,
} from '../clients/spclient/spApis/getObjectStatus';
import {
getListObjectPoliciesMetaInfo,
parseGetListObjectPoliciesResponse,
Expand Down Expand Up @@ -94,14 +87,22 @@ import {
ListObjectsByIDsResponse,
Long,
ObjectStatus,
OnProgress,
SpResponse,
TxResponse,
UploadOffsetResponse,
} from '../types';
import {
DelegateCreateFolderRepsonse,
DelegatedCreateFolderRequest,
} from '../types/sp/DelegateCreateFolder';
import { DelegatedPubObjectRequest } from '../types/sp/DelegatedPubObject';
import { GetObjectRequest } from '../types/sp/GetObject';
import { GetObjectMetaRequest, GetObjectMetaResponse } from '../types/sp/GetObjectMeta';
import { ListObjectsByBucketNameResponse } from '../types/sp/ListObjectsByBucketName';
import { PutObjectRequest } from '../types/sp/PutObject';
import { UploadProgressResponse } from '../types/sp/UploadProgress';
import { assertAuthType, assertFileType, assertStringRequire } from '../utils/asserts/params';
import {
checkObjectName,
generateUrlByBucketName,
Expand Down Expand Up @@ -249,7 +250,15 @@ export class Objects implements IObject {
}

public async delegateUploadObject(params: DelegatedPubObjectRequest, authType: AuthType) {
const { bucketName, objectName, body, resumableOpts, timeout = 30000, delegatedOpts } = params;
const {
bucketName,
objectName,
body,
resumableOpts,
timeout = 30000,
delegatedOpts,
onProgress,
} = params;

assertAuthType(authType);
verifyBucketName(bucketName);
Expand Down Expand Up @@ -280,8 +289,9 @@ export class Objects implements IObject {
body,
authType,
delegatedOpts,
timeout,
duration: timeout,
txnHash: '',
onProgress,
});
}

Expand All @@ -292,6 +302,7 @@ export class Objects implements IObject {
body,
partSize,
authType,
timeout,
delegatedOpts,
);
}
Expand All @@ -300,7 +311,7 @@ export class Objects implements IObject {
params: PutObjectRequest,
authType: AuthType,
): Promise<SpResponse<null>> {
const { bucketName, objectName, body, duration = 30000, resumableOpts } = params;
const { bucketName, objectName, body, duration = 30000, resumableOpts, onProgress } = params;
assertAuthType(authType);
verifyBucketName(bucketName);
verifyObjectName(objectName);
Expand Down Expand Up @@ -341,7 +352,8 @@ export class Objects implements IObject {
body,
txnHash,
authType,
timeout: duration,
duration,
onProgress,
});
}

Expand All @@ -352,31 +364,34 @@ export class Objects implements IObject {
body,
partSize,
authType,
duration,
);
}

private async putObject(params: {
endpoint: string;
bucketName: string;
objectName: string;
body: File;
body: UploadFile;
txnHash: string;
authType: AuthType;
delegatedOpts?: DelegatedOpts;
timeout: number;
duration: number;
onProgress?: OnProgress;
}): Promise<SpResponse<null>> {
const {
authType,
body,
bucketName,
delegatedOpts,
timeout: duration,
duration,
endpoint,
objectName,
txnHash,
onProgress,
} = params;

const { reqMeta, optionsWithOutHeaders, url } = await getPutObjectMetaInfo(endpoint, {
const { reqMeta, optionsWithOutHeaders, url, file } = await getPutObjectMetaInfo(endpoint, {
bucketName,
objectName,
contentType: body.type,
Expand All @@ -387,14 +402,19 @@ export class Objects implements IObject {
const signHeaders = await this.spClient.signHeaders(reqMeta, authType);

try {
const result = await this.spClient.callApi(
const result = await this.spClient.upload(
url,
{
...optionsWithOutHeaders,
headers: signHeaders,
},
duration,
file,
{
onProgress,
},
);

const { status } = result;

return { code: 0, message: 'Put object success.', statusCode: status };
Expand Down Expand Up @@ -426,9 +446,10 @@ export class Objects implements IObject {
endpoint: string,
bucketName: string,
objectName: string,
body: File,
body: UploadFile,
partSize: number,
authType: AuthType,
timeout: number,
delegatedOpts?: DelegatedOpts,
) {
let offset = 0;
Expand All @@ -444,11 +465,12 @@ export class Objects implements IObject {
const { totalPartsCount } = this.splitPartInfo(body.size, partSize);

// split file
const file = assertFileType(body) ? body.content : body;
const chunks = [];
for (let i = 0; i < totalPartsCount; i++) {
const start = i * partSize;
const end = Math.min(start + partSize, body.size);
const chunk = body.slice(start, end);
const chunk = file.slice(start, end);
chunks.push(chunk);
}

Expand Down Expand Up @@ -478,7 +500,7 @@ export class Objects implements IObject {
...optionsWithOutHeaders,
headers: signHeaders,
},
30000,
timeout,
);
} catch (error: any) {
return {
Expand Down Expand Up @@ -918,7 +940,7 @@ export class Objects implements IObject {
const signHeaders = await this.spClient.signHeaders(reqMeta, authType);

try {
const result = await this.spClient.callApi(
const result = await this.spClient.callApiV2(
url,
{
...optionsWithOutHeaders,
Expand All @@ -928,7 +950,8 @@ export class Objects implements IObject {
);
const { status } = result;

const xmlData = await result.text();
//@ts-ignore
const xmlData = result.text;
const res = parseDelegatedCreateFolderResponse(xmlData);

return { code: 0, message: 'Create folder success.', statusCode: status, body: res };
Expand Down
5 changes: 3 additions & 2 deletions packages/js-sdk/src/clients/spclient/spApis/putObject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EMPTY_STRING_SHA256, METHOD_PUT } from '@/constants';
import { ReqMeta, VisibilityType } from '@/types';
import { UploadFile } from '@/types/sp/Common';
import { generateUrlByBucketName } from '@/utils/asserts/s3';
import { encodePath, getSortQueryParams } from '../auth';

Expand All @@ -10,7 +11,7 @@ export const getPutObjectMetaInfo = async (
objectName: string;
bucketName: string;
contentType: string;
body: File;
body: UploadFile;
txnHash?: string;
delegatedOpts?: {
visibility: VisibilityType;
Expand Down Expand Up @@ -48,12 +49,12 @@ export const getPutObjectMetaInfo = async (

const optionsWithOutHeaders: Omit<RequestInit, 'headers'> = {
method: METHOD_PUT,
body,
};

return {
url: url.href,
optionsWithOutHeaders,
reqMeta,
file: body,
};
};
Loading

0 comments on commit e789764

Please sign in to comment.