feat: blob size api (#4060)
This commit is contained in:
parent
cc00da9325
commit
0add43f8db
489
Cargo.lock
generated
489
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -89,6 +89,12 @@ export class InvitationWorkspaceType {
|
||||
avatar!: string;
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
export class WorkspaceBlobSizes {
|
||||
@Field(() => Int)
|
||||
size!: number;
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
export class InvitationType {
|
||||
@Field({ description: 'Workspace information' })
|
||||
@ -581,6 +587,16 @@ export class WorkspaceResolver {
|
||||
return this.storage.listBlobs(workspaceId);
|
||||
}
|
||||
|
||||
@Query(() => WorkspaceBlobSizes)
|
||||
async collectBlobSizes(
|
||||
@CurrentUser() user: UserType,
|
||||
@Args('workspaceId') workspaceId: string
|
||||
) {
|
||||
await this.permissionProvider.check(workspaceId, user.id);
|
||||
|
||||
return this.storage.blobsSize(workspaceId).then(size => ({ size }));
|
||||
}
|
||||
|
||||
@Mutation(() => String)
|
||||
async setBlob(
|
||||
@CurrentUser() user: UserType,
|
||||
|
@ -123,6 +123,10 @@ type InvitationWorkspaceType {
|
||||
avatar: String!
|
||||
}
|
||||
|
||||
type WorkspaceBlobSizes {
|
||||
size: Int!
|
||||
}
|
||||
|
||||
type InvitationType {
|
||||
"""Workspace information"""
|
||||
workspace: InvitationWorkspaceType!
|
||||
@ -149,6 +153,7 @@ type Query {
|
||||
|
||||
"""List blobs of workspace"""
|
||||
listBlobs(workspaceId: String!): [String!]!
|
||||
collectBlobSizes(workspaceId: String!): WorkspaceBlobSizes!
|
||||
|
||||
"""Get current user"""
|
||||
currentUser: UserType!
|
||||
|
@ -330,6 +330,28 @@ async function listBlobs(
|
||||
return res.body.data.listBlobs;
|
||||
}
|
||||
|
||||
async function collectBlobSizes(
|
||||
app: INestApplication,
|
||||
token: string,
|
||||
workspaceId: string
|
||||
): Promise<number> {
|
||||
const res = await request(app.getHttpServer())
|
||||
.post(gql)
|
||||
.auth(token, { type: 'bearer' })
|
||||
.set({ 'x-request-id': 'test', 'x-operation-name': 'test' })
|
||||
.send({
|
||||
query: `
|
||||
query {
|
||||
collectBlobSizes(workspaceId: "${workspaceId}") {
|
||||
size
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
.expect(200);
|
||||
return res.body.data.collectBlobSizes.size;
|
||||
}
|
||||
|
||||
async function setBlob(
|
||||
app: INestApplication,
|
||||
token: string,
|
||||
@ -424,6 +446,7 @@ async function getInviteInfo(
|
||||
export {
|
||||
acceptInvite,
|
||||
acceptInviteById,
|
||||
collectBlobSizes,
|
||||
createTestApp,
|
||||
createWorkspace,
|
||||
currentUser,
|
||||
|
@ -9,7 +9,13 @@ import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';
|
||||
import request from 'supertest';
|
||||
|
||||
import { AppModule } from '../app';
|
||||
import { createWorkspace, listBlobs, setBlob, signUp } from './utils';
|
||||
import {
|
||||
collectBlobSizes,
|
||||
createWorkspace,
|
||||
listBlobs,
|
||||
setBlob,
|
||||
signUp,
|
||||
} from './utils';
|
||||
|
||||
describe('Workspace Module - Blobs', () => {
|
||||
let app: INestApplication;
|
||||
@ -44,6 +50,33 @@ describe('Workspace Module - Blobs', () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
it('should set blobs', async () => {
|
||||
const u1 = await signUp(app, 'u1', 'u1@affine.pro', '1');
|
||||
|
||||
const workspace = await createWorkspace(app, u1.token.token);
|
||||
|
||||
const buffer1 = Buffer.from([0, 0]);
|
||||
const hash1 = await setBlob(app, u1.token.token, workspace.id, buffer1);
|
||||
const buffer2 = Buffer.from([0, 1]);
|
||||
const hash2 = await setBlob(app, u1.token.token, workspace.id, buffer2);
|
||||
|
||||
const server = app.getHttpServer();
|
||||
|
||||
const response1 = await request(server)
|
||||
.get(`/api/workspaces/${workspace.id}/blobs/${hash1}`)
|
||||
.auth(u1.token.token, { type: 'bearer' })
|
||||
.buffer();
|
||||
|
||||
deepEqual(response1.body, buffer1, 'failed to get blob');
|
||||
|
||||
const response2 = await request(server)
|
||||
.get(`/api/workspaces/${workspace.id}/blobs/${hash2}`)
|
||||
.auth(u1.token.token, { type: 'bearer' })
|
||||
.buffer();
|
||||
|
||||
deepEqual(response2.body, buffer2, 'failed to get blob');
|
||||
});
|
||||
|
||||
it('should list blobs', async () => {
|
||||
const u1 = await signUp(app, 'u1', 'u1@affine.pro', '1');
|
||||
|
||||
@ -51,20 +84,28 @@ describe('Workspace Module - Blobs', () => {
|
||||
const blobs = await listBlobs(app, u1.token.token, workspace.id);
|
||||
ok(blobs.length === 0, 'failed to list blobs');
|
||||
|
||||
const buffer = Buffer.from([0, 0]);
|
||||
const hash = await setBlob(app, u1.token.token, workspace.id, buffer);
|
||||
const buffer1 = Buffer.from([0, 0]);
|
||||
const hash1 = await setBlob(app, u1.token.token, workspace.id, buffer1);
|
||||
const buffer2 = Buffer.from([0, 1]);
|
||||
const hash2 = await setBlob(app, u1.token.token, workspace.id, buffer2);
|
||||
|
||||
const ret = await listBlobs(app, u1.token.token, workspace.id);
|
||||
ok(ret.length === 1, 'failed to list blobs');
|
||||
ok(ret[0] === hash, 'failed to list blobs');
|
||||
const server = app.getHttpServer();
|
||||
ok(ret.length === 2, 'failed to list blobs');
|
||||
ok(ret[0] === hash1, 'failed to list blobs');
|
||||
ok(ret[1] === hash2, 'failed to list blobs');
|
||||
});
|
||||
|
||||
const token = u1.token.token;
|
||||
const response = await request(server)
|
||||
.get(`/api/workspaces/${workspace.id}/blobs/${hash}`)
|
||||
.auth(token, { type: 'bearer' })
|
||||
.buffer();
|
||||
it('should calc blobs size', async () => {
|
||||
const u1 = await signUp(app, 'u1', 'u1@affine.pro', '1');
|
||||
|
||||
deepEqual(response.body, buffer, 'failed to get blob');
|
||||
const workspace = await createWorkspace(app, u1.token.token);
|
||||
|
||||
const buffer1 = Buffer.from([0, 0]);
|
||||
await setBlob(app, u1.token.token, workspace.id, buffer1);
|
||||
const buffer2 = Buffer.from([0, 1]);
|
||||
await setBlob(app, u1.token.token, workspace.id, buffer2);
|
||||
|
||||
const size = await collectBlobSizes(app, u1.token.token, workspace.id);
|
||||
ok(size === 4, 'failed to collect blob sizes');
|
||||
});
|
||||
});
|
||||
|
5
packages/graphql/src/graphql/blob-size.gql
Normal file
5
packages/graphql/src/graphql/blob-size.gql
Normal file
@ -0,0 +1,5 @@
|
||||
query blobSizes($workspaceId: String!) {
|
||||
collectBlobSizes(workspaceId: $workspaceId) {
|
||||
size
|
||||
}
|
||||
}
|
@ -40,6 +40,19 @@ mutation setBlob($workspaceId: String!, $blob: Upload!) {
|
||||
}`,
|
||||
};
|
||||
|
||||
export const blobSizesQuery = {
|
||||
id: 'blobSizesQuery' as const,
|
||||
operationName: 'blobSizes',
|
||||
definitionName: 'collectBlobSizes',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query blobSizes($workspaceId: String!) {
|
||||
collectBlobSizes(workspaceId: $workspaceId) {
|
||||
size
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const changeEmailMutation = {
|
||||
id: 'changeEmailMutation' as const,
|
||||
operationName: 'changeEmail',
|
||||
|
@ -73,6 +73,15 @@ export type SetBlobMutationVariables = Exact<{
|
||||
|
||||
export type SetBlobMutation = { __typename?: 'Mutation'; setBlob: string };
|
||||
|
||||
export type BlobSizesQueryVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type BlobSizesQuery = {
|
||||
__typename?: 'Query';
|
||||
collectBlobSizes: { __typename?: 'WorkspaceBlobSizes'; size: number };
|
||||
};
|
||||
|
||||
export type ChangeEmailMutationVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
newEmail: Scalars['String']['input'];
|
||||
@ -434,6 +443,11 @@ export type Queries =
|
||||
variables: ListBlobsQueryVariables;
|
||||
response: ListBlobsQuery;
|
||||
}
|
||||
| {
|
||||
name: 'blobSizesQuery';
|
||||
variables: BlobSizesQueryVariables;
|
||||
response: BlobSizesQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getCurrentUserQuery';
|
||||
variables: GetCurrentUserQueryVariables;
|
||||
|
0
scripts/bump-octobase.sh
Normal file → Executable file
0
scripts/bump-octobase.sh
Normal file → Executable file
Loading…
x
Reference in New Issue
Block a user