diff --git a/.changeset/eleven-dragons-report.md b/.changeset/eleven-dragons-report.md new file mode 100644 index 00000000..9ce932dc --- /dev/null +++ b/.changeset/eleven-dragons-report.md @@ -0,0 +1,5 @@ +--- +'@bnb-chain/greenfield-js-sdk': major +--- + +feat: Support delegatedCreateFolder diff --git a/examples/nextjs/src/components/object/create/index.tsx b/examples/nextjs/src/components/object/create/index.tsx index 987781a8..084454ba 100644 --- a/examples/nextjs/src/components/object/create/index.tsx +++ b/examples/nextjs/src/components/object/create/index.tsx @@ -323,6 +323,40 @@ export const CreateObject = () => { }} > create folder + {' '} + diff --git a/packages/js-sdk/src/api/objects.ts b/packages/js-sdk/src/api/objects.ts index 0918e661..4ae19709 100644 --- a/packages/js-sdk/src/api/objects.ts +++ b/packages/js-sdk/src/api/objects.ts @@ -1,3 +1,4 @@ +import { getDelegatedCreateFolderMetaInfo } from '@/clients/spclient/spApis/delegatedCreateFolder'; import { getObjectOffsetInfo, parseObjectOffsetResponse, @@ -91,7 +92,12 @@ import { import { GetObjectRequest } from '../types/sp/GetObject'; import { GetObjectMetaRequest, GetObjectMetaResponse } from '../types/sp/GetObjectMeta'; import { ListObjectsByBucketNameResponse } from '../types/sp/ListObjectsByBucketName'; -import { DelegatedOpts, DelegatedPubObjectRequest, PutObjectRequest } from '../types/sp/PutObject'; +import { + DelegatedCreateFolderRequest, + DelegatedOpts, + DelegatedPubObjectRequest, + PutObjectRequest, +} from '../types/sp/PutObject'; import { checkObjectName, generateUrlByBucketName, @@ -144,6 +150,11 @@ export interface IObject { msg: Omit, ): Promise; + delegateCreateFolder( + params: DelegatedCreateFolderRequest, + authType: AuthType, + ): Promise>; + putObjectPolicy( bucketName: string, objectName: string, @@ -884,6 +895,45 @@ export class Objects implements IObject { return this.createObject(newMsg); } + public async delegateCreateFolder(params: DelegatedCreateFolderRequest, authType: AuthType) { + const { bucketName, objectName, delegatedOpts, timeout = 10000 } = params; + + let endpoint = params.endpoint; + if (!endpoint) { + endpoint = await this.sp.getSPUrlByBucket(bucketName); + } + const { reqMeta, optionsWithOutHeaders, url } = await getDelegatedCreateFolderMetaInfo( + endpoint, + { + bucketName: bucketName, + objectName: objectName, + // contentType: '', + delegatedOpts, + }, + ); + const signHeaders = await this.spClient.signHeaders(reqMeta, authType); + + try { + const result = await this.spClient.callApi( + url, + { + ...optionsWithOutHeaders, + headers: signHeaders, + }, + timeout, + ); + const { status } = result; + + return { code: 0, message: 'Put object success.', statusCode: status }; + } catch (error: any) { + return { + code: -1, + message: error.message, + statusCode: error?.statusCode || NORMAL_ERROR_CODE, + }; + } + } + public async putObjectPolicy( bucketName: string, objectName: string, diff --git a/packages/js-sdk/src/clients/spclient/spApis/delegatedCreateFolder.ts b/packages/js-sdk/src/clients/spclient/spApis/delegatedCreateFolder.ts new file mode 100644 index 00000000..48ffda92 --- /dev/null +++ b/packages/js-sdk/src/clients/spclient/spApis/delegatedCreateFolder.ts @@ -0,0 +1,52 @@ +import { EMPTY_STRING_SHA256, METHOD_POST } from '@/constants'; +import { ReqMeta } from '@/types'; +import { generateUrlByBucketName } from '@/utils'; +import { VisibilityType } from '@bnb-chain/greenfield-cosmos-types/greenfield/storage/common'; +import { encodePath, getSortQueryParams } from '../auth'; + +export const getDelegatedCreateFolderMetaInfo = async ( + endpoint: string, + params: { + objectName: string; + bucketName: string; + delegatedOpts?: { + visibility: VisibilityType; + }; + }, +) => { + const { bucketName, objectName, delegatedOpts } = params; + const path = `/${encodePath(objectName)}`; + let queryMap = {}; + + if (delegatedOpts) { + queryMap = { + 'create-folder': '', + payload_size: '0', + visibility: delegatedOpts.visibility.toString(), + }; + } + + let url = new URL(path, generateUrlByBucketName(endpoint, bucketName)); + url = getSortQueryParams(url, queryMap); + + const reqMeta: Partial = { + contentSHA256: EMPTY_STRING_SHA256, + method: METHOD_POST, + url: { + hostname: url.hostname, + query: url.searchParams.toString(), + path, + }, + contentType: '', + }; + + const optionsWithOutHeaders: Omit = { + method: METHOD_POST, + }; + + return { + url: url.href, + optionsWithOutHeaders, + reqMeta, + }; +}; diff --git a/packages/js-sdk/src/types/sp/PutObject.ts b/packages/js-sdk/src/types/sp/PutObject.ts index 40ea0c1b..f57d6e9e 100644 --- a/packages/js-sdk/src/types/sp/PutObject.ts +++ b/packages/js-sdk/src/types/sp/PutObject.ts @@ -21,6 +21,14 @@ export type DelegatedPubObjectRequest = { resumableOpts?: ResumableOpts; }; +export type DelegatedCreateFolderRequest = { + bucketName: string; + objectName: string; + delegatedOpts: DelegatedOpts; + endpoint?: string; + timeout?: number; +}; + export type DelegatedOpts = { visibility: VisibilityType; isUpdate?: boolean;