mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 12:55:00 +00:00
feat!: affine cloud support (#3813)
Co-authored-by: Hongtao Lye <codert.sn@gmail.com> Co-authored-by: liuyi <forehalo@gmail.com> Co-authored-by: LongYinan <lynweklm@gmail.com> Co-authored-by: X1a0t <405028157@qq.com> Co-authored-by: JimmFly <yangjinfei001@gmail.com> Co-authored-by: Peng Xiao <pengxiao@outlook.com> Co-authored-by: xiaodong zuo <53252747+zuoxiaodong0815@users.noreply.github.com> Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com> Co-authored-by: Qi <474021214@qq.com> Co-authored-by: danielchim <kahungchim@gmail.com>
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
import { nanoid } from 'nanoid';
|
||||
import type { Mock } from 'vitest';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { gqlFetcherFactory } from '../fetcher';
|
||||
import type { GraphQLQuery } from '../graphql';
|
||||
import {
|
||||
generateRandUTF16Chars,
|
||||
SPAN_ID_BYTES,
|
||||
TRACE_ID_BYTES,
|
||||
TraceReporter,
|
||||
} from '../utils';
|
||||
|
||||
const query: GraphQLQuery = {
|
||||
id: 'query',
|
||||
@@ -51,16 +58,18 @@ describe('GraphQL fetcher', () => {
|
||||
variables: { a: 1, b: '2', c: { d: false } },
|
||||
});
|
||||
|
||||
expect(fetch.mock.lastCall[1]).toMatchInlineSnapshot(`
|
||||
{
|
||||
"body": "{\\"query\\":\\"query { field }\\",\\"variables\\":{\\"a\\":1,\\"b\\":\\"2\\",\\"c\\":{\\"d\\":false}},\\"operationName\\":\\"query\\"}",
|
||||
"headers": {
|
||||
"x-definition-name": "query",
|
||||
"x-operation-name": "query",
|
||||
},
|
||||
"method": "POST",
|
||||
}
|
||||
`);
|
||||
expect(fetch.mock.lastCall[1]).toEqual(
|
||||
expect.objectContaining({
|
||||
body: '{"query":"query { field }","variables":{"a":1,"b":"2","c":{"d":false}},"operationName":"query"}',
|
||||
headers: expect.objectContaining({
|
||||
'content-type': 'application/json',
|
||||
'x-definition-name': 'query',
|
||||
'x-operation-name': 'query',
|
||||
'x-request-id': expect.any(String),
|
||||
}),
|
||||
method: 'POST',
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should correctly ignore nil variables', async () => {
|
||||
@@ -110,3 +119,41 @@ describe('GraphQL fetcher', () => {
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Trace Reporter', () => {
|
||||
const startTime = new Date().toISOString();
|
||||
const traceId = generateRandUTF16Chars(TRACE_ID_BYTES);
|
||||
const spanId = generateRandUTF16Chars(SPAN_ID_BYTES);
|
||||
const requestId = nanoid();
|
||||
|
||||
it('spanId, traceId should be right format', () => {
|
||||
expect(
|
||||
new RegExp(`^[0-9a-f]{${SPAN_ID_BYTES * 2}}$`).test(
|
||||
generateRandUTF16Chars(SPAN_ID_BYTES)
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
new RegExp(`^[0-9a-f]{${TRACE_ID_BYTES * 2}}$`).test(
|
||||
generateRandUTF16Chars(TRACE_ID_BYTES)
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('test createTraceSpan', () => {
|
||||
const traceSpan = TraceReporter.createTraceSpan(
|
||||
traceId,
|
||||
spanId,
|
||||
requestId,
|
||||
startTime
|
||||
);
|
||||
expect(traceSpan.startTime).toBe(startTime);
|
||||
expect(
|
||||
traceSpan.name ===
|
||||
`projects/{GCP_PROJECT_ID}/traces/${traceId}/spans/${spanId}`
|
||||
).toBe(true);
|
||||
expect(traceSpan.spanId).toBe(spanId);
|
||||
expect(traceSpan.attributes.attributeMap.requestId.stringValue.value).toBe(
|
||||
requestId
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import type { ExecutionResult } from 'graphql';
|
||||
import { GraphQLError } from 'graphql';
|
||||
import { isNil, isObject, merge } from 'lodash-es';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import type { GraphQLQuery } from './graphql';
|
||||
import type { Mutations, Queries } from './schema';
|
||||
import {
|
||||
generateRandUTF16Chars,
|
||||
SPAN_ID_BYTES,
|
||||
TRACE_FLAG,
|
||||
TRACE_ID_BYTES,
|
||||
TRACE_VERSION,
|
||||
traceReporter,
|
||||
} from './utils';
|
||||
|
||||
export type NotArray<T> = T extends Array<unknown> ? never : T;
|
||||
|
||||
@@ -116,19 +125,24 @@ export function transformToForm(body: RequestBody) {
|
||||
if (body.operationName) {
|
||||
gqlBody.name = body.operationName;
|
||||
}
|
||||
|
||||
const map: Record<string, [string]> = {};
|
||||
const files: File[] = [];
|
||||
if (body.variables) {
|
||||
let i = 0;
|
||||
Object.entries(body.variables).forEach(([key, value]) => {
|
||||
if (value instanceof File) {
|
||||
gqlBody.map['0'] = [`variables.${key}`];
|
||||
form.append(`${i}`, value);
|
||||
map['0'] = [`variables.${key}`];
|
||||
files[i] = value;
|
||||
i++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
form.append('operations', JSON.stringify(gqlBody));
|
||||
form.set('operations', JSON.stringify(gqlBody));
|
||||
form.set('map', JSON.stringify(map));
|
||||
for (const [i, file] of files.entries()) {
|
||||
form.set(`${i}`, file);
|
||||
}
|
||||
return form;
|
||||
}
|
||||
|
||||
@@ -159,20 +173,25 @@ export const gqlFetcherFactory = (endpoint: string) => {
|
||||
): Promise<QueryResponse<Query>> => {
|
||||
const body = formatRequestBody(options);
|
||||
|
||||
const ret = fetch(
|
||||
const isFormData = body instanceof FormData;
|
||||
const headers: Record<string, string> = {
|
||||
'x-operation-name': options.query.operationName,
|
||||
'x-definition-name': options.query.definitionName,
|
||||
};
|
||||
if (!isFormData) {
|
||||
headers['content-type'] = 'application/json';
|
||||
}
|
||||
const ret = fetchWithReport(
|
||||
endpoint,
|
||||
merge(options.context, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-operation-name': options.query.operationName,
|
||||
'x-definition-name': options.query.definitionName,
|
||||
},
|
||||
body: body instanceof FormData ? body : JSON.stringify(body),
|
||||
headers,
|
||||
body: isFormData ? body : JSON.stringify(body),
|
||||
})
|
||||
).then(async res => {
|
||||
if (res.headers.get('content-type') === 'application/json') {
|
||||
if (res.headers.get('content-type')?.startsWith('application/json')) {
|
||||
const result = (await res.json()) as ExecutionResult;
|
||||
if (res.status >= 400) {
|
||||
if (res.status >= 400 || result.errors) {
|
||||
if (result.errors && result.errors.length > 0) {
|
||||
throw result.errors.map(
|
||||
error => new GraphQLError(error.message, error)
|
||||
@@ -194,3 +213,40 @@ export const gqlFetcherFactory = (endpoint: string) => {
|
||||
|
||||
return gqlFetch;
|
||||
};
|
||||
|
||||
export const fetchWithReport = (
|
||||
input: RequestInfo | URL,
|
||||
init?: RequestInit
|
||||
): Promise<Response> => {
|
||||
const startTime = new Date().toISOString();
|
||||
const spanId = generateRandUTF16Chars(SPAN_ID_BYTES);
|
||||
const traceId = generateRandUTF16Chars(TRACE_ID_BYTES);
|
||||
const traceparent = `${TRACE_VERSION}-${traceId}-${spanId}-${TRACE_FLAG}`;
|
||||
init = init || {};
|
||||
init.headers = init.headers || new Headers();
|
||||
const requestId = nanoid();
|
||||
if (init.headers instanceof Headers) {
|
||||
init.headers.append('x-request-id', requestId);
|
||||
init.headers.append('traceparent', traceparent);
|
||||
} else {
|
||||
const headers = init.headers as Record<string, string>;
|
||||
headers['x-request-id'] = requestId;
|
||||
headers['traceparent'] = traceparent;
|
||||
}
|
||||
|
||||
if (!traceReporter) {
|
||||
return fetch(input, init);
|
||||
}
|
||||
|
||||
return fetch(input, init)
|
||||
.then(response => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
traceReporter!.cacheTrace(traceId, spanId, requestId, startTime);
|
||||
return response;
|
||||
})
|
||||
.catch(err => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
traceReporter!.uploadTrace(traceId, spanId, requestId, startTime);
|
||||
return Promise.reject(err);
|
||||
});
|
||||
};
|
||||
|
||||
3
packages/graphql/src/graphql/blob-delete.gql
Normal file
3
packages/graphql/src/graphql/blob-delete.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation deleteBlob($workspaceId: String!, $hash: String!) {
|
||||
deleteBlob(workspaceId: $workspaceId, hash: $hash)
|
||||
}
|
||||
3
packages/graphql/src/graphql/blob-list.gql
Normal file
3
packages/graphql/src/graphql/blob-list.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
query listBlobs($workspaceId: String!) {
|
||||
listBlobs(workspaceId: $workspaceId)
|
||||
}
|
||||
3
packages/graphql/src/graphql/blob-set.gql
Normal file
3
packages/graphql/src/graphql/blob-set.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation setBlob($workspaceId: String!, $blob: Upload!) {
|
||||
setBlob(workspaceId: $workspaceId, blob: $blob)
|
||||
}
|
||||
8
packages/graphql/src/graphql/change-email.gql
Normal file
8
packages/graphql/src/graphql/change-email.gql
Normal file
@@ -0,0 +1,8 @@
|
||||
mutation changeEmail($id: String!, $newEmail: String!) {
|
||||
changeEmail(id: $id, email: $newEmail) {
|
||||
id
|
||||
name
|
||||
avatarUrl
|
||||
email
|
||||
}
|
||||
}
|
||||
8
packages/graphql/src/graphql/change-password.gql
Normal file
8
packages/graphql/src/graphql/change-password.gql
Normal file
@@ -0,0 +1,8 @@
|
||||
mutation changePassword($id: String!, $newPassword: String!) {
|
||||
changePassword(id: $id, newPassword: $newPassword) {
|
||||
id
|
||||
name
|
||||
avatarUrl
|
||||
email
|
||||
}
|
||||
}
|
||||
5
packages/graphql/src/graphql/delete-account.gql
Normal file
5
packages/graphql/src/graphql/delete-account.gql
Normal file
@@ -0,0 +1,5 @@
|
||||
mutation deleteAccount {
|
||||
deleteAccount {
|
||||
success
|
||||
}
|
||||
}
|
||||
3
packages/graphql/src/graphql/delete-workspace.gql
Normal file
3
packages/graphql/src/graphql/delete-workspace.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation deleteWorkspace($id: String!) {
|
||||
deleteWorkspace(id: $id)
|
||||
}
|
||||
10
packages/graphql/src/graphql/get-current-user.gql
Normal file
10
packages/graphql/src/graphql/get-current-user.gql
Normal file
@@ -0,0 +1,10 @@
|
||||
query getCurrentUser {
|
||||
currentUser {
|
||||
id
|
||||
name
|
||||
email
|
||||
emailVerified
|
||||
avatarUrl
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
14
packages/graphql/src/graphql/get-invite-info.gql
Normal file
14
packages/graphql/src/graphql/get-invite-info.gql
Normal file
@@ -0,0 +1,14 @@
|
||||
query getInviteInfo($inviteId: String!) {
|
||||
getInviteInfo(inviteId: $inviteId) {
|
||||
workspace {
|
||||
id
|
||||
name
|
||||
avatar
|
||||
}
|
||||
user {
|
||||
id
|
||||
name
|
||||
avatarUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
3
packages/graphql/src/graphql/get-is-owner.gql
Normal file
3
packages/graphql/src/graphql/get-is-owner.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
query getIsOwner($workspaceId: String!) {
|
||||
isOwner(workspaceId: $workspaceId)
|
||||
}
|
||||
14
packages/graphql/src/graphql/get-members-by-workspace-id.gql
Normal file
14
packages/graphql/src/graphql/get-members-by-workspace-id.gql
Normal file
@@ -0,0 +1,14 @@
|
||||
query getMembersByWorkspaceId($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
members {
|
||||
id
|
||||
name
|
||||
email
|
||||
avatarUrl
|
||||
permission
|
||||
inviteId
|
||||
accepted
|
||||
emailVerified
|
||||
}
|
||||
}
|
||||
}
|
||||
5
packages/graphql/src/graphql/get-public-workspace.gql
Normal file
5
packages/graphql/src/graphql/get-public-workspace.gql
Normal file
@@ -0,0 +1,5 @@
|
||||
query getPublicWorkspace($id: String!) {
|
||||
publicWorkspace(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
9
packages/graphql/src/graphql/get-user.gql
Normal file
9
packages/graphql/src/graphql/get-user.gql
Normal file
@@ -0,0 +1,9 @@
|
||||
query getUser($email: String!) {
|
||||
user(email: $email) {
|
||||
id
|
||||
name
|
||||
avatarUrl
|
||||
email
|
||||
hasPassword
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
query getWorkspacePublicById($id: String!) {
|
||||
workspace(id: $id) {
|
||||
public
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
query getWorkspaceSharedPages($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
sharedPages
|
||||
}
|
||||
}
|
||||
5
packages/graphql/src/graphql/get-workspace.gql
Normal file
5
packages/graphql/src/graphql/get-workspace.gql
Normal file
@@ -0,0 +1,5 @@
|
||||
query getWorkspace($id: String!) {
|
||||
workspace(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
5
packages/graphql/src/graphql/get-workspaces.gql
Normal file
5
packages/graphql/src/graphql/get-workspaces.gql
Normal file
@@ -0,0 +1,5 @@
|
||||
query getWorkspaces {
|
||||
workspaces {
|
||||
id
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,71 @@ export interface GraphQLQuery {
|
||||
containsFile?: boolean;
|
||||
}
|
||||
|
||||
export const deleteBlobMutation = {
|
||||
id: 'deleteBlobMutation' as const,
|
||||
operationName: 'deleteBlob',
|
||||
definitionName: 'deleteBlob',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation deleteBlob($workspaceId: String!, $hash: String!) {
|
||||
deleteBlob(workspaceId: $workspaceId, hash: $hash)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const listBlobsQuery = {
|
||||
id: 'listBlobsQuery' as const,
|
||||
operationName: 'listBlobs',
|
||||
definitionName: 'listBlobs',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query listBlobs($workspaceId: String!) {
|
||||
listBlobs(workspaceId: $workspaceId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const setBlobMutation = {
|
||||
id: 'setBlobMutation' as const,
|
||||
operationName: 'setBlob',
|
||||
definitionName: 'setBlob',
|
||||
containsFile: true,
|
||||
query: `
|
||||
mutation setBlob($workspaceId: String!, $blob: Upload!) {
|
||||
setBlob(workspaceId: $workspaceId, blob: $blob)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const changeEmailMutation = {
|
||||
id: 'changeEmailMutation' as const,
|
||||
operationName: 'changeEmail',
|
||||
definitionName: 'changeEmail',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation changeEmail($id: String!, $newEmail: String!) {
|
||||
changeEmail(id: $id, email: $newEmail) {
|
||||
id
|
||||
name
|
||||
avatarUrl
|
||||
email
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const changePasswordMutation = {
|
||||
id: 'changePasswordMutation' as const,
|
||||
operationName: 'changePassword',
|
||||
definitionName: 'changePassword',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation changePassword($id: String!, $newPassword: String!) {
|
||||
changePassword(id: $id, newPassword: $newPassword) {
|
||||
id
|
||||
name
|
||||
avatarUrl
|
||||
email
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const createWorkspaceMutation = {
|
||||
id: 'createWorkspaceMutation' as const,
|
||||
operationName: 'createWorkspace',
|
||||
@@ -22,6 +87,327 @@ mutation createWorkspace($init: Upload!) {
|
||||
}`,
|
||||
};
|
||||
|
||||
export const deleteAccountMutation = {
|
||||
id: 'deleteAccountMutation' as const,
|
||||
operationName: 'deleteAccount',
|
||||
definitionName: 'deleteAccount',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation deleteAccount {
|
||||
deleteAccount {
|
||||
success
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const deleteWorkspaceMutation = {
|
||||
id: 'deleteWorkspaceMutation' as const,
|
||||
operationName: 'deleteWorkspace',
|
||||
definitionName: 'deleteWorkspace',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation deleteWorkspace($id: String!) {
|
||||
deleteWorkspace(id: $id)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getCurrentUserQuery = {
|
||||
id: 'getCurrentUserQuery' as const,
|
||||
operationName: 'getCurrentUser',
|
||||
definitionName: 'currentUser',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getCurrentUser {
|
||||
currentUser {
|
||||
id
|
||||
name
|
||||
email
|
||||
emailVerified
|
||||
avatarUrl
|
||||
createdAt
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getInviteInfoQuery = {
|
||||
id: 'getInviteInfoQuery' as const,
|
||||
operationName: 'getInviteInfo',
|
||||
definitionName: 'getInviteInfo',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getInviteInfo($inviteId: String!) {
|
||||
getInviteInfo(inviteId: $inviteId) {
|
||||
workspace {
|
||||
id
|
||||
name
|
||||
avatar
|
||||
}
|
||||
user {
|
||||
id
|
||||
name
|
||||
avatarUrl
|
||||
}
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getIsOwnerQuery = {
|
||||
id: 'getIsOwnerQuery' as const,
|
||||
operationName: 'getIsOwner',
|
||||
definitionName: 'isOwner',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getIsOwner($workspaceId: String!) {
|
||||
isOwner(workspaceId: $workspaceId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getMembersByWorkspaceIdQuery = {
|
||||
id: 'getMembersByWorkspaceIdQuery' as const,
|
||||
operationName: 'getMembersByWorkspaceId',
|
||||
definitionName: 'workspace',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getMembersByWorkspaceId($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
members {
|
||||
id
|
||||
name
|
||||
email
|
||||
avatarUrl
|
||||
permission
|
||||
inviteId
|
||||
accepted
|
||||
emailVerified
|
||||
}
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getPublicWorkspaceQuery = {
|
||||
id: 'getPublicWorkspaceQuery' as const,
|
||||
operationName: 'getPublicWorkspace',
|
||||
definitionName: 'publicWorkspace',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getPublicWorkspace($id: String!) {
|
||||
publicWorkspace(id: $id) {
|
||||
id
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getUserQuery = {
|
||||
id: 'getUserQuery' as const,
|
||||
operationName: 'getUser',
|
||||
definitionName: 'user',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getUser($email: String!) {
|
||||
user(email: $email) {
|
||||
id
|
||||
name
|
||||
avatarUrl
|
||||
email
|
||||
hasPassword
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getWorkspacePublicByIdQuery = {
|
||||
id: 'getWorkspacePublicByIdQuery' as const,
|
||||
operationName: 'getWorkspacePublicById',
|
||||
definitionName: 'workspace',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getWorkspacePublicById($id: String!) {
|
||||
workspace(id: $id) {
|
||||
public
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getWorkspaceSharedPagesQuery = {
|
||||
id: 'getWorkspaceSharedPagesQuery' as const,
|
||||
operationName: 'getWorkspaceSharedPages',
|
||||
definitionName: 'workspace',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getWorkspaceSharedPages($workspaceId: String!) {
|
||||
workspace(id: $workspaceId) {
|
||||
sharedPages
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getWorkspaceQuery = {
|
||||
id: 'getWorkspaceQuery' as const,
|
||||
operationName: 'getWorkspace',
|
||||
definitionName: 'workspace',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getWorkspace($id: String!) {
|
||||
workspace(id: $id) {
|
||||
id
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const getWorkspacesQuery = {
|
||||
id: 'getWorkspacesQuery' as const,
|
||||
operationName: 'getWorkspaces',
|
||||
definitionName: 'workspaces',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query getWorkspaces {
|
||||
workspaces {
|
||||
id
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const leaveWorkspaceMutation = {
|
||||
id: 'leaveWorkspaceMutation' as const,
|
||||
operationName: 'leaveWorkspace',
|
||||
definitionName: 'leaveWorkspace',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation leaveWorkspace($workspaceId: String!) {
|
||||
leaveWorkspace(workspaceId: $workspaceId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const revokeMemberPermissionMutation = {
|
||||
id: 'revokeMemberPermissionMutation' as const,
|
||||
operationName: 'revokeMemberPermission',
|
||||
definitionName: 'revoke',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation revokeMemberPermission($workspaceId: String!, $userId: String!) {
|
||||
revoke(workspaceId: $workspaceId, userId: $userId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const revokePageMutation = {
|
||||
id: 'revokePageMutation' as const,
|
||||
operationName: 'revokePage',
|
||||
definitionName: 'revokePage',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation revokePage($workspaceId: String!, $pageId: String!) {
|
||||
revokePage(workspaceId: $workspaceId, pageId: $pageId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const sendChangeEmailMutation = {
|
||||
id: 'sendChangeEmailMutation' as const,
|
||||
operationName: 'sendChangeEmail',
|
||||
definitionName: 'sendChangeEmail',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation sendChangeEmail($email: String!, $callbackUrl: String!) {
|
||||
sendChangeEmail(email: $email, callbackUrl: $callbackUrl)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const sendChangePasswordEmailMutation = {
|
||||
id: 'sendChangePasswordEmailMutation' as const,
|
||||
operationName: 'sendChangePasswordEmail',
|
||||
definitionName: 'sendChangePasswordEmail',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation sendChangePasswordEmail($email: String!, $callbackUrl: String!) {
|
||||
sendChangePasswordEmail(email: $email, callbackUrl: $callbackUrl)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const sendSetPasswordEmailMutation = {
|
||||
id: 'sendSetPasswordEmailMutation' as const,
|
||||
operationName: 'sendSetPasswordEmail',
|
||||
definitionName: 'sendSetPasswordEmail',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation sendSetPasswordEmail($email: String!, $callbackUrl: String!) {
|
||||
sendSetPasswordEmail(email: $email, callbackUrl: $callbackUrl)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const setRevokePageMutation = {
|
||||
id: 'setRevokePageMutation' as const,
|
||||
operationName: 'setRevokePage',
|
||||
definitionName: 'revokePage',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation setRevokePage($workspaceId: String!, $pageId: String!) {
|
||||
revokePage(workspaceId: $workspaceId, pageId: $pageId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const setSharePageMutation = {
|
||||
id: 'setSharePageMutation' as const,
|
||||
operationName: 'setSharePage',
|
||||
definitionName: 'sharePage',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation setSharePage($workspaceId: String!, $pageId: String!) {
|
||||
sharePage(workspaceId: $workspaceId, pageId: $pageId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const setWorkspacePublicByIdMutation = {
|
||||
id: 'setWorkspacePublicByIdMutation' as const,
|
||||
operationName: 'setWorkspacePublicById',
|
||||
definitionName: 'updateWorkspace',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation setWorkspacePublicById($id: ID!, $public: Boolean!) {
|
||||
updateWorkspace(input: {id: $id, public: $public}) {
|
||||
id
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const sharePageMutation = {
|
||||
id: 'sharePageMutation' as const,
|
||||
operationName: 'sharePage',
|
||||
definitionName: 'sharePage',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation sharePage($workspaceId: String!, $pageId: String!) {
|
||||
sharePage(workspaceId: $workspaceId, pageId: $pageId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const signInMutation = {
|
||||
id: 'signInMutation' as const,
|
||||
operationName: 'signIn',
|
||||
definitionName: 'signIn',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation signIn($email: String!, $password: String!) {
|
||||
signIn(email: $email, password: $password) {
|
||||
token {
|
||||
token
|
||||
}
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const signUpMutation = {
|
||||
id: 'signUpMutation' as const,
|
||||
operationName: 'signUp',
|
||||
definitionName: 'signUp',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation signUp($name: String!, $email: String!, $password: String!) {
|
||||
signUp(name: $name, email: $email, password: $password) {
|
||||
token {
|
||||
token
|
||||
}
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const uploadAvatarMutation = {
|
||||
id: 'uploadAvatarMutation' as const,
|
||||
operationName: 'uploadAvatar',
|
||||
@@ -38,17 +424,40 @@ mutation uploadAvatar($id: String!, $avatar: Upload!) {
|
||||
}`,
|
||||
};
|
||||
|
||||
export const workspaceByIdQuery = {
|
||||
id: 'workspaceByIdQuery' as const,
|
||||
operationName: 'workspaceById',
|
||||
definitionName: 'workspace',
|
||||
export const inviteByEmailMutation = {
|
||||
id: 'inviteByEmailMutation' as const,
|
||||
operationName: 'inviteByEmail',
|
||||
definitionName: 'invite',
|
||||
containsFile: false,
|
||||
query: `
|
||||
query workspaceById($id: String!) {
|
||||
workspace(id: $id) {
|
||||
id
|
||||
public
|
||||
createdAt
|
||||
}
|
||||
mutation inviteByEmail($workspaceId: String!, $email: String!, $permission: Permission!, $sendInviteMail: Boolean) {
|
||||
invite(
|
||||
workspaceId: $workspaceId
|
||||
email: $email
|
||||
permission: $permission
|
||||
sendInviteMail: $sendInviteMail
|
||||
)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const acceptInviteByInviteIdMutation = {
|
||||
id: 'acceptInviteByInviteIdMutation' as const,
|
||||
operationName: 'acceptInviteByInviteId',
|
||||
definitionName: 'acceptInviteById',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation acceptInviteByInviteId($workspaceId: String!, $inviteId: String!) {
|
||||
acceptInviteById(workspaceId: $workspaceId, inviteId: $inviteId)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const acceptInviteByWorkspaceIdMutation = {
|
||||
id: 'acceptInviteByWorkspaceIdMutation' as const,
|
||||
operationName: 'acceptInviteByWorkspaceId',
|
||||
definitionName: 'acceptInvite',
|
||||
containsFile: false,
|
||||
query: `
|
||||
mutation acceptInviteByWorkspaceId($workspaceId: String!) {
|
||||
acceptInvite(workspaceId: $workspaceId)
|
||||
}`,
|
||||
};
|
||||
|
||||
3
packages/graphql/src/graphql/leave-workspace.gql
Normal file
3
packages/graphql/src/graphql/leave-workspace.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation leaveWorkspace($workspaceId: String!) {
|
||||
leaveWorkspace(workspaceId: $workspaceId)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mutation revokeMemberPermission($workspaceId: String!, $userId: String!) {
|
||||
revoke(workspaceId: $workspaceId, userId: $userId)
|
||||
}
|
||||
3
packages/graphql/src/graphql/revoke-page.gql
Normal file
3
packages/graphql/src/graphql/revoke-page.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation revokePage($workspaceId: String!, $pageId: String!) {
|
||||
revokePage(workspaceId: $workspaceId, pageId: $pageId)
|
||||
}
|
||||
3
packages/graphql/src/graphql/send-change-email.gql
Normal file
3
packages/graphql/src/graphql/send-change-email.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation sendChangeEmail($email: String!, $callbackUrl: String!) {
|
||||
sendChangeEmail(email: $email, callbackUrl: $callbackUrl)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mutation sendChangePasswordEmail($email: String!, $callbackUrl: String!) {
|
||||
sendChangePasswordEmail(email: $email, callbackUrl: $callbackUrl)
|
||||
}
|
||||
3
packages/graphql/src/graphql/send-set-password-email.gql
Normal file
3
packages/graphql/src/graphql/send-set-password-email.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation sendSetPasswordEmail($email: String!, $callbackUrl: String!) {
|
||||
sendSetPasswordEmail(email: $email, callbackUrl: $callbackUrl)
|
||||
}
|
||||
3
packages/graphql/src/graphql/set-revoke-page.gql
Normal file
3
packages/graphql/src/graphql/set-revoke-page.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation setRevokePage($workspaceId: String!, $pageId: String!) {
|
||||
revokePage(workspaceId: $workspaceId, pageId: $pageId)
|
||||
}
|
||||
3
packages/graphql/src/graphql/set-share-page.gql
Normal file
3
packages/graphql/src/graphql/set-share-page.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation setSharePage($workspaceId: String!, $pageId: String!) {
|
||||
sharePage(workspaceId: $workspaceId, pageId: $pageId)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
mutation setWorkspacePublicById($id: ID!, $public: Boolean!) {
|
||||
updateWorkspace(input: { id: $id, public: $public }) {
|
||||
id
|
||||
}
|
||||
}
|
||||
3
packages/graphql/src/graphql/share-page.gql
Normal file
3
packages/graphql/src/graphql/share-page.gql
Normal file
@@ -0,0 +1,3 @@
|
||||
mutation sharePage($workspaceId: String!, $pageId: String!) {
|
||||
sharePage(workspaceId: $workspaceId, pageId: $pageId)
|
||||
}
|
||||
7
packages/graphql/src/graphql/sign-in.gql
Normal file
7
packages/graphql/src/graphql/sign-in.gql
Normal file
@@ -0,0 +1,7 @@
|
||||
mutation signIn($email: String!, $password: String!) {
|
||||
signIn(email: $email, password: $password) {
|
||||
token {
|
||||
token
|
||||
}
|
||||
}
|
||||
}
|
||||
7
packages/graphql/src/graphql/sign-up.gql
Normal file
7
packages/graphql/src/graphql/sign-up.gql
Normal file
@@ -0,0 +1,7 @@
|
||||
mutation signUp($name: String!, $email: String!, $password: String!) {
|
||||
signUp(name: $name, email: $email, password: $password) {
|
||||
token {
|
||||
token
|
||||
}
|
||||
}
|
||||
}
|
||||
13
packages/graphql/src/graphql/workspace-intive-by-email.gql
Normal file
13
packages/graphql/src/graphql/workspace-intive-by-email.gql
Normal file
@@ -0,0 +1,13 @@
|
||||
mutation inviteByEmail(
|
||||
$workspaceId: String!
|
||||
$email: String!
|
||||
$permission: Permission!
|
||||
$sendInviteMail: Boolean
|
||||
) {
|
||||
invite(
|
||||
workspaceId: $workspaceId
|
||||
email: $email
|
||||
permission: $permission
|
||||
sendInviteMail: $sendInviteMail
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mutation acceptInviteByInviteId($workspaceId: String!, $inviteId: String!) {
|
||||
acceptInviteById(workspaceId: $workspaceId, inviteId: $inviteId)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mutation acceptInviteByWorkspaceId($workspaceId: String!) {
|
||||
acceptInvite(workspaceId: $workspaceId)
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
query workspaceById($id: String!) {
|
||||
workspace(id: $id) {
|
||||
id
|
||||
public
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './fetcher';
|
||||
export * from './graphql';
|
||||
export * from './schema';
|
||||
import '@affine/env/global';
|
||||
|
||||
@@ -32,6 +32,10 @@ export interface Scalars {
|
||||
Upload: { input: File; output: File };
|
||||
}
|
||||
|
||||
export enum NewFeaturesKind {
|
||||
EarlyAccess = 'EarlyAccess',
|
||||
}
|
||||
|
||||
/** User permission in workspace */
|
||||
export enum Permission {
|
||||
Admin = 'Admin',
|
||||
@@ -46,6 +50,61 @@ export interface UpdateWorkspaceInput {
|
||||
public: InputMaybe<Scalars['Boolean']['input']>;
|
||||
}
|
||||
|
||||
export type DeleteBlobMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
hash: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type DeleteBlobMutation = {
|
||||
__typename?: 'Mutation';
|
||||
deleteBlob: boolean;
|
||||
};
|
||||
|
||||
export type ListBlobsQueryVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type ListBlobsQuery = { __typename?: 'Query'; listBlobs: Array<string> };
|
||||
|
||||
export type SetBlobMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
blob: Scalars['Upload']['input'];
|
||||
}>;
|
||||
|
||||
export type SetBlobMutation = { __typename?: 'Mutation'; setBlob: string };
|
||||
|
||||
export type ChangeEmailMutationVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
newEmail: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type ChangeEmailMutation = {
|
||||
__typename?: 'Mutation';
|
||||
changeEmail: {
|
||||
__typename?: 'UserType';
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string | null;
|
||||
email: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type ChangePasswordMutationVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
newPassword: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type ChangePasswordMutation = {
|
||||
__typename?: 'Mutation';
|
||||
changePassword: {
|
||||
__typename?: 'UserType';
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string | null;
|
||||
email: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type CreateWorkspaceMutationVariables = Exact<{
|
||||
init: Scalars['Upload']['input'];
|
||||
}>;
|
||||
@@ -60,6 +119,270 @@ export type CreateWorkspaceMutation = {
|
||||
};
|
||||
};
|
||||
|
||||
export type DeleteAccountMutationVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type DeleteAccountMutation = {
|
||||
__typename?: 'Mutation';
|
||||
deleteAccount: { __typename?: 'DeleteAccount'; success: boolean };
|
||||
};
|
||||
|
||||
export type DeleteWorkspaceMutationVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type DeleteWorkspaceMutation = {
|
||||
__typename?: 'Mutation';
|
||||
deleteWorkspace: boolean;
|
||||
};
|
||||
|
||||
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type GetCurrentUserQuery = {
|
||||
__typename?: 'Query';
|
||||
currentUser: {
|
||||
__typename?: 'UserType';
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
emailVerified: string | null;
|
||||
avatarUrl: string | null;
|
||||
createdAt: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
export type GetInviteInfoQueryVariables = Exact<{
|
||||
inviteId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type GetInviteInfoQuery = {
|
||||
__typename?: 'Query';
|
||||
getInviteInfo: {
|
||||
__typename?: 'InvitationType';
|
||||
workspace: {
|
||||
__typename?: 'InvitationWorkspaceType';
|
||||
id: string;
|
||||
name: string;
|
||||
avatar: string;
|
||||
};
|
||||
user: {
|
||||
__typename?: 'UserType';
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string | null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type GetIsOwnerQueryVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type GetIsOwnerQuery = { __typename?: 'Query'; isOwner: boolean };
|
||||
|
||||
export type GetMembersByWorkspaceIdQueryVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type GetMembersByWorkspaceIdQuery = {
|
||||
__typename?: 'Query';
|
||||
workspace: {
|
||||
__typename?: 'WorkspaceType';
|
||||
members: Array<{
|
||||
__typename?: 'InviteUserType';
|
||||
id: string;
|
||||
name: string | null;
|
||||
email: string | null;
|
||||
avatarUrl: string | null;
|
||||
permission: Permission;
|
||||
inviteId: string;
|
||||
accepted: boolean;
|
||||
emailVerified: string | null;
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
export type GetPublicWorkspaceQueryVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type GetPublicWorkspaceQuery = {
|
||||
__typename?: 'Query';
|
||||
publicWorkspace: { __typename?: 'WorkspaceType'; id: string };
|
||||
};
|
||||
|
||||
export type GetUserQueryVariables = Exact<{
|
||||
email: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type GetUserQuery = {
|
||||
__typename?: 'Query';
|
||||
user: {
|
||||
__typename?: 'UserType';
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string | null;
|
||||
email: string;
|
||||
hasPassword: boolean | null;
|
||||
} | null;
|
||||
};
|
||||
|
||||
export type GetWorkspacePublicByIdQueryVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type GetWorkspacePublicByIdQuery = {
|
||||
__typename?: 'Query';
|
||||
workspace: { __typename?: 'WorkspaceType'; public: boolean };
|
||||
};
|
||||
|
||||
export type GetWorkspaceSharedPagesQueryVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type GetWorkspaceSharedPagesQuery = {
|
||||
__typename?: 'Query';
|
||||
workspace: { __typename?: 'WorkspaceType'; sharedPages: Array<string> };
|
||||
};
|
||||
|
||||
export type GetWorkspaceQueryVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type GetWorkspaceQuery = {
|
||||
__typename?: 'Query';
|
||||
workspace: { __typename?: 'WorkspaceType'; id: string };
|
||||
};
|
||||
|
||||
export type GetWorkspacesQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type GetWorkspacesQuery = {
|
||||
__typename?: 'Query';
|
||||
workspaces: Array<{ __typename?: 'WorkspaceType'; id: string }>;
|
||||
};
|
||||
|
||||
export type LeaveWorkspaceMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type LeaveWorkspaceMutation = {
|
||||
__typename?: 'Mutation';
|
||||
leaveWorkspace: boolean;
|
||||
};
|
||||
|
||||
export type RevokeMemberPermissionMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
userId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type RevokeMemberPermissionMutation = {
|
||||
__typename?: 'Mutation';
|
||||
revoke: boolean;
|
||||
};
|
||||
|
||||
export type RevokePageMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
pageId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type RevokePageMutation = {
|
||||
__typename?: 'Mutation';
|
||||
revokePage: boolean;
|
||||
};
|
||||
|
||||
export type SendChangeEmailMutationVariables = Exact<{
|
||||
email: Scalars['String']['input'];
|
||||
callbackUrl: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type SendChangeEmailMutation = {
|
||||
__typename?: 'Mutation';
|
||||
sendChangeEmail: boolean;
|
||||
};
|
||||
|
||||
export type SendChangePasswordEmailMutationVariables = Exact<{
|
||||
email: Scalars['String']['input'];
|
||||
callbackUrl: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type SendChangePasswordEmailMutation = {
|
||||
__typename?: 'Mutation';
|
||||
sendChangePasswordEmail: boolean;
|
||||
};
|
||||
|
||||
export type SendSetPasswordEmailMutationVariables = Exact<{
|
||||
email: Scalars['String']['input'];
|
||||
callbackUrl: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type SendSetPasswordEmailMutation = {
|
||||
__typename?: 'Mutation';
|
||||
sendSetPasswordEmail: boolean;
|
||||
};
|
||||
|
||||
export type SetRevokePageMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
pageId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type SetRevokePageMutation = {
|
||||
__typename?: 'Mutation';
|
||||
revokePage: boolean;
|
||||
};
|
||||
|
||||
export type SetSharePageMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
pageId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type SetSharePageMutation = {
|
||||
__typename?: 'Mutation';
|
||||
sharePage: boolean;
|
||||
};
|
||||
|
||||
export type SetWorkspacePublicByIdMutationVariables = Exact<{
|
||||
id: Scalars['ID']['input'];
|
||||
public: Scalars['Boolean']['input'];
|
||||
}>;
|
||||
|
||||
export type SetWorkspacePublicByIdMutation = {
|
||||
__typename?: 'Mutation';
|
||||
updateWorkspace: { __typename?: 'WorkspaceType'; id: string };
|
||||
};
|
||||
|
||||
export type SharePageMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
pageId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type SharePageMutation = { __typename?: 'Mutation'; sharePage: boolean };
|
||||
|
||||
export type SignInMutationVariables = Exact<{
|
||||
email: Scalars['String']['input'];
|
||||
password: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type SignInMutation = {
|
||||
__typename?: 'Mutation';
|
||||
signIn: {
|
||||
__typename?: 'UserType';
|
||||
token: { __typename?: 'TokenType'; token: string };
|
||||
};
|
||||
};
|
||||
|
||||
export type SignUpMutationVariables = Exact<{
|
||||
name: Scalars['String']['input'];
|
||||
email: Scalars['String']['input'];
|
||||
password: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type SignUpMutation = {
|
||||
__typename?: 'Mutation';
|
||||
signUp: {
|
||||
__typename?: 'UserType';
|
||||
token: { __typename?: 'TokenType'; token: string };
|
||||
};
|
||||
};
|
||||
|
||||
export type UploadAvatarMutationVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
avatar: Scalars['Upload']['input'];
|
||||
@@ -76,34 +399,204 @@ export type UploadAvatarMutation = {
|
||||
};
|
||||
};
|
||||
|
||||
export type WorkspaceByIdQueryVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
export type InviteByEmailMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
email: Scalars['String']['input'];
|
||||
permission: Permission;
|
||||
sendInviteMail: InputMaybe<Scalars['Boolean']['input']>;
|
||||
}>;
|
||||
|
||||
export type WorkspaceByIdQuery = {
|
||||
__typename?: 'Query';
|
||||
workspace: {
|
||||
__typename?: 'WorkspaceType';
|
||||
id: string;
|
||||
public: boolean;
|
||||
createdAt: string;
|
||||
};
|
||||
export type InviteByEmailMutation = { __typename?: 'Mutation'; invite: string };
|
||||
|
||||
export type AcceptInviteByInviteIdMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
inviteId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type AcceptInviteByInviteIdMutation = {
|
||||
__typename?: 'Mutation';
|
||||
acceptInviteById: boolean;
|
||||
};
|
||||
|
||||
export type Queries = {
|
||||
name: 'workspaceByIdQuery';
|
||||
variables: WorkspaceByIdQueryVariables;
|
||||
response: WorkspaceByIdQuery;
|
||||
export type AcceptInviteByWorkspaceIdMutationVariables = Exact<{
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type AcceptInviteByWorkspaceIdMutation = {
|
||||
__typename?: 'Mutation';
|
||||
acceptInvite: boolean;
|
||||
};
|
||||
|
||||
export type Queries =
|
||||
| {
|
||||
name: 'listBlobsQuery';
|
||||
variables: ListBlobsQueryVariables;
|
||||
response: ListBlobsQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getCurrentUserQuery';
|
||||
variables: GetCurrentUserQueryVariables;
|
||||
response: GetCurrentUserQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getInviteInfoQuery';
|
||||
variables: GetInviteInfoQueryVariables;
|
||||
response: GetInviteInfoQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getIsOwnerQuery';
|
||||
variables: GetIsOwnerQueryVariables;
|
||||
response: GetIsOwnerQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getMembersByWorkspaceIdQuery';
|
||||
variables: GetMembersByWorkspaceIdQueryVariables;
|
||||
response: GetMembersByWorkspaceIdQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getPublicWorkspaceQuery';
|
||||
variables: GetPublicWorkspaceQueryVariables;
|
||||
response: GetPublicWorkspaceQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getUserQuery';
|
||||
variables: GetUserQueryVariables;
|
||||
response: GetUserQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getWorkspacePublicByIdQuery';
|
||||
variables: GetWorkspacePublicByIdQueryVariables;
|
||||
response: GetWorkspacePublicByIdQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getWorkspaceSharedPagesQuery';
|
||||
variables: GetWorkspaceSharedPagesQueryVariables;
|
||||
response: GetWorkspaceSharedPagesQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getWorkspaceQuery';
|
||||
variables: GetWorkspaceQueryVariables;
|
||||
response: GetWorkspaceQuery;
|
||||
}
|
||||
| {
|
||||
name: 'getWorkspacesQuery';
|
||||
variables: GetWorkspacesQueryVariables;
|
||||
response: GetWorkspacesQuery;
|
||||
};
|
||||
|
||||
export type Mutations =
|
||||
| {
|
||||
name: 'deleteBlobMutation';
|
||||
variables: DeleteBlobMutationVariables;
|
||||
response: DeleteBlobMutation;
|
||||
}
|
||||
| {
|
||||
name: 'setBlobMutation';
|
||||
variables: SetBlobMutationVariables;
|
||||
response: SetBlobMutation;
|
||||
}
|
||||
| {
|
||||
name: 'changeEmailMutation';
|
||||
variables: ChangeEmailMutationVariables;
|
||||
response: ChangeEmailMutation;
|
||||
}
|
||||
| {
|
||||
name: 'changePasswordMutation';
|
||||
variables: ChangePasswordMutationVariables;
|
||||
response: ChangePasswordMutation;
|
||||
}
|
||||
| {
|
||||
name: 'createWorkspaceMutation';
|
||||
variables: CreateWorkspaceMutationVariables;
|
||||
response: CreateWorkspaceMutation;
|
||||
}
|
||||
| {
|
||||
name: 'deleteAccountMutation';
|
||||
variables: DeleteAccountMutationVariables;
|
||||
response: DeleteAccountMutation;
|
||||
}
|
||||
| {
|
||||
name: 'deleteWorkspaceMutation';
|
||||
variables: DeleteWorkspaceMutationVariables;
|
||||
response: DeleteWorkspaceMutation;
|
||||
}
|
||||
| {
|
||||
name: 'leaveWorkspaceMutation';
|
||||
variables: LeaveWorkspaceMutationVariables;
|
||||
response: LeaveWorkspaceMutation;
|
||||
}
|
||||
| {
|
||||
name: 'revokeMemberPermissionMutation';
|
||||
variables: RevokeMemberPermissionMutationVariables;
|
||||
response: RevokeMemberPermissionMutation;
|
||||
}
|
||||
| {
|
||||
name: 'revokePageMutation';
|
||||
variables: RevokePageMutationVariables;
|
||||
response: RevokePageMutation;
|
||||
}
|
||||
| {
|
||||
name: 'sendChangeEmailMutation';
|
||||
variables: SendChangeEmailMutationVariables;
|
||||
response: SendChangeEmailMutation;
|
||||
}
|
||||
| {
|
||||
name: 'sendChangePasswordEmailMutation';
|
||||
variables: SendChangePasswordEmailMutationVariables;
|
||||
response: SendChangePasswordEmailMutation;
|
||||
}
|
||||
| {
|
||||
name: 'sendSetPasswordEmailMutation';
|
||||
variables: SendSetPasswordEmailMutationVariables;
|
||||
response: SendSetPasswordEmailMutation;
|
||||
}
|
||||
| {
|
||||
name: 'setRevokePageMutation';
|
||||
variables: SetRevokePageMutationVariables;
|
||||
response: SetRevokePageMutation;
|
||||
}
|
||||
| {
|
||||
name: 'setSharePageMutation';
|
||||
variables: SetSharePageMutationVariables;
|
||||
response: SetSharePageMutation;
|
||||
}
|
||||
| {
|
||||
name: 'setWorkspacePublicByIdMutation';
|
||||
variables: SetWorkspacePublicByIdMutationVariables;
|
||||
response: SetWorkspacePublicByIdMutation;
|
||||
}
|
||||
| {
|
||||
name: 'sharePageMutation';
|
||||
variables: SharePageMutationVariables;
|
||||
response: SharePageMutation;
|
||||
}
|
||||
| {
|
||||
name: 'signInMutation';
|
||||
variables: SignInMutationVariables;
|
||||
response: SignInMutation;
|
||||
}
|
||||
| {
|
||||
name: 'signUpMutation';
|
||||
variables: SignUpMutationVariables;
|
||||
response: SignUpMutation;
|
||||
}
|
||||
| {
|
||||
name: 'uploadAvatarMutation';
|
||||
variables: UploadAvatarMutationVariables;
|
||||
response: UploadAvatarMutation;
|
||||
}
|
||||
| {
|
||||
name: 'inviteByEmailMutation';
|
||||
variables: InviteByEmailMutationVariables;
|
||||
response: InviteByEmailMutation;
|
||||
}
|
||||
| {
|
||||
name: 'acceptInviteByInviteIdMutation';
|
||||
variables: AcceptInviteByInviteIdMutationVariables;
|
||||
response: AcceptInviteByInviteIdMutation;
|
||||
}
|
||||
| {
|
||||
name: 'acceptInviteByWorkspaceIdMutation';
|
||||
variables: AcceptInviteByWorkspaceIdMutationVariables;
|
||||
response: AcceptInviteByWorkspaceIdMutation;
|
||||
};
|
||||
|
||||
174
packages/graphql/src/utils.ts
Normal file
174
packages/graphql/src/utils.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
export const SPAN_ID_BYTES = 8;
|
||||
export const TRACE_ID_BYTES = 16;
|
||||
export const TRACE_VERSION = '00';
|
||||
export const TRACE_FLAG = '01';
|
||||
|
||||
const BytesBuffer = Array(32);
|
||||
|
||||
type TraceSpan = {
|
||||
name: string;
|
||||
spanId: string;
|
||||
displayName: {
|
||||
value: string;
|
||||
truncatedByteCount: number;
|
||||
};
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
attributes: {
|
||||
attributeMap: {
|
||||
requestId: {
|
||||
stringValue: {
|
||||
value: string;
|
||||
truncatedByteCount: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
droppedAttributesCount: number;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* inspired by open-telemetry/opentelemetry-js
|
||||
*/
|
||||
export function generateRandUTF16Chars(bytes: number) {
|
||||
for (let i = 0; i < bytes * 2; i++) {
|
||||
BytesBuffer[i] = Math.floor(Math.random() * 16) + 48;
|
||||
// valid hex characters in the range 48-57 and 97-102
|
||||
if (BytesBuffer[i] >= 58) {
|
||||
BytesBuffer[i] += 39;
|
||||
}
|
||||
}
|
||||
|
||||
return String.fromCharCode(...BytesBuffer.slice(0, bytes * 2));
|
||||
}
|
||||
|
||||
export class TraceReporter {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
static traceReportEndpoint = process.env.TRACE_REPORT_ENDPOINT!;
|
||||
static shouldReportTrace = process.env.SHOULD_REPORT_TRACE;
|
||||
|
||||
private spansCache = new Array<TraceSpan>();
|
||||
private reportIntervalId: number | undefined | NodeJS.Timeout;
|
||||
private reportInterval = 60_000;
|
||||
|
||||
private static instance: TraceReporter;
|
||||
|
||||
public static getInstance(): TraceReporter {
|
||||
if (!TraceReporter.instance) {
|
||||
const instance = (TraceReporter.instance = new TraceReporter());
|
||||
instance.initTraceReport();
|
||||
}
|
||||
|
||||
return TraceReporter.instance;
|
||||
}
|
||||
|
||||
public cacheTrace(
|
||||
traceId: string,
|
||||
spanId: string,
|
||||
requestId: string,
|
||||
startTime: string
|
||||
) {
|
||||
const span = TraceReporter.createTraceSpan(
|
||||
traceId,
|
||||
spanId,
|
||||
requestId,
|
||||
startTime
|
||||
);
|
||||
this.spansCache.push(span);
|
||||
if (this.spansCache.length <= 1) {
|
||||
this.initTraceReport();
|
||||
}
|
||||
}
|
||||
|
||||
public uploadTrace(
|
||||
traceId: string,
|
||||
spanId: string,
|
||||
requestId: string,
|
||||
startTime: string
|
||||
) {
|
||||
const span = TraceReporter.createTraceSpan(
|
||||
traceId,
|
||||
spanId,
|
||||
requestId,
|
||||
startTime
|
||||
);
|
||||
TraceReporter.reportToTraceEndpoint(JSON.stringify({ spans: [span] }));
|
||||
}
|
||||
|
||||
public static reportToTraceEndpoint(payload: string): void {
|
||||
if (typeof navigator !== 'undefined') {
|
||||
navigator.sendBeacon(TraceReporter.traceReportEndpoint, payload);
|
||||
} else {
|
||||
fetch(TraceReporter.traceReportEndpoint, {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: payload,
|
||||
}).catch(console.warn);
|
||||
}
|
||||
}
|
||||
|
||||
public static createTraceSpan(
|
||||
traceId: string,
|
||||
spanId: string,
|
||||
requestId: string,
|
||||
startTime: string
|
||||
): TraceSpan {
|
||||
return {
|
||||
name: `projects/{GCP_PROJECT_ID}/traces/${traceId}/spans/${spanId}`,
|
||||
spanId,
|
||||
displayName: {
|
||||
value: 'fetch',
|
||||
truncatedByteCount: 0,
|
||||
},
|
||||
startTime,
|
||||
endTime: new Date().toISOString(),
|
||||
attributes: {
|
||||
attributeMap: {
|
||||
requestId: {
|
||||
stringValue: {
|
||||
value: requestId,
|
||||
truncatedByteCount: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
droppedAttributesCount: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private initTraceReport = () => {
|
||||
if (!this.reportIntervalId && TraceReporter.shouldReportTrace) {
|
||||
if (typeof window !== 'undefined') {
|
||||
this.reportIntervalId = window.setInterval(
|
||||
this.reportHandler,
|
||||
this.reportInterval
|
||||
);
|
||||
} else {
|
||||
this.reportIntervalId = setInterval(
|
||||
this.reportHandler,
|
||||
this.reportInterval
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private reportHandler = () => {
|
||||
if (this.spansCache.length <= 0) {
|
||||
clearInterval(this.reportIntervalId);
|
||||
this.reportIntervalId = undefined;
|
||||
return;
|
||||
}
|
||||
TraceReporter.reportToTraceEndpoint(
|
||||
JSON.stringify({ spans: [...this.spansCache] })
|
||||
);
|
||||
this.spansCache = [];
|
||||
};
|
||||
}
|
||||
|
||||
export const traceReporter = !process.env.SHOULD_REPORT_TRACE
|
||||
? null
|
||||
: TraceReporter.getInstance();
|
||||
Reference in New Issue
Block a user