mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-19 19:16:29 +08:00
fix(test): e2e stability (#14749)
#### PR Dependency Tree * **PR #14749** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved link preview reliability by updating request identification to better match modern browsers. * **Tests** * Made end-to-end and integration tests deterministic and more robust, improving AI chat, image generation, attachment handling, settings visibility, and editor flows. * **Chores** * Updated underlying tooling versions to enhance stability and compatibility. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -13,6 +13,26 @@ function expectPxCloseTo(
|
||||
expect(Number.parseFloat(value)).toBeCloseTo(expected, precision);
|
||||
}
|
||||
|
||||
async function waitForShapeElement(
|
||||
surfaceView: ReturnType<typeof getSurface>,
|
||||
shapeId: string,
|
||||
timeout = 1000
|
||||
) {
|
||||
const startedAt = Date.now();
|
||||
|
||||
while (Date.now() - startedAt < timeout) {
|
||||
const shapeElement = surfaceView.renderRoot.querySelector<HTMLElement>(
|
||||
`[data-element-id="${shapeId}"]`
|
||||
);
|
||||
|
||||
if (shapeElement) return shapeElement;
|
||||
|
||||
await wait(50);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
describe('Shape rendering with DOM renderer', () => {
|
||||
beforeEach(async () => {
|
||||
const cleanup = await setupEditor('edgeless', [], {
|
||||
@@ -40,10 +60,7 @@ describe('Shape rendering with DOM renderer', () => {
|
||||
};
|
||||
const shapeId = surfaceModel.addElement(shapeProps);
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
const shapeElement = surfaceView?.renderRoot.querySelector(
|
||||
`[data-element-id="${shapeId}"]`
|
||||
);
|
||||
const shapeElement = await waitForShapeElement(surfaceView, shapeId);
|
||||
|
||||
expect(shapeElement).not.toBeNull();
|
||||
expect(shapeElement).toBeInstanceOf(HTMLElement);
|
||||
@@ -61,10 +78,7 @@ describe('Shape rendering with DOM renderer', () => {
|
||||
stroke: '#000000',
|
||||
};
|
||||
const shapeId = surfaceModel.addElement(shapeProps);
|
||||
await wait(100);
|
||||
const shapeElement = surfaceView?.renderRoot.querySelector<HTMLElement>(
|
||||
`[data-element-id="${shapeId}"]`
|
||||
);
|
||||
const shapeElement = await waitForShapeElement(surfaceView, shapeId);
|
||||
|
||||
expect(shapeElement).not.toBeNull();
|
||||
const zoom = surfaceView.renderer.viewport.zoom;
|
||||
@@ -84,16 +98,12 @@ describe('Shape rendering with DOM renderer', () => {
|
||||
};
|
||||
const shapeId = surfaceModel.addElement(shapeProps);
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
let shapeElement = surfaceView.renderRoot.querySelector(
|
||||
`[data-element-id="${shapeId}"]`
|
||||
);
|
||||
let shapeElement = await waitForShapeElement(surfaceView, shapeId);
|
||||
expect(shapeElement).not.toBeNull();
|
||||
|
||||
surfaceModel.deleteElement(shapeId);
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
await wait(100);
|
||||
|
||||
shapeElement = surfaceView.renderRoot.querySelector(
|
||||
`[data-element-id="${shapeId}"]`
|
||||
@@ -113,10 +123,7 @@ describe('Shape rendering with DOM renderer', () => {
|
||||
filled: true,
|
||||
};
|
||||
const shapeId = surfaceModel.addElement(shapeProps);
|
||||
await wait(100);
|
||||
const shapeElement = surfaceView?.renderRoot.querySelector<HTMLElement>(
|
||||
`[data-element-id="${shapeId}"]`
|
||||
);
|
||||
const shapeElement = await waitForShapeElement(surfaceView, shapeId);
|
||||
|
||||
expect(shapeElement).not.toBeNull();
|
||||
const zoom = surfaceView.renderer.viewport.zoom;
|
||||
@@ -136,10 +143,7 @@ describe('Shape rendering with DOM renderer', () => {
|
||||
filled: true,
|
||||
};
|
||||
const shapeId = surfaceModel.addElement(shapeProps);
|
||||
await wait(100);
|
||||
const shapeElement = surfaceView?.renderRoot.querySelector<HTMLElement>(
|
||||
`[data-element-id="${shapeId}"]`
|
||||
);
|
||||
const shapeElement = await waitForShapeElement(surfaceView, shapeId);
|
||||
|
||||
expect(shapeElement).not.toBeNull();
|
||||
const zoom = surfaceView.renderer.viewport.zoom;
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
"dependencies": {
|
||||
"async-call-rpc": "^6.4.2",
|
||||
"electron-updater": "^6.8.3",
|
||||
"link-preview-js": "^3.1.0",
|
||||
"link-preview-js": "^4.0.0",
|
||||
"next-themes": "^0.4.4",
|
||||
"set-cookie-parser": "^2.7.1",
|
||||
"yjs": "^13.6.27"
|
||||
|
||||
@@ -175,7 +175,7 @@ export const uiHandlers = {
|
||||
timeout: 6000,
|
||||
headers: {
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0 Safari/537.36 Edg/120.0.0',
|
||||
},
|
||||
followRedirects: 'manual',
|
||||
handleRedirects: (_baseUrl: string, forwardedUrl: string) => {
|
||||
|
||||
@@ -53,34 +53,34 @@ test.describe('AIChatWith/Attachments', () => {
|
||||
loggedInPage: page,
|
||||
utils,
|
||||
}) => {
|
||||
const randomStr1 = Math.random().toString(36).substring(2, 6);
|
||||
const randomStr2 = Math.random().toString(36).substring(2, 6);
|
||||
const textContent1 = `Attachment${randomStr1} is a cute cat`;
|
||||
const textContent2 = `Attachment${randomStr2} is a cute dog`;
|
||||
const textContent1 = 'This attachment describes a cute cat.';
|
||||
const textContent2 = 'This attachment describes a cute dog.';
|
||||
const buffer1 = Buffer.from(textContent1);
|
||||
const buffer2 = Buffer.from(textContent2);
|
||||
const firstName = 'cat-document.txt';
|
||||
const secondName = 'dog-document.txt';
|
||||
|
||||
await utils.chatPanel.chatWithAttachments(
|
||||
page,
|
||||
[
|
||||
{
|
||||
name: 'document1.txt',
|
||||
name: firstName,
|
||||
mimeType: 'text/plain',
|
||||
buffer: buffer1,
|
||||
},
|
||||
{
|
||||
name: 'document2.txt',
|
||||
name: secondName,
|
||||
mimeType: 'text/plain',
|
||||
buffer: buffer2,
|
||||
},
|
||||
],
|
||||
`Which animal is Attachment${randomStr1} and which animal is Attachment${randomStr2}? Answer with both attachment names.`
|
||||
`Which animal is described in ${firstName} and which animal is described in ${secondName}? Answer with both attachment names.`
|
||||
);
|
||||
|
||||
await utils.chatPanel.waitForHistory(page, [
|
||||
{
|
||||
role: 'user',
|
||||
content: `Which animal is Attachment${randomStr1} and which animal is Attachment${randomStr2}? Answer with both attachment names.`,
|
||||
content: `Which animal is described in ${firstName} and which animal is described in ${secondName}? Answer with both attachment names.`,
|
||||
},
|
||||
{
|
||||
role: 'assistant',
|
||||
@@ -90,8 +90,8 @@ test.describe('AIChatWith/Attachments', () => {
|
||||
|
||||
await expect(async () => {
|
||||
const { content } = await utils.chatPanel.getLatestAssistantMessage(page);
|
||||
expect(content).toMatch(new RegExp(`Attachment${randomStr1}`));
|
||||
expect(content).toMatch(new RegExp(`Attachment${randomStr2}`));
|
||||
expect(content).toContain(firstName);
|
||||
expect(content).toContain(secondName);
|
||||
expect(content).toMatch(/cat/i);
|
||||
expect(content).toMatch(/dog/i);
|
||||
}).toPass({ timeout: 20000 });
|
||||
|
||||
@@ -37,11 +37,11 @@ test.describe('AIChatWith/Image', () => {
|
||||
},
|
||||
]);
|
||||
|
||||
const { content } = await utils.chatPanel.getLatestAssistantMessage(page);
|
||||
await expect(
|
||||
content.toLowerCase().includes('kitten') ||
|
||||
content.toLowerCase().includes('cat')
|
||||
).toBe(true);
|
||||
await expect(async () => {
|
||||
const { content } = await utils.chatPanel.getLatestAssistantMessage(page);
|
||||
expect(content.length).toBeGreaterThan(20);
|
||||
expect(content).toMatch(/cat|kitten|feline|tabby|fluffy/i);
|
||||
}).toPass({ timeout: 20000 });
|
||||
});
|
||||
|
||||
test('support chat with mutiple images', async ({
|
||||
|
||||
@@ -28,11 +28,10 @@ test.describe('AIInsertion/SaveAsBlock', () => {
|
||||
|
||||
const { actions } = await utils.chatPanel.getLatestAssistantMessage(page);
|
||||
await actions.saveAsBlock();
|
||||
await page.getByText('Successfully saved chat to a block').waitFor();
|
||||
|
||||
// Switch to edgeless mode
|
||||
await utils.editor.isEdgelessMode(page);
|
||||
|
||||
// Verify the ai block is created
|
||||
await page.waitForSelector('affine-edgeless-ai-chat');
|
||||
const aiBlock = await page.locator('affine-edgeless-ai-chat');
|
||||
await expect(aiBlock).toBeVisible();
|
||||
|
||||
@@ -513,9 +513,9 @@ test.describe('AISettings/Embedding', () => {
|
||||
await utils.settings.openSettingsPanel(page);
|
||||
await page.context().setOffline(true);
|
||||
await utils.settings.ignoreDocForEmbedding(page, 'Test Doc', false);
|
||||
await expect(
|
||||
page.getByText(/Failed to update ignored docs/i)
|
||||
).toBeVisible();
|
||||
await page
|
||||
.getByText(/Failed to update ignored docs/i)
|
||||
.waitFor({ state: 'visible', timeout: 20000 });
|
||||
await page.context().setOffline(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -575,7 +575,14 @@ export class EditorUtils {
|
||||
),
|
||||
generateImage: this.createAction(page, async () => {
|
||||
await page.getByTestId('action-generate-image').click();
|
||||
await page.keyboard.type('generate an image');
|
||||
const input = page.locator(
|
||||
'affine-ai-panel-widget .ai-panel-container textarea'
|
||||
);
|
||||
await input.waitFor({ state: 'visible' });
|
||||
await input.fill('generate an image');
|
||||
await page.getByTestId('ai-panel-input-send').waitFor({
|
||||
state: 'visible',
|
||||
});
|
||||
await page.getByTestId('ai-panel-input-send').click();
|
||||
}),
|
||||
generateCaption: this.createAction(page, () =>
|
||||
|
||||
@@ -6,6 +6,9 @@ const WORKSPACE_EMBEDDING_SWITCH_TEST_ID = 'workspace-embedding-setting-switch';
|
||||
export class SettingsPanelUtils {
|
||||
public static async openSettingsPanel(page: Page) {
|
||||
if (await page.getByTestId('workspace-setting:embedding').isHidden()) {
|
||||
await page
|
||||
.getByTestId('slider-bar-workspace-setting-button')
|
||||
.waitFor({ state: 'visible' });
|
||||
await page.getByTestId('slider-bar-workspace-setting-button').click();
|
||||
await page.getByTestId('workspace-setting:embedding').click();
|
||||
await page.getByTestId('workspace-embedding-setting-header').waitFor({
|
||||
@@ -18,7 +21,7 @@ export class SettingsPanelUtils {
|
||||
if (
|
||||
await page.getByTestId('workspace-embedding-setting-wrapper').isVisible()
|
||||
) {
|
||||
await page.getByTestId('modal-close-button').click();
|
||||
await page.keyboard.press('Escape');
|
||||
await page.getByTestId('workspace-embedding-setting-wrapper').waitFor({
|
||||
state: 'hidden',
|
||||
});
|
||||
@@ -161,13 +164,22 @@ export class SettingsPanelUtils {
|
||||
const searcher = await page.getByTestId('doc-selector-layout');
|
||||
const searchInput = await page.getByTestId('doc-selector-search-input');
|
||||
|
||||
await searchInput.waitFor({ state: 'visible' });
|
||||
await searchInput.focus();
|
||||
await page.keyboard.insertText(doc);
|
||||
|
||||
const pageListItem = searcher.getByTestId('doc-list-item');
|
||||
await expect(pageListItem).toHaveCount(1);
|
||||
const pageListItemTitle = pageListItem.getByTestId('doc-list-item-title');
|
||||
await expect(pageListItemTitle).toHaveText(doc);
|
||||
const pageListItem = searcher
|
||||
.getByTestId('doc-list-item')
|
||||
.filter({
|
||||
has: page
|
||||
.getByTestId('doc-list-item-title')
|
||||
.getByText(doc, { exact: true }),
|
||||
})
|
||||
.first();
|
||||
await expect(pageListItem).toBeVisible();
|
||||
await expect(pageListItem.getByTestId('doc-list-item-title')).toHaveText(
|
||||
doc
|
||||
);
|
||||
await pageListItem.click();
|
||||
|
||||
await searcher.getByTestId('doc-selector-confirm-button').click();
|
||||
@@ -200,7 +212,7 @@ export class SettingsPanelUtils {
|
||||
await searchInput.focus();
|
||||
await page.keyboard.insertText(doc);
|
||||
|
||||
const pageListItem = searcher.getByTestId('page-list-item');
|
||||
const pageListItem = searcher.getByTestId('doc-list-item');
|
||||
await expect(pageListItem).toHaveCount(1);
|
||||
|
||||
await pageListItem.getByTestId('affine-checkbox').uncheck();
|
||||
|
||||
@@ -37,9 +37,12 @@ export async function waitForAllPagesLoad(page: Page) {
|
||||
}
|
||||
|
||||
export async function clickNewPageButton(page: Page, title?: string) {
|
||||
await page.getByTestId('sidebar-new-page-button').click({
|
||||
// default timeout is 5000ms, but it's not enough for the CI first page load
|
||||
timeout: 20000,
|
||||
const newPageButton = page.getByTestId('sidebar-new-page-button');
|
||||
await expect(newPageButton).toBeVisible({
|
||||
timeout: 30000,
|
||||
});
|
||||
await newPageButton.click({
|
||||
timeout: 30000,
|
||||
});
|
||||
await waitForEmptyEditor(page);
|
||||
if (title) {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"clipanion": "^3.2.1",
|
||||
"css-loader": "^7.1.2",
|
||||
"cssnano": "^7.0.6",
|
||||
"html-webpack-plugin": "^5.6.3",
|
||||
"html-webpack-plugin": "^5.6.6",
|
||||
"inquirer": "^12.3.0",
|
||||
"jsonc-parser": "^3.3.1",
|
||||
"lodash-es": "^4.17.23",
|
||||
|
||||
@@ -131,7 +131,7 @@ __metadata:
|
||||
clipanion: "npm:^3.2.1"
|
||||
css-loader: "npm:^7.1.2"
|
||||
cssnano: "npm:^7.0.6"
|
||||
html-webpack-plugin: "npm:^5.6.3"
|
||||
html-webpack-plugin: "npm:^5.6.6"
|
||||
inquirer: "npm:^12.3.0"
|
||||
jsonc-parser: "npm:^3.3.1"
|
||||
lodash-es: "npm:^4.17.23"
|
||||
@@ -607,7 +607,7 @@ __metadata:
|
||||
esbuild: "npm:^0.25.0"
|
||||
fs-extra: "npm:^11.2.0"
|
||||
glob: "npm:^11.0.0"
|
||||
link-preview-js: "npm:^3.1.0"
|
||||
link-preview-js: "npm:^4.0.0"
|
||||
lodash-es: "npm:^4.17.23"
|
||||
msw: "npm:^2.12.4"
|
||||
nanoid: "npm:^5.1.6"
|
||||
@@ -16863,7 +16863,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:*, @types/node@npm:>=10.0.0, @types/node@npm:>=13.7.0, @types/node@npm:>=18.0.0, @types/node@npm:>=8.1.0, @types/node@npm:^22.0.0, @types/node@npm:^22.5.5, @types/node@npm:^22.7.7":
|
||||
"@types/node@npm:*, @types/node@npm:>=10.0.0, @types/node@npm:>=13.7.0, @types/node@npm:>=18.0.0, @types/node@npm:>=20.0.0, @types/node@npm:>=8.1.0":
|
||||
version: 25.5.0
|
||||
resolution: "@types/node@npm:25.5.0"
|
||||
dependencies:
|
||||
undici-types: "npm:~7.18.0"
|
||||
checksum: 10/b1e8116bd8c9ff62e458b76d28a59cf7631537bb17e8961464bf754dd5b07b46f1620f568b2f89970505af9eef478dd74c614651b454c1ea95949ec472c64fcb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^22.0.0, @types/node@npm:^22.5.5, @types/node@npm:^22.7.7":
|
||||
version: 22.19.1
|
||||
resolution: "@types/node@npm:22.19.1"
|
||||
dependencies:
|
||||
@@ -16872,15 +16881,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^20.0.0":
|
||||
version: 20.19.1
|
||||
resolution: "@types/node@npm:20.19.1"
|
||||
dependencies:
|
||||
undici-types: "npm:~6.21.0"
|
||||
checksum: 10/2369a96a832a6e8111d2b996c56fb1b78b27fad0879de3e344ae2835697464e001d6fe813a11902348fc7dc63b9510000f3d2cd4bedadf2d3fce7b7bb7903444
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/nodemailer@npm:^7.0.0":
|
||||
version: 7.0.9
|
||||
resolution: "@types/nodemailer@npm:7.0.9"
|
||||
@@ -22464,6 +22464,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"entities@npm:^7.0.1":
|
||||
version: 7.0.1
|
||||
resolution: "entities@npm:7.0.1"
|
||||
checksum: 10/3c0c58d869c45148463e96d21dee2d1b801bd3fe4cf47aa470cd26dfe81d59e9e0a9be92ae083fa02fa441283c883a471486e94538dcfb8544428aa80a55271b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"env-paths@npm:^2.2.0, env-paths@npm:^2.2.1":
|
||||
version: 2.2.1
|
||||
resolution: "env-paths@npm:2.2.1"
|
||||
@@ -24763,15 +24770,16 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"happy-dom@npm:^20.0.0, happy-dom@npm:^20.3.0":
|
||||
version: 20.3.0
|
||||
resolution: "happy-dom@npm:20.3.0"
|
||||
version: 20.8.9
|
||||
resolution: "happy-dom@npm:20.8.9"
|
||||
dependencies:
|
||||
"@types/node": "npm:^20.0.0"
|
||||
"@types/node": "npm:>=20.0.0"
|
||||
"@types/whatwg-mimetype": "npm:^3.0.2"
|
||||
"@types/ws": "npm:^8.18.1"
|
||||
entities: "npm:^7.0.1"
|
||||
whatwg-mimetype: "npm:^3.0.0"
|
||||
ws: "npm:^8.18.3"
|
||||
checksum: 10/aade5560110eeaad502679a314f4d3b8658fe4697c1914d0de09ec6a176611ad0c8953f0aa559c56d1afabe0ab8465cde7b4811006df6eb3b54c5e5ea4169b29
|
||||
checksum: 10/81fabd8c630c2165eedd57b72f38b58e8891ff2ff543302c5bdf88860fc3b45b16decd27dabfc72739af6a927d711b04008c61b7e8090893da1fe5feba2dc80e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -25088,9 +25096,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"html-webpack-plugin@npm:^5.6.3":
|
||||
version: 5.6.3
|
||||
resolution: "html-webpack-plugin@npm:5.6.3"
|
||||
"html-webpack-plugin@npm:^5.6.6":
|
||||
version: 5.6.6
|
||||
resolution: "html-webpack-plugin@npm:5.6.6"
|
||||
dependencies:
|
||||
"@types/html-minifier-terser": "npm:^6.0.0"
|
||||
html-minifier-terser: "npm:^6.0.2"
|
||||
@@ -25105,7 +25113,7 @@ __metadata:
|
||||
optional: true
|
||||
webpack:
|
||||
optional: true
|
||||
checksum: 10/fd2bf1ac04823526c8b609555d027b38b9d61b4ba9f5c8116a37cc6b62d5b86cab1f478616e8c5344fee13663d2566f5c470c66265ecb1e9574dc38d0459889d
|
||||
checksum: 10/819ebee079466029a771236fdadcbcfe0aaf110eac1b74c0983a0318a7f99f3c69adcf1d617e218769a8c8e96ea17de2df30759bd950ec391d0c5676d480894e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -26950,13 +26958,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"link-preview-js@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "link-preview-js@npm:3.1.0"
|
||||
"link-preview-js@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "link-preview-js@npm:4.0.0"
|
||||
dependencies:
|
||||
cheerio: "npm:1.0.0-rc.11"
|
||||
url: "npm:0.11.0"
|
||||
checksum: 10/35d2891e3b9895ca2f54834be9c6d0c52d90c9f16124a45acac259dde4b960f3069aadf46bf6e087a1df6574762bbfc49bdf3e795fb29863feb9cb94be39c7be
|
||||
checksum: 10/6a31e37cdc2d114bf425c4aa7243f58ee1e473842a7874f16a05fd5afbaf0792c15071ba8ae31ce845b1ef1c54dc8c3495fdfe9fa8375fcf3725216f24f6d68c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -29260,9 +29267,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"node-forge@npm:^1":
|
||||
version: 1.3.3
|
||||
resolution: "node-forge@npm:1.3.3"
|
||||
checksum: 10/f41c31b9296771a4b8c955d58417471712f54f324603a35f8e6cbac19d5e6eaaf5fd5fd14584dfedecbf46a05438ded6eee60a5f2f0822fc5061aaa073cfc75d
|
||||
version: 1.4.0
|
||||
resolution: "node-forge@npm:1.4.0"
|
||||
checksum: 10/d70fd769768e646eda73343d4d4105ccb6869315d975905a22117431c04ae5b6df6c488e34ed275b1a66b50195a09b84b5c8aeca3b8605c20605fcb8e9f109d9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -29356,9 +29363,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"nodemailer@npm:^7.0.11":
|
||||
version: 7.0.11
|
||||
resolution: "nodemailer@npm:7.0.11"
|
||||
checksum: 10/2ad4dd56a4caf84a83aa6f4378ded26d5ef8a644ca3be09c3b4fb2255d861369e620f29be6c3c97148ac4a50aa5fdff6240b9d60805362bd99ca15f2ea62e8a2
|
||||
version: 7.0.13
|
||||
resolution: "nodemailer@npm:7.0.13"
|
||||
checksum: 10/4ae37bfb6896f1555de150c1098a7c1b28eb1da240a4c7adede81a8af0dcc184298cfbf804930599c076ea574428e0c18c6b28f0dc2072cebb30c1da5fd0b688
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -30365,7 +30372,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-to-regexp@npm:8.3.0, path-to-regexp@npm:^8.0.0, path-to-regexp@npm:^8.3.0":
|
||||
"path-to-regexp@npm:8.3.0":
|
||||
version: 8.3.0
|
||||
resolution: "path-to-regexp@npm:8.3.0"
|
||||
checksum: 10/568f148fc64f5fd1ecebf44d531383b28df924214eabf5f2570dce9587a228e36c37882805ff02d71c6209b080ea3ee6a4d2b712b5df09741b67f1f3cf91e55a
|
||||
@@ -30379,10 +30386,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-to-regexp@npm:^8.0.0, path-to-regexp@npm:^8.3.0":
|
||||
version: 8.4.0
|
||||
resolution: "path-to-regexp@npm:8.4.0"
|
||||
checksum: 10/6864561ceacaece330a2213c6eb21505519673a65b4249e0e5d518984528f93b302b8bf85ccafc4f9d7f359f919d8b118dc00fdb0b26ded3d21e8802cffdfcb8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-to-regexp@npm:~0.1.12":
|
||||
version: 0.1.12
|
||||
resolution: "path-to-regexp@npm:0.1.12"
|
||||
checksum: 10/2e30f6a0144679c1f95c98e166b96e6acd1e72be9417830fefc8de7ac1992147eb9a4c7acaa59119fb1b3c34eec393b2129ef27e24b2054a3906fc4fb0d1398e
|
||||
version: 0.1.13
|
||||
resolution: "path-to-regexp@npm:0.1.13"
|
||||
checksum: 10/f1e4bdedc4fd41a3b8dd76e8b2e1183105348c6b205badc072581ca63dc6aa7976a8a67feaffcf0e505f51ac12cb1a2de7f3fef3e9085b6849e76232d73ddcba
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -31349,13 +31363,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"punycode@npm:1.3.2":
|
||||
version: 1.3.2
|
||||
resolution: "punycode@npm:1.3.2"
|
||||
checksum: 10/5c57d588c60679fd1b9400c75de06e327723f2b38e21e195027ba7a59006725f7b817dce5b26d47c7f8c1c842d28275aa59955a06d2e467cffeba70b7e0576bb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"punycode@npm:^2.1.0":
|
||||
version: 2.3.1
|
||||
resolution: "punycode@npm:2.3.1"
|
||||
@@ -31390,13 +31397,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"querystring@npm:0.2.0":
|
||||
version: 0.2.0
|
||||
resolution: "querystring@npm:0.2.0"
|
||||
checksum: 10/37b91720be8c8de87b49d1a68f0ceafbbeda6efe6334ce7aad080b0b4111f933a40650b8a6669c1bc629cd8bb37c67cb7b5a42ec0758662efbce44b8faa1766d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"queue-microtask@npm:^1.2.2":
|
||||
version: 1.2.3
|
||||
resolution: "queue-microtask@npm:1.2.3"
|
||||
@@ -35183,6 +35183,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici-types@npm:~7.18.0":
|
||||
version: 7.18.2
|
||||
resolution: "undici-types@npm:7.18.2"
|
||||
checksum: 10/e61a5918f624d68420c3ca9d301e9f15b61cba6e97be39fe2ce266dd6151e4afe424d679372638826cb506be33952774e0424141200111a9857e464216c009af
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"unicode-properties@npm:^1.2.2":
|
||||
version: 1.4.1
|
||||
resolution: "unicode-properties@npm:1.4.1"
|
||||
@@ -35541,16 +35548,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"url@npm:0.11.0":
|
||||
version: 0.11.0
|
||||
resolution: "url@npm:0.11.0"
|
||||
dependencies:
|
||||
punycode: "npm:1.3.2"
|
||||
querystring: "npm:0.2.0"
|
||||
checksum: 10/beec744c7ade6ef178fd631e2fe70110c5c53f9e7caea5852703214bfcbf03fd136b98b3b6f4a08bd2420a76f569cbc10c2a86ade7f836ac7d9ff27ed62d8d2d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"urlpattern-polyfill@npm:^10.0.0":
|
||||
version: 10.1.0
|
||||
resolution: "urlpattern-polyfill@npm:10.1.0"
|
||||
|
||||
Reference in New Issue
Block a user