feat(server): send mention email (#10859)

close CLOUD-170
This commit is contained in:
fengmk2
2025-03-20 09:26:42 +00:00
parent 5ea65b1709
commit 42745f059d
13 changed files with 323 additions and 7 deletions

View File

@@ -1,6 +1,7 @@
import test from 'ava';
import { DocID, DocVariant } from '../doc';
import { DocMode } from '../../../models';
import { DocID, DocVariant, generateDocPath } from '../doc';
test('can parse', t => {
// workspace only
@@ -80,3 +81,45 @@ test('special case: `wsId:space:page:pageId`', t => {
t.throws(() => new DocID('ws:space:b:page'));
t.throws(() => new DocID('ws:s:page:page'));
});
test('should generate doc path', t => {
t.is(
generateDocPath({
workspaceId: 'ws',
docId: 'doc',
mode: DocMode.page,
}),
'/workspace/ws/doc?mode=page'
);
t.is(
generateDocPath({
workspaceId: 'ws',
docId: 'doc',
mode: DocMode.page,
blockId: 'block',
}),
'/workspace/ws/doc?mode=page&blockIds=block'
);
t.is(
generateDocPath({
workspaceId: 'ws',
docId: 'doc',
mode: DocMode.page,
elementId: 'element.+?aaa$!@#',
}),
'/workspace/ws/doc?mode=page&elementIds=element.%2B%3Faaa%24%21%40%23'
);
t.is(
generateDocPath({
workspaceId: 'ws',
docId: 'doc',
mode: DocMode.page,
blockId: 'block',
elementId: 'element',
}),
'/workspace/ws/doc?mode=page&elementIds=element&blockIds=block'
);
});

View File

@@ -1,5 +1,7 @@
import { registerEnumType } from '@nestjs/graphql';
import { DocMode } from '../../models';
export enum DocVariant {
Workspace = 'workspace',
Page = 'page',
@@ -33,7 +35,7 @@ export class DocID {
return this.variant === DocVariant.Workspace
? this.workspace
: // sub is always truthy when variant is not workspace
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// oxlint-disable-next-line @typescript-eslint/no-non-null-assertion
this.sub!;
}
@@ -119,3 +121,29 @@ export class DocID {
}
}
}
type DocPathParams = {
workspaceId: string;
docId: string;
mode: DocMode;
blockId?: string;
elementId?: string;
};
/**
* To generate a doc url path like
*
* /workspace/{workspaceId}/{docId}?mode={DocMode}&elementIds={elementId}&blockIds={blockId}
*/
export function generateDocPath(params: DocPathParams) {
const search = new URLSearchParams({
mode: params.mode,
});
if (params.elementId) {
search.set('elementIds', params.elementId);
}
if (params.blockId) {
search.set('blockIds', params.blockId);
}
return `/workspace/${params.workspaceId}/${params.docId}?${search.toString()}`;
}