mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-13 16:16:46 +08:00
feat: improve test & bundler (#14434)
#### PR Dependency Tree * **PR #14434** 👈 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 * **New Features** * Introduced rspack bundler as an alternative to webpack for optimized builds. * **Tests & Quality** * Added comprehensive editor semantic tests covering markdown, hotkeys, and slash-menu operations. * Expanded CI cross-browser testing to Chromium, Firefox, and WebKit; improved shape-rendering tests to account for zoom. * **Bug Fixes** * Corrected CSS overlay styling for development servers. * Fixed TypeScript typings for build tooling. * **Other** * Document duplication now produces consistent "(n)" suffixes. * French i18n completeness increased to 100%. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -210,18 +210,13 @@ jobs:
|
||||
e2e-blocksuite-cross-browser-test:
|
||||
name: E2E BlockSuite Cross Browser Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shard: [1]
|
||||
browser: ['chromium', 'firefox', 'webkit']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
playwright-platform: ${{ matrix.browser }}
|
||||
playwright-platform: 'chromium,firefox,webkit'
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
|
||||
@@ -229,18 +224,64 @@ jobs:
|
||||
run: yarn workspace @blocksuite/playground build
|
||||
|
||||
- name: Run playwright tests
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
run: yarn workspace @affine-test/blocksuite test "cross-platform/" --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||
run: |
|
||||
yarn workspace @blocksuite/integration-test test:unit
|
||||
yarn workspace @affine-test/blocksuite test "cross-platform/" --forbid-only
|
||||
|
||||
- name: Upload test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-results-e2e-bs-cross-browser-${{ matrix.browser }}-${{ matrix.shard }}
|
||||
name: test-results-e2e-bs-cross-browser
|
||||
path: ./test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
bundler-matrix:
|
||||
name: Bundler Matrix (${{ matrix.bundler }})
|
||||
runs-on: ubuntu-24.04-arm
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
bundler: [webpack, rspack]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: false
|
||||
electron-install: false
|
||||
full-cache: true
|
||||
|
||||
- name: Run frontend build matrix
|
||||
env:
|
||||
AFFINE_BUNDLER: ${{ matrix.bundler }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
packages=(
|
||||
"@affine/web"
|
||||
"@affine/mobile"
|
||||
"@affine/ios"
|
||||
"@affine/android"
|
||||
"@affine/admin"
|
||||
"@affine/electron-renderer"
|
||||
)
|
||||
summary="test-results-bundler-${AFFINE_BUNDLER}.txt"
|
||||
: > "$summary"
|
||||
for pkg in "${packages[@]}"; do
|
||||
start=$(date +%s)
|
||||
yarn affine "$pkg" build
|
||||
end=$(date +%s)
|
||||
echo "${pkg},$((end-start))" >> "$summary"
|
||||
done
|
||||
|
||||
- name: Upload bundler timing
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: test-results-bundler-${{ matrix.bundler }}
|
||||
path: ./test-results-bundler-${{ matrix.bundler }}.txt
|
||||
if-no-files-found: ignore
|
||||
|
||||
e2e-test:
|
||||
name: E2E Test
|
||||
runs-on: ubuntu-24.04-arm
|
||||
@@ -321,6 +362,7 @@ jobs:
|
||||
with:
|
||||
electron-install: true
|
||||
playwright-install: true
|
||||
playwright-platform: 'chromium,firefox,webkit'
|
||||
full-cache: true
|
||||
|
||||
- name: Download affine.linux-x64-gnu.node
|
||||
|
||||
@@ -5,6 +5,14 @@ import { wait } from '../utils/common.js';
|
||||
import { getSurface } from '../utils/edgeless.js';
|
||||
import { setupEditor } from '../utils/setup.js';
|
||||
|
||||
function expectPxCloseTo(
|
||||
value: string,
|
||||
expected: number,
|
||||
precision: number = 2
|
||||
) {
|
||||
expect(Number.parseFloat(value)).toBeCloseTo(expected, precision);
|
||||
}
|
||||
|
||||
describe('Shape rendering with DOM renderer', () => {
|
||||
beforeEach(async () => {
|
||||
const cleanup = await setupEditor('edgeless', [], {
|
||||
@@ -59,7 +67,8 @@ describe('Shape rendering with DOM renderer', () => {
|
||||
);
|
||||
|
||||
expect(shapeElement).not.toBeNull();
|
||||
expect(shapeElement?.style.borderRadius).toBe('6px');
|
||||
const zoom = surfaceView.renderer.viewport.zoom;
|
||||
expectPxCloseTo(shapeElement!.style.borderRadius, 6 * zoom);
|
||||
});
|
||||
|
||||
test('should remove shape DOM node when element is deleted', async () => {
|
||||
@@ -110,8 +119,9 @@ describe('Shape rendering with DOM renderer', () => {
|
||||
);
|
||||
|
||||
expect(shapeElement).not.toBeNull();
|
||||
expect(shapeElement?.style.width).toBe('80px');
|
||||
expect(shapeElement?.style.height).toBe('60px');
|
||||
const zoom = surfaceView.renderer.viewport.zoom;
|
||||
expectPxCloseTo(shapeElement!.style.width, 80 * zoom);
|
||||
expectPxCloseTo(shapeElement!.style.height, 60 * zoom);
|
||||
});
|
||||
|
||||
test('should correctly render triangle shape', async () => {
|
||||
@@ -132,7 +142,8 @@ describe('Shape rendering with DOM renderer', () => {
|
||||
);
|
||||
|
||||
expect(shapeElement).not.toBeNull();
|
||||
expect(shapeElement?.style.width).toBe('80px');
|
||||
expect(shapeElement?.style.height).toBe('60px');
|
||||
const zoom = surfaceView.renderer.viewport.zoom;
|
||||
expectPxCloseTo(shapeElement!.style.width, 80 * zoom);
|
||||
expectPxCloseTo(shapeElement!.style.height, 60 * zoom);
|
||||
});
|
||||
});
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 24 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,363 @@
|
||||
import { LinkExtension } from '@blocksuite/affine-inline-link';
|
||||
import { textKeymap } from '@blocksuite/affine-inline-preset';
|
||||
import type {
|
||||
ListBlockModel,
|
||||
ParagraphBlockModel,
|
||||
} from '@blocksuite/affine-model';
|
||||
import { insertContent } from '@blocksuite/affine-rich-text';
|
||||
import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts';
|
||||
import { createDefaultDoc } from '@blocksuite/affine-shared/utils';
|
||||
import { TextSelection } from '@blocksuite/std';
|
||||
import type { InlineMarkdownMatch } from '@blocksuite/std/inline';
|
||||
import { Text } from '@blocksuite/store';
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import { defaultSlashMenuConfig } from '../../../../affine/widgets/slash-menu/src/config.js';
|
||||
import type {
|
||||
SlashMenuActionItem,
|
||||
SlashMenuItem,
|
||||
} from '../../../../affine/widgets/slash-menu/src/types.js';
|
||||
import { wait } from '../utils/common.js';
|
||||
import { addNote } from '../utils/edgeless.js';
|
||||
import { setupEditor } from '../utils/setup.js';
|
||||
|
||||
type RichTextElement = HTMLElement & {
|
||||
inlineEditor: {
|
||||
getFormat: (range: {
|
||||
index: number;
|
||||
length: number;
|
||||
}) => Record<string, unknown>;
|
||||
getInlineRange: () => { index: number; length: number } | null;
|
||||
setInlineRange: (range: { index: number; length: number }) => void;
|
||||
yTextString: string;
|
||||
};
|
||||
markdownMatches: InlineMarkdownMatch[];
|
||||
undoManager: {
|
||||
stopCapturing: () => void;
|
||||
};
|
||||
};
|
||||
|
||||
function findSlashActionItem(
|
||||
items: SlashMenuItem[],
|
||||
name: string
|
||||
): SlashMenuActionItem {
|
||||
const item = items.find(entry => entry.name === name);
|
||||
if (!item || !('action' in item)) {
|
||||
throw new Error(`Cannot find slash-menu action: ${name}`);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
function getRichTextByBlockId(blockId: string): RichTextElement {
|
||||
const block = editor.host?.view.getBlock(blockId) as HTMLElement | null;
|
||||
if (!block) {
|
||||
throw new Error(`Cannot find block view: ${blockId}`);
|
||||
}
|
||||
const richText = block.querySelector('rich-text') as RichTextElement | null;
|
||||
if (!richText) {
|
||||
throw new Error(`Cannot find rich-text for block: ${blockId}`);
|
||||
}
|
||||
return richText;
|
||||
}
|
||||
|
||||
async function createParagraph(text = '') {
|
||||
const noteId = addNote(doc);
|
||||
const note = doc.getBlock(noteId)?.model;
|
||||
if (!note) {
|
||||
throw new Error('Cannot find note model');
|
||||
}
|
||||
const paragraph = note.children[0] as ParagraphBlockModel | undefined;
|
||||
if (!paragraph) {
|
||||
throw new Error('Cannot find paragraph model');
|
||||
}
|
||||
if (text) {
|
||||
doc.updateBlock(paragraph, {
|
||||
text: new Text(text),
|
||||
});
|
||||
}
|
||||
await wait();
|
||||
return {
|
||||
noteId,
|
||||
paragraphId: paragraph.id,
|
||||
};
|
||||
}
|
||||
|
||||
function setTextSelection(blockId: string, index: number, length: number) {
|
||||
const to = length
|
||||
? {
|
||||
blockId,
|
||||
index: index + length,
|
||||
length: 0,
|
||||
}
|
||||
: null;
|
||||
const selection = editor.host?.selection.create(TextSelection, {
|
||||
from: {
|
||||
blockId,
|
||||
index,
|
||||
length: 0,
|
||||
},
|
||||
to,
|
||||
});
|
||||
if (!selection) {
|
||||
throw new Error('Cannot create text selection');
|
||||
}
|
||||
editor.host?.selection.setGroup('note', [selection]);
|
||||
const richText = getRichTextByBlockId(blockId);
|
||||
richText.inlineEditor.setInlineRange({ index, length });
|
||||
}
|
||||
|
||||
async function triggerMarkdown(
|
||||
blockId: string,
|
||||
input: string,
|
||||
matcherName: string
|
||||
) {
|
||||
const model = doc.getBlock(blockId)?.model as ParagraphBlockModel | undefined;
|
||||
if (!model) {
|
||||
throw new Error(`Cannot find paragraph model: ${blockId}`);
|
||||
}
|
||||
doc.updateBlock(model, {
|
||||
text: new Text(input),
|
||||
});
|
||||
await wait();
|
||||
|
||||
const richText = getRichTextByBlockId(blockId);
|
||||
const matcher = richText.markdownMatches.find(
|
||||
item => item.name === matcherName
|
||||
);
|
||||
if (!matcher) {
|
||||
throw new Error(`Cannot find markdown matcher: ${matcherName}`);
|
||||
}
|
||||
const inlineRange = { index: input.length, length: 0 };
|
||||
setTextSelection(blockId, inlineRange.index, 0);
|
||||
|
||||
matcher.action({
|
||||
inlineEditor: richText.inlineEditor as any,
|
||||
prefixText: input,
|
||||
inlineRange,
|
||||
pattern: matcher.pattern,
|
||||
undoManager: richText.undoManager as any,
|
||||
});
|
||||
|
||||
await wait();
|
||||
}
|
||||
|
||||
function mockKeyboardContext() {
|
||||
const preventDefault = vi.fn();
|
||||
const ctx = {
|
||||
get(key: string) {
|
||||
if (key === 'keyboardState') {
|
||||
return { raw: { preventDefault } };
|
||||
}
|
||||
throw new Error(`Unexpected state key: ${key}`);
|
||||
},
|
||||
};
|
||||
return { ctx: ctx as any, preventDefault };
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
const cleanup = await setupEditor('page', [LinkExtension]);
|
||||
return cleanup;
|
||||
});
|
||||
|
||||
describe('markdown/list/paragraph/quote/code/link', () => {
|
||||
test('markdown list shortcut converts to todo list and keeps checked state', async () => {
|
||||
const { noteId, paragraphId } = await createParagraph();
|
||||
await triggerMarkdown(paragraphId, '[x] ', 'list');
|
||||
|
||||
const note = doc.getBlock(noteId)?.model;
|
||||
if (!note) {
|
||||
throw new Error('Cannot find note model');
|
||||
}
|
||||
const model = note.children[0] as ListBlockModel;
|
||||
expect(model.flavour).toBe('affine:list');
|
||||
expect(model.props.type).toBe('todo');
|
||||
expect(model.props.checked).toBe(true);
|
||||
});
|
||||
|
||||
test('markdown heading and quote shortcuts convert paragraph type', async () => {
|
||||
const { noteId: headingNoteId, paragraphId: headingParagraphId } =
|
||||
await createParagraph();
|
||||
await triggerMarkdown(headingParagraphId, '# ', 'heading');
|
||||
const headingNote = doc.getBlock(headingNoteId)?.model;
|
||||
if (!headingNote) {
|
||||
throw new Error('Cannot find heading note model');
|
||||
}
|
||||
const headingModel = headingNote.children[0] as ParagraphBlockModel;
|
||||
expect(headingModel.flavour).toBe('affine:paragraph');
|
||||
expect(headingModel.props.type).toBe('h1');
|
||||
|
||||
const { noteId: quoteNoteId, paragraphId: quoteParagraphId } =
|
||||
await createParagraph();
|
||||
await triggerMarkdown(quoteParagraphId, '> ', 'heading');
|
||||
const quoteNote = doc.getBlock(quoteNoteId)?.model;
|
||||
if (!quoteNote) {
|
||||
throw new Error('Cannot find quote note model');
|
||||
}
|
||||
const quoteModel = quoteNote.children[0] as ParagraphBlockModel;
|
||||
expect(quoteModel.flavour).toBe('affine:paragraph');
|
||||
expect(quoteModel.props.type).toBe('quote');
|
||||
});
|
||||
|
||||
test('markdown code shortcut converts paragraph to code block with language', async () => {
|
||||
const { noteId, paragraphId } = await createParagraph();
|
||||
await triggerMarkdown(paragraphId, '```ts ', 'code-block');
|
||||
|
||||
const note = doc.getBlock(noteId)?.model;
|
||||
if (!note) {
|
||||
throw new Error('Cannot find note model');
|
||||
}
|
||||
const model = note.children[0];
|
||||
expect(model.flavour).toBe('affine:code');
|
||||
expect((model as any).props.language).toBe('typescript');
|
||||
});
|
||||
|
||||
test('inline markdown converts style and link attributes', async () => {
|
||||
const { paragraphId: boldParagraphId } = await createParagraph();
|
||||
await triggerMarkdown(boldParagraphId, '**bold** ', 'bold');
|
||||
const boldRichText = getRichTextByBlockId(boldParagraphId);
|
||||
expect(boldRichText.inlineEditor.yTextString).toBe('bold');
|
||||
expect(
|
||||
boldRichText.inlineEditor.getFormat({ index: 1, length: 0 })
|
||||
).toMatchObject({
|
||||
bold: true,
|
||||
});
|
||||
|
||||
const { paragraphId: codeParagraphId } = await createParagraph();
|
||||
await triggerMarkdown(codeParagraphId, '`code` ', 'code');
|
||||
const codeRichText = getRichTextByBlockId(codeParagraphId);
|
||||
expect(codeRichText.inlineEditor.yTextString).toBe('code');
|
||||
expect(
|
||||
codeRichText.inlineEditor.getFormat({ index: 1, length: 0 })
|
||||
).toMatchObject({
|
||||
code: true,
|
||||
});
|
||||
|
||||
const { paragraphId: linkParagraphId } = await createParagraph();
|
||||
await triggerMarkdown(
|
||||
linkParagraphId,
|
||||
'[AFFiNE](https://affine.pro) ',
|
||||
'link'
|
||||
);
|
||||
const linkRichText = getRichTextByBlockId(linkParagraphId);
|
||||
expect(linkRichText.inlineEditor.yTextString).toBe('AFFiNE');
|
||||
expect(
|
||||
linkRichText.inlineEditor.getFormat({ index: 1, length: 0 })
|
||||
).toMatchObject({
|
||||
link: 'https://affine.pro',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('hotkey/bracket/linked-page', () => {
|
||||
test('bracket keymap skips redundant right bracket in code block', async () => {
|
||||
const { noteId, paragraphId } = await createParagraph();
|
||||
await triggerMarkdown(paragraphId, '```ts ', 'code-block');
|
||||
const note = doc.getBlock(noteId)?.model;
|
||||
const codeId = note?.children[0]?.id;
|
||||
if (!codeId) {
|
||||
throw new Error('Cannot find code block id');
|
||||
}
|
||||
const codeModel = doc.getBlock(codeId)?.model;
|
||||
if (!codeModel) {
|
||||
throw new Error('Cannot find code block model');
|
||||
}
|
||||
const keymap = textKeymap(editor.std);
|
||||
const leftHandler = keymap['('];
|
||||
const rightHandler = keymap[')'];
|
||||
expect(leftHandler).toBeDefined();
|
||||
if (!rightHandler) {
|
||||
throw new Error('Cannot find bracket key handlers');
|
||||
}
|
||||
|
||||
doc.updateBlock(codeModel, {
|
||||
text: new Text('()'),
|
||||
});
|
||||
await wait();
|
||||
const codeRichText = getRichTextByBlockId(codeId);
|
||||
setTextSelection(codeId, 1, 0);
|
||||
const rightContext = mockKeyboardContext();
|
||||
rightHandler(rightContext.ctx);
|
||||
expect(rightContext.preventDefault).not.toHaveBeenCalled();
|
||||
expect(codeRichText.inlineEditor.yTextString).toBe('()');
|
||||
});
|
||||
|
||||
test('consecutive linked-page reference nodes render as separate references', async () => {
|
||||
const { paragraphId } = await createParagraph();
|
||||
const paragraphModel = doc.getBlock(paragraphId)?.model as
|
||||
| ParagraphBlockModel
|
||||
| undefined;
|
||||
if (!paragraphModel) {
|
||||
throw new Error('Cannot find paragraph model');
|
||||
}
|
||||
const linkedDoc = createDefaultDoc(collection, {
|
||||
title: 'Linked page',
|
||||
});
|
||||
|
||||
setTextSelection(paragraphId, 0, 0);
|
||||
insertContent(editor.std, paragraphModel, REFERENCE_NODE, {
|
||||
reference: {
|
||||
type: 'LinkedPage',
|
||||
pageId: linkedDoc.id,
|
||||
},
|
||||
});
|
||||
insertContent(editor.std, paragraphModel, REFERENCE_NODE, {
|
||||
reference: {
|
||||
type: 'LinkedPage',
|
||||
pageId: linkedDoc.id,
|
||||
},
|
||||
});
|
||||
await wait();
|
||||
expect(collection.docs.has(linkedDoc.id)).toBe(true);
|
||||
|
||||
const richText = getRichTextByBlockId(paragraphId);
|
||||
expect(richText.querySelectorAll('affine-reference').length).toBe(2);
|
||||
expect(richText.inlineEditor.yTextString.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('slash-menu action semantics', () => {
|
||||
test('date and move actions mutate block content/order as expected', async () => {
|
||||
const noteId = addNote(doc);
|
||||
const note = doc.getBlock(noteId)?.model;
|
||||
if (!note) {
|
||||
throw new Error('Cannot find note model');
|
||||
}
|
||||
const first = note.children[0] as ParagraphBlockModel;
|
||||
const secondId = doc.addBlock(
|
||||
'affine:paragraph',
|
||||
{ text: new Text('second') },
|
||||
noteId
|
||||
);
|
||||
const second = doc.getBlock(secondId)?.model as
|
||||
| ParagraphBlockModel
|
||||
| undefined;
|
||||
if (!second) {
|
||||
throw new Error('Cannot find second paragraph model');
|
||||
}
|
||||
doc.updateBlock(first, { text: new Text('first') });
|
||||
await wait();
|
||||
|
||||
const slashItems = defaultSlashMenuConfig.items;
|
||||
const items =
|
||||
typeof slashItems === 'function'
|
||||
? slashItems({ std: editor.std, model: first })
|
||||
: slashItems;
|
||||
const today = findSlashActionItem(items, 'Today');
|
||||
const moveDown = findSlashActionItem(items, 'Move Down');
|
||||
const moveUp = findSlashActionItem(items, 'Move Up');
|
||||
|
||||
moveDown.action({ std: editor.std, model: first });
|
||||
await wait();
|
||||
expect(note.children.map(child => child.id)).toEqual([second.id, first.id]);
|
||||
|
||||
moveUp.action({ std: editor.std, model: first });
|
||||
await wait();
|
||||
expect(note.children.map(child => child.id)).toEqual([first.id, second.id]);
|
||||
|
||||
setTextSelection(first.id, 0, 0);
|
||||
today.action({ std: editor.std, model: first });
|
||||
await wait();
|
||||
const richText = getRichTextByBlockId(first.id);
|
||||
expect(richText.inlineEditor.yTextString).toMatch(/\d{4}-\d{2}-\d{2}/);
|
||||
});
|
||||
});
|
||||
@@ -19,7 +19,11 @@ export default defineConfig(_configEnv =>
|
||||
browser: {
|
||||
enabled: true,
|
||||
headless: process.env.CI === 'true',
|
||||
instances: [{ browser: 'chromium' }],
|
||||
instances: [
|
||||
{ browser: 'chromium' },
|
||||
{ browser: 'firefox' },
|
||||
{ browser: 'webkit' },
|
||||
],
|
||||
provider: 'playwright',
|
||||
isolate: false,
|
||||
viewport: {
|
||||
|
||||
@@ -6,7 +6,8 @@ textarea
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
#webpack-dev-server-client-overlay {
|
||||
#webpack-dev-server-client-overlay,
|
||||
#rspack-dev-server-client-overlay {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export const WORKSPACE_ROUTE_PATH = '/workspace/:workspaceId/*';
|
||||
export const SHARE_ROUTE_PATH = '/share/:workspaceId/:pageId';
|
||||
export const NOT_FOUND_ROUTE_PATH = '/404';
|
||||
export const CATCH_ALL_ROUTE_PATH = '*';
|
||||
|
||||
export function getWorkspaceDocPath(workspaceId: string, docId: string) {
|
||||
return `/workspace/${workspaceId}/${docId}`;
|
||||
}
|
||||
@@ -10,6 +10,13 @@ import {
|
||||
import { AffineErrorComponent } from '../components/affine/affine-error-boundary/affine-error-fallback';
|
||||
import { NavigateContext } from '../components/hooks/use-navigate-helper';
|
||||
import { RootWrapper } from './pages/root';
|
||||
import {
|
||||
CATCH_ALL_ROUTE_PATH,
|
||||
getWorkspaceDocPath,
|
||||
NOT_FOUND_ROUTE_PATH,
|
||||
SHARE_ROUTE_PATH,
|
||||
WORKSPACE_ROUTE_PATH,
|
||||
} from './route-paths';
|
||||
|
||||
export function RootRouter() {
|
||||
const navigate = useNavigate();
|
||||
@@ -38,17 +45,19 @@ export const topLevelRoutes = [
|
||||
lazy: () => import('./pages/index'),
|
||||
},
|
||||
{
|
||||
path: '/workspace/:workspaceId/*',
|
||||
path: WORKSPACE_ROUTE_PATH,
|
||||
lazy: () => import('./pages/workspace/index'),
|
||||
},
|
||||
{
|
||||
path: '/share/:workspaceId/:pageId',
|
||||
path: SHARE_ROUTE_PATH,
|
||||
loader: ({ params }) => {
|
||||
return redirect(`/workspace/${params.workspaceId}/${params.pageId}`);
|
||||
return redirect(
|
||||
getWorkspaceDocPath(params.workspaceId ?? '', params.pageId ?? '')
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/404',
|
||||
path: NOT_FOUND_ROUTE_PATH,
|
||||
lazy: () => import('./pages/404'),
|
||||
},
|
||||
{
|
||||
@@ -175,7 +184,7 @@ export const topLevelRoutes = [
|
||||
lazy: () => import('./pages/open-app'),
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
path: CATCH_ALL_ROUTE_PATH,
|
||||
lazy: () => import('./pages/404'),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -18,6 +18,7 @@ import type { DocPropertiesStore } from '../stores/doc-properties';
|
||||
import type { DocsStore } from '../stores/docs';
|
||||
import type { DocCreateOptions } from '../types';
|
||||
import { DocService } from './doc';
|
||||
import { getDuplicatedDocTitle } from './duplicate-title';
|
||||
|
||||
const logger = new DebugLogger('DocsService');
|
||||
|
||||
@@ -286,13 +287,7 @@ export class DocsService extends Service {
|
||||
});
|
||||
|
||||
// duplicate doc title
|
||||
const originalTitle = sourceDoc.title$.value;
|
||||
const lastDigitRegex = /\((\d+)\)$/;
|
||||
const match = originalTitle.match(lastDigitRegex);
|
||||
const newNumber = match ? parseInt(match[1], 10) + 1 : 1;
|
||||
const newPageTitle =
|
||||
originalTitle.replace(lastDigitRegex, '') + `(${newNumber})`;
|
||||
targetDoc.changeDocTitle(newPageTitle);
|
||||
targetDoc.changeDocTitle(getDuplicatedDocTitle(sourceDoc.title$.value));
|
||||
|
||||
// duplicate doc properties
|
||||
const properties = sourceDoc.getProperties();
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
const DUPLICATED_DOC_TITLE_SUFFIX = /\((\d+)\)$/;
|
||||
|
||||
export function getDuplicatedDocTitle(originalTitle: string) {
|
||||
const match = originalTitle.match(DUPLICATED_DOC_TITLE_SUFFIX);
|
||||
const nextSequence = match ? parseInt(match[1], 10) + 1 : 1;
|
||||
return (
|
||||
originalTitle.replace(DUPLICATED_DOC_TITLE_SUFFIX, '') + `(${nextSequence})`
|
||||
);
|
||||
}
|
||||
@@ -46,6 +46,10 @@ import type {
|
||||
} from '../../workspace';
|
||||
import { WorkspaceImpl } from '../../workspace/impls/workspace';
|
||||
import { getWorkspaceProfileWorker } from './out-worker';
|
||||
import {
|
||||
dedupeWorkspaceIds,
|
||||
normalizeWorkspaceIds,
|
||||
} from './workspace-id-utils';
|
||||
|
||||
export const LOCAL_WORKSPACE_LOCAL_STORAGE_KEY = 'affine-local-workspace';
|
||||
export const LOCAL_WORKSPACE_GLOBAL_STATE_KEY =
|
||||
@@ -61,13 +65,6 @@ type GlobalStateStorageLike = {
|
||||
set<T>(key: string, value: T): void;
|
||||
};
|
||||
|
||||
function normalizeWorkspaceIds(ids: unknown): string[] {
|
||||
if (!Array.isArray(ids)) {
|
||||
return [];
|
||||
}
|
||||
return ids.filter((id): id is string => typeof id === 'string');
|
||||
}
|
||||
|
||||
function getElectronGlobalStateStorage(): GlobalStateStorageLike | null {
|
||||
if (!BUILD_CONFIG.isElectron) {
|
||||
return null;
|
||||
@@ -113,7 +110,7 @@ export function setLocalWorkspaceIds(
|
||||
? idsOrUpdater(getLocalWorkspaceIds())
|
||||
: idsOrUpdater
|
||||
);
|
||||
const deduplicated = [...new Set(next)];
|
||||
const deduplicated = dedupeWorkspaceIds(next);
|
||||
|
||||
const globalState = getElectronGlobalStateStorage();
|
||||
if (globalState) {
|
||||
@@ -168,14 +165,12 @@ class LocalWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
|
||||
}
|
||||
|
||||
setLocalWorkspaceIds(currentIds => {
|
||||
return [
|
||||
...new Set([
|
||||
...currentIds,
|
||||
...persistedIds,
|
||||
...legacyIds,
|
||||
...scannedIds,
|
||||
]),
|
||||
];
|
||||
return dedupeWorkspaceIds([
|
||||
...currentIds,
|
||||
...persistedIds,
|
||||
...legacyIds,
|
||||
...scannedIds,
|
||||
]);
|
||||
});
|
||||
})()
|
||||
.catch(e => {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export function normalizeWorkspaceIds(ids: unknown): string[] {
|
||||
if (!Array.isArray(ids)) return [];
|
||||
return ids.filter((id): id is string => typeof id === 'string');
|
||||
}
|
||||
|
||||
export function dedupeWorkspaceIds(ids: string[]): string[] {
|
||||
return [...new Set(ids)];
|
||||
}
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
/// <reference types="@webpack/env"" />
|
||||
/// <reference types="@webpack/env" />
|
||||
/// <reference types="@rspack/core/module" />
|
||||
|
||||
declare module '*.md' {
|
||||
const text: string;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"es-CL": 98,
|
||||
"es": 96,
|
||||
"fa": 96,
|
||||
"fr": 98,
|
||||
"fr": 100,
|
||||
"hi": 1,
|
||||
"it-IT": 98,
|
||||
"it": 1,
|
||||
|
||||
@@ -2311,4 +2311,3 @@
|
||||
"error.RESPONSE_TOO_LARGE_ERROR": "Réponse trop volumineuse ({{receivedBytes}} octets), la limite est de {{limitBytes}} octets",
|
||||
"error.SSRF_BLOCKED_ERROR": "URL invalide"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import type { Page } from '@playwright/test';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
export let coreUrl = 'http://localhost:8080';
|
||||
|
||||
@@ -21,6 +20,7 @@ export async function confirmCreateJournal(page: Page) {
|
||||
}
|
||||
|
||||
export async function openJournalsPage(page: Page) {
|
||||
const { expect } = await import('@playwright/test');
|
||||
await page.getByTestId('slider-bar-journals-button').click();
|
||||
await confirmCreateJournal(page);
|
||||
await expect(
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
"@affine/s3-compat": "workspace:*",
|
||||
"@napi-rs/simple-git": "^0.1.22",
|
||||
"@perfsee/webpack": "^1.13.0",
|
||||
"@rspack/core": "^1.7.6",
|
||||
"@rspack/dev-server": "^1.1.3",
|
||||
"@sentry/webpack-plugin": "^4.0.0",
|
||||
"@swc/core": "^1.10.1",
|
||||
"@tailwindcss/postcss": "^4.0.0",
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import type { Configuration as WebpackDevServerConfiguration } from 'webpack-dev-server';
|
||||
|
||||
export const RSPACK_SUPPORTED_PACKAGES = [
|
||||
'@affine/admin',
|
||||
'@affine/web',
|
||||
'@affine/mobile',
|
||||
'@affine/ios',
|
||||
'@affine/android',
|
||||
'@affine/electron-renderer',
|
||||
'@affine/server',
|
||||
] as const;
|
||||
|
||||
const rspackSupportedPackageSet = new Set<string>(RSPACK_SUPPORTED_PACKAGES);
|
||||
|
||||
export function isRspackSupportedPackageName(name: string) {
|
||||
return rspackSupportedPackageSet.has(name);
|
||||
}
|
||||
|
||||
export function assertRspackSupportedPackageName(name: string) {
|
||||
if (isRspackSupportedPackageName(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`AFFINE_BUNDLER=rspack currently supports: ${Array.from(RSPACK_SUPPORTED_PACKAGES).join(', ')}. Use AFFINE_BUNDLER=webpack for ${name}.`
|
||||
);
|
||||
}
|
||||
|
||||
const IN_CI = !!process.env.CI;
|
||||
const httpProxyMiddlewareLogLevel = IN_CI ? 'silent' : 'error';
|
||||
|
||||
export const DEFAULT_DEV_SERVER_CONFIG: WebpackDevServerConfiguration = {
|
||||
host: '0.0.0.0',
|
||||
allowedHosts: 'all',
|
||||
hot: false,
|
||||
liveReload: true,
|
||||
compress: !process.env.CI,
|
||||
setupExitSignals: true,
|
||||
client: {
|
||||
overlay: process.env.DISABLE_DEV_OVERLAY === 'true' ? false : undefined,
|
||||
logging: process.env.CI ? 'none' : 'error',
|
||||
// see: https://webpack.js.org/configuration/dev-server/#websocketurl
|
||||
// must be an explicit ws/wss URL because custom protocols (e.g. assets://)
|
||||
// cannot be used to construct WebSocket endpoints in Electron
|
||||
webSocketURL: 'ws://0.0.0.0:8080/ws',
|
||||
},
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
{
|
||||
from: /.*/,
|
||||
to: () => {
|
||||
return process.env.SELF_HOSTED === 'true'
|
||||
? '/selfhost.html'
|
||||
: '/index.html';
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
proxy: [
|
||||
{
|
||||
context: '/api',
|
||||
target: 'http://localhost:3010',
|
||||
logLevel: httpProxyMiddlewareLogLevel,
|
||||
},
|
||||
{
|
||||
context: '/socket.io',
|
||||
target: 'http://localhost:3010',
|
||||
ws: true,
|
||||
logLevel: httpProxyMiddlewareLogLevel,
|
||||
},
|
||||
{
|
||||
context: '/graphql',
|
||||
target: 'http://localhost:3010',
|
||||
logLevel: httpProxyMiddlewareLogLevel,
|
||||
},
|
||||
],
|
||||
};
|
||||
+226
-70
@@ -3,20 +3,46 @@ import { cpus } from 'node:os';
|
||||
|
||||
import { Logger } from '@affine-tools/utils/logger';
|
||||
import { Package } from '@affine-tools/utils/workspace';
|
||||
import rspack, { type MultiRspackOptions } from '@rspack/core';
|
||||
import {
|
||||
type Configuration as RspackDevServerConfiguration,
|
||||
RspackDevServer,
|
||||
} from '@rspack/dev-server';
|
||||
import { merge } from 'lodash-es';
|
||||
import webpack from 'webpack';
|
||||
import WebpackDevServer, {
|
||||
type Configuration as DevServerConfiguration,
|
||||
type Configuration as WebpackDevServerConfiguration,
|
||||
} from 'webpack-dev-server';
|
||||
|
||||
import {
|
||||
assertRspackSupportedPackageName,
|
||||
DEFAULT_DEV_SERVER_CONFIG,
|
||||
isRspackSupportedPackageName,
|
||||
} from './bundle-shared';
|
||||
import { type Bundler, getBundler } from './bundler';
|
||||
import { Option, PackageCommand } from './command';
|
||||
import {
|
||||
createHTMLTargetConfig,
|
||||
createNodeTargetConfig,
|
||||
createWorkerTargetConfig,
|
||||
createHTMLTargetConfig as createRspackHTMLTargetConfig,
|
||||
createNodeTargetConfig as createRspackNodeTargetConfig,
|
||||
createWorkerTargetConfig as createRspackWorkerTargetConfig,
|
||||
} from './rspack';
|
||||
import {
|
||||
createHTMLTargetConfig as createWebpackHTMLTargetConfig,
|
||||
createNodeTargetConfig as createWebpackNodeTargetConfig,
|
||||
createWorkerTargetConfig as createWebpackWorkerTargetConfig,
|
||||
} from './webpack';
|
||||
|
||||
function getBaseWorkerConfigs(pkg: Package) {
|
||||
type WorkerConfig = { name: string };
|
||||
type CreateWorkerTargetConfig = (pkg: Package, entry: string) => WorkerConfig;
|
||||
|
||||
function assertRspackSupportedPackage(pkg: Package) {
|
||||
assertRspackSupportedPackageName(pkg.name);
|
||||
}
|
||||
|
||||
function getBaseWorkerConfigs(
|
||||
pkg: Package,
|
||||
createWorkerTargetConfig: CreateWorkerTargetConfig
|
||||
) {
|
||||
const core = new Package('@affine/core');
|
||||
|
||||
return [
|
||||
@@ -39,27 +65,30 @@ function getBaseWorkerConfigs(pkg: Package) {
|
||||
];
|
||||
}
|
||||
|
||||
function getBundleConfigs(pkg: Package): webpack.MultiConfiguration {
|
||||
function getWebpackBundleConfigs(pkg: Package): webpack.MultiConfiguration {
|
||||
switch (pkg.name) {
|
||||
case '@affine/admin': {
|
||||
return [
|
||||
createHTMLTargetConfig(pkg, pkg.srcPath.join('index.tsx').value),
|
||||
createWebpackHTMLTargetConfig(pkg, pkg.srcPath.join('index.tsx').value),
|
||||
] as webpack.MultiConfiguration;
|
||||
}
|
||||
case '@affine/web':
|
||||
case '@affine/mobile':
|
||||
case '@affine/ios':
|
||||
case '@affine/android': {
|
||||
const workerConfigs = getBaseWorkerConfigs(pkg);
|
||||
const workerConfigs = getBaseWorkerConfigs(
|
||||
pkg,
|
||||
createWebpackWorkerTargetConfig
|
||||
);
|
||||
workerConfigs.push(
|
||||
createWorkerTargetConfig(
|
||||
createWebpackWorkerTargetConfig(
|
||||
pkg,
|
||||
pkg.srcPath.join('nbstore.worker.ts').value
|
||||
)
|
||||
);
|
||||
|
||||
return [
|
||||
createHTMLTargetConfig(
|
||||
createWebpackHTMLTargetConfig(
|
||||
pkg,
|
||||
pkg.srcPath.join('index.tsx').value,
|
||||
{},
|
||||
@@ -69,10 +98,13 @@ function getBundleConfigs(pkg: Package): webpack.MultiConfiguration {
|
||||
] as webpack.MultiConfiguration;
|
||||
}
|
||||
case '@affine/electron-renderer': {
|
||||
const workerConfigs = getBaseWorkerConfigs(pkg);
|
||||
const workerConfigs = getBaseWorkerConfigs(
|
||||
pkg,
|
||||
createWebpackWorkerTargetConfig
|
||||
);
|
||||
|
||||
return [
|
||||
createHTMLTargetConfig(
|
||||
createWebpackHTMLTargetConfig(
|
||||
pkg,
|
||||
{
|
||||
index: pkg.srcPath.join('app/index.tsx').value,
|
||||
@@ -93,7 +125,7 @@ function getBundleConfigs(pkg: Package): webpack.MultiConfiguration {
|
||||
}
|
||||
case '@affine/server': {
|
||||
return [
|
||||
createNodeTargetConfig(pkg, pkg.srcPath.join('index.ts').value),
|
||||
createWebpackNodeTargetConfig(pkg, pkg.srcPath.join('index.ts').value),
|
||||
] as webpack.MultiConfiguration;
|
||||
}
|
||||
}
|
||||
@@ -101,55 +133,75 @@ function getBundleConfigs(pkg: Package): webpack.MultiConfiguration {
|
||||
throw new Error(`Unsupported package: ${pkg.name}`);
|
||||
}
|
||||
|
||||
const IN_CI = !!process.env.CI;
|
||||
const httpProxyMiddlewareLogLevel = IN_CI ? 'silent' : 'error';
|
||||
function getRspackBundleConfigs(pkg: Package): MultiRspackOptions {
|
||||
assertRspackSupportedPackage(pkg);
|
||||
|
||||
const defaultDevServerConfig: DevServerConfiguration = {
|
||||
host: '0.0.0.0',
|
||||
allowedHosts: 'all',
|
||||
hot: false,
|
||||
liveReload: true,
|
||||
compress: !process.env.CI,
|
||||
setupExitSignals: true,
|
||||
client: {
|
||||
overlay: process.env.DISABLE_DEV_OVERLAY === 'true' ? false : undefined,
|
||||
logging: process.env.CI ? 'none' : 'error',
|
||||
// see: https://webpack.js.org/configuration/dev-server/#websocketurl
|
||||
// must be an explicit ws/wss URL because custom protocols (e.g. assets://)
|
||||
// cannot be used to construct WebSocket endpoints in Electron
|
||||
webSocketURL: 'ws://0.0.0.0:8080/ws',
|
||||
},
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
{
|
||||
from: /.*/,
|
||||
to: () => {
|
||||
return process.env.SELF_HOSTED === 'true'
|
||||
? '/selfhost.html'
|
||||
: '/index.html';
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
proxy: [
|
||||
{
|
||||
context: '/api',
|
||||
target: 'http://localhost:3010',
|
||||
logLevel: httpProxyMiddlewareLogLevel,
|
||||
},
|
||||
{
|
||||
context: '/socket.io',
|
||||
target: 'http://localhost:3010',
|
||||
ws: true,
|
||||
logLevel: httpProxyMiddlewareLogLevel,
|
||||
},
|
||||
{
|
||||
context: '/graphql',
|
||||
target: 'http://localhost:3010',
|
||||
logLevel: httpProxyMiddlewareLogLevel,
|
||||
},
|
||||
],
|
||||
};
|
||||
switch (pkg.name) {
|
||||
case '@affine/admin': {
|
||||
return [
|
||||
createRspackHTMLTargetConfig(pkg, pkg.srcPath.join('index.tsx').value),
|
||||
] as MultiRspackOptions;
|
||||
}
|
||||
case '@affine/web':
|
||||
case '@affine/mobile':
|
||||
case '@affine/ios':
|
||||
case '@affine/android': {
|
||||
const workerConfigs = getBaseWorkerConfigs(
|
||||
pkg,
|
||||
createRspackWorkerTargetConfig
|
||||
);
|
||||
workerConfigs.push(
|
||||
createRspackWorkerTargetConfig(
|
||||
pkg,
|
||||
pkg.srcPath.join('nbstore.worker.ts').value
|
||||
)
|
||||
);
|
||||
|
||||
return [
|
||||
createRspackHTMLTargetConfig(
|
||||
pkg,
|
||||
pkg.srcPath.join('index.tsx').value,
|
||||
{},
|
||||
workerConfigs.map(config => config.name)
|
||||
),
|
||||
...workerConfigs,
|
||||
] as MultiRspackOptions;
|
||||
}
|
||||
case '@affine/electron-renderer': {
|
||||
const workerConfigs = getBaseWorkerConfigs(
|
||||
pkg,
|
||||
createRspackWorkerTargetConfig
|
||||
);
|
||||
|
||||
return [
|
||||
createRspackHTMLTargetConfig(
|
||||
pkg,
|
||||
{
|
||||
index: pkg.srcPath.join('app/index.tsx').value,
|
||||
shell: pkg.srcPath.join('shell/index.tsx').value,
|
||||
popup: pkg.srcPath.join('popup/index.tsx').value,
|
||||
backgroundWorker: pkg.srcPath.join('background-worker/index.ts')
|
||||
.value,
|
||||
},
|
||||
{
|
||||
additionalEntryForSelfhost: false,
|
||||
injectGlobalErrorHandler: false,
|
||||
emitAssetsManifest: false,
|
||||
},
|
||||
workerConfigs.map(config => config.name)
|
||||
),
|
||||
...workerConfigs,
|
||||
] as MultiRspackOptions;
|
||||
}
|
||||
case '@affine/server': {
|
||||
return [
|
||||
createRspackNodeTargetConfig(pkg, pkg.srcPath.join('index.ts').value),
|
||||
] as MultiRspackOptions;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported package: ${pkg.name}`);
|
||||
}
|
||||
|
||||
export class BundleCommand extends PackageCommand {
|
||||
static override paths = [['bundle'], ['webpack'], ['pack'], ['bun']];
|
||||
@@ -164,22 +216,36 @@ export class BundleCommand extends PackageCommand {
|
||||
|
||||
async execute() {
|
||||
const pkg = this.workspace.getPackage(this.package);
|
||||
const bundler = getBundler();
|
||||
|
||||
if (this.dev) {
|
||||
await BundleCommand.dev(pkg);
|
||||
await BundleCommand.dev(pkg, bundler);
|
||||
} else {
|
||||
await BundleCommand.build(pkg);
|
||||
await BundleCommand.build(pkg, bundler);
|
||||
}
|
||||
}
|
||||
|
||||
static async build(pkg: Package) {
|
||||
static async build(pkg: Package, bundler: Bundler = getBundler()) {
|
||||
if (bundler === 'rspack' && !isRspackSupportedPackageName(pkg.name)) {
|
||||
return BundleCommand.buildWithWebpack(pkg);
|
||||
}
|
||||
|
||||
switch (bundler) {
|
||||
case 'webpack':
|
||||
return BundleCommand.buildWithWebpack(pkg);
|
||||
case 'rspack':
|
||||
return BundleCommand.buildWithRspack(pkg);
|
||||
}
|
||||
}
|
||||
|
||||
static async buildWithWebpack(pkg: Package) {
|
||||
process.env.NODE_ENV = 'production';
|
||||
const logger = new Logger('bundle');
|
||||
logger.info(`Packing package ${pkg.name}...`);
|
||||
logger.info(`Packing package ${pkg.name} with webpack...`);
|
||||
logger.info('Cleaning old output...');
|
||||
rmSync(pkg.distPath.value, { recursive: true, force: true });
|
||||
|
||||
const config = getBundleConfigs(pkg);
|
||||
const config = getWebpackBundleConfigs(pkg);
|
||||
config.parallelism = cpus().length;
|
||||
|
||||
const compiler = webpack(config);
|
||||
@@ -203,12 +269,43 @@ export class BundleCommand extends PackageCommand {
|
||||
});
|
||||
}
|
||||
|
||||
static async dev(pkg: Package, devServerConfig?: DevServerConfiguration) {
|
||||
static async dev(
|
||||
pkg: Package,
|
||||
bundler: Bundler = getBundler(),
|
||||
devServerConfig?:
|
||||
| WebpackDevServerConfiguration
|
||||
| RspackDevServerConfiguration
|
||||
) {
|
||||
if (bundler === 'rspack' && !isRspackSupportedPackageName(pkg.name)) {
|
||||
return BundleCommand.devWithWebpack(
|
||||
pkg,
|
||||
devServerConfig as WebpackDevServerConfiguration | undefined
|
||||
);
|
||||
}
|
||||
|
||||
switch (bundler) {
|
||||
case 'webpack':
|
||||
return BundleCommand.devWithWebpack(
|
||||
pkg,
|
||||
devServerConfig as WebpackDevServerConfiguration | undefined
|
||||
);
|
||||
case 'rspack':
|
||||
return BundleCommand.devWithRspack(
|
||||
pkg,
|
||||
devServerConfig as RspackDevServerConfiguration | undefined
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static async devWithWebpack(
|
||||
pkg: Package,
|
||||
devServerConfig?: WebpackDevServerConfiguration
|
||||
) {
|
||||
process.env.NODE_ENV = 'development';
|
||||
const logger = new Logger('bundle');
|
||||
logger.info(`Starting dev server for ${pkg.name}...`);
|
||||
logger.info(`Starting webpack dev server for ${pkg.name}...`);
|
||||
|
||||
const config = getBundleConfigs(pkg);
|
||||
const config = getWebpackBundleConfigs(pkg);
|
||||
config.parallelism = cpus().length;
|
||||
|
||||
const compiler = webpack(config);
|
||||
@@ -217,7 +314,66 @@ export class BundleCommand extends PackageCommand {
|
||||
}
|
||||
|
||||
const devServer = new WebpackDevServer(
|
||||
merge({}, defaultDevServerConfig, devServerConfig),
|
||||
merge({}, DEFAULT_DEV_SERVER_CONFIG, devServerConfig),
|
||||
compiler
|
||||
);
|
||||
|
||||
await devServer.start();
|
||||
}
|
||||
|
||||
static async buildWithRspack(pkg: Package) {
|
||||
process.env.NODE_ENV = 'production';
|
||||
assertRspackSupportedPackage(pkg);
|
||||
|
||||
const logger = new Logger('bundle');
|
||||
logger.info(`Packing package ${pkg.name} with rspack...`);
|
||||
logger.info('Cleaning old output...');
|
||||
rmSync(pkg.distPath.value, { recursive: true, force: true });
|
||||
|
||||
const config = getRspackBundleConfigs(pkg);
|
||||
config.parallelism = cpus().length;
|
||||
|
||||
const compiler = rspack(config);
|
||||
if (!compiler) {
|
||||
throw new Error('Failed to create rspack compiler');
|
||||
}
|
||||
|
||||
compiler.run((error, stats) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
if (stats) {
|
||||
if (stats.hasErrors()) {
|
||||
console.error(stats.toString('errors-only'));
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log(stats.toString('minimal'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static async devWithRspack(
|
||||
pkg: Package,
|
||||
devServerConfig?: RspackDevServerConfiguration
|
||||
) {
|
||||
process.env.NODE_ENV = 'development';
|
||||
assertRspackSupportedPackage(pkg);
|
||||
|
||||
const logger = new Logger('bundle');
|
||||
logger.info(`Starting rspack dev server for ${pkg.name}...`);
|
||||
|
||||
const config = getRspackBundleConfigs(pkg);
|
||||
config.parallelism = cpus().length;
|
||||
|
||||
const compiler = rspack(config);
|
||||
if (!compiler) {
|
||||
throw new Error('Failed to create rspack compiler');
|
||||
}
|
||||
|
||||
const devServer = new RspackDevServer(
|
||||
merge({}, DEFAULT_DEV_SERVER_CONFIG, devServerConfig),
|
||||
compiler
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
export const SUPPORTED_BUNDLERS = ['webpack', 'rspack'] as const;
|
||||
|
||||
export type Bundler = (typeof SUPPORTED_BUNDLERS)[number];
|
||||
|
||||
export const DEFAULT_BUNDLER: Bundler = 'rspack';
|
||||
|
||||
function isBundler(value: string): value is Bundler {
|
||||
return SUPPORTED_BUNDLERS.includes(value as Bundler);
|
||||
}
|
||||
|
||||
export function normalizeBundler(input: string | undefined | null): Bundler {
|
||||
const value = input?.trim().toLowerCase();
|
||||
if (!value) {
|
||||
return DEFAULT_BUNDLER;
|
||||
}
|
||||
if (isBundler(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Unsupported AFFINE_BUNDLER: "${input}". Expected one of: ${SUPPORTED_BUNDLERS.join(', ')}.`
|
||||
);
|
||||
}
|
||||
|
||||
export function getBundler(env: NodeJS.ProcessEnv = process.env): Bundler {
|
||||
return normalizeBundler(env.AFFINE_BUNDLER);
|
||||
}
|
||||
@@ -0,0 +1,638 @@
|
||||
import { createRequire } from 'node:module';
|
||||
import path from 'node:path';
|
||||
|
||||
import { getBuildConfig } from '@affine-tools/utils/build-config';
|
||||
import { Path, ProjectRoot } from '@affine-tools/utils/path';
|
||||
import { Package } from '@affine-tools/utils/workspace';
|
||||
import rspack, {
|
||||
type Configuration as RspackConfiguration,
|
||||
} from '@rspack/core';
|
||||
import { sentryWebpackPlugin } from '@sentry/webpack-plugin';
|
||||
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
|
||||
import cssnano from 'cssnano';
|
||||
import { compact, merge } from 'lodash-es';
|
||||
|
||||
import { productionCacheGroups } from '../webpack/cache-group.js';
|
||||
import {
|
||||
type CreateHTMLPluginConfig,
|
||||
createHTMLPlugins as createWebpackCompatibleHTMLPlugins,
|
||||
} from '../webpack/html-plugin.js';
|
||||
import { WebpackS3Plugin } from '../webpack/s3-plugin.js';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const IN_CI = !!process.env.CI;
|
||||
|
||||
const availableChannels = ['canary', 'beta', 'stable', 'internal'];
|
||||
function getBuildConfigFromEnv(pkg: Package) {
|
||||
const channel = process.env.BUILD_TYPE ?? 'canary';
|
||||
const dev = process.env.NODE_ENV === 'development';
|
||||
if (!availableChannels.includes(channel)) {
|
||||
throw new Error(
|
||||
`BUILD_TYPE must be one of ${availableChannels.join(', ')}, received [${channel}]`
|
||||
);
|
||||
}
|
||||
|
||||
return getBuildConfig(pkg, {
|
||||
// @ts-expect-error checked
|
||||
channel,
|
||||
mode: dev ? 'development' : 'production',
|
||||
});
|
||||
}
|
||||
|
||||
export function createHTMLTargetConfig(
|
||||
pkg: Package,
|
||||
entry: string | Record<string, string>,
|
||||
htmlConfig: Partial<CreateHTMLPluginConfig> = {},
|
||||
deps?: string[]
|
||||
): RspackConfiguration {
|
||||
entry = typeof entry === 'string' ? { index: entry } : entry;
|
||||
|
||||
htmlConfig = merge(
|
||||
{},
|
||||
{
|
||||
filename: 'index.html',
|
||||
additionalEntryForSelfhost: true,
|
||||
injectGlobalErrorHandler: true,
|
||||
emitAssetsManifest: true,
|
||||
},
|
||||
htmlConfig
|
||||
);
|
||||
|
||||
const buildConfig = getBuildConfigFromEnv(pkg);
|
||||
|
||||
console.log(
|
||||
`Building [${pkg.name}] for [${buildConfig.appBuildType}] channel in [${buildConfig.debug ? 'development' : 'production'}] mode.`
|
||||
);
|
||||
console.log(
|
||||
`Entry points: ${Object.entries(entry)
|
||||
.map(([name, path]) => `${name}: ${path}`)
|
||||
.join(', ')}`
|
||||
);
|
||||
console.log(`Output path: ${pkg.distPath.value}`);
|
||||
console.log(`Config: ${JSON.stringify(buildConfig, null, 2)}`);
|
||||
|
||||
const config: RspackConfiguration = {
|
||||
//#region basic webpack config
|
||||
name: entry['index'],
|
||||
dependencies: deps,
|
||||
context: ProjectRoot.value,
|
||||
experiments: {
|
||||
topLevelAwait: true,
|
||||
outputModule: false,
|
||||
asyncWebAssembly: true,
|
||||
},
|
||||
entry,
|
||||
output: {
|
||||
environment: { module: true, dynamicImport: true },
|
||||
filename: buildConfig.debug
|
||||
? 'js/[name].js'
|
||||
: 'js/[name].[contenthash:8].js',
|
||||
assetModuleFilename: buildConfig.debug
|
||||
? '[name].[contenthash:8][ext]'
|
||||
: 'assets/[name].[contenthash:8][ext][query]',
|
||||
path: pkg.distPath.value,
|
||||
clean: false,
|
||||
globalObject: 'globalThis',
|
||||
// NOTE: always keep it '/'
|
||||
publicPath: '/',
|
||||
},
|
||||
target: ['web', 'es2022'],
|
||||
mode: buildConfig.debug ? 'development' : 'production',
|
||||
devtool: buildConfig.debug ? 'cheap-module-source-map' : 'source-map',
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
extensionAlias: {
|
||||
'.js': ['.js', '.tsx', '.ts'],
|
||||
'.mjs': ['.mjs', '.mts'],
|
||||
},
|
||||
extensions: ['.js', '.ts', '.tsx'],
|
||||
alias: {
|
||||
yjs: ProjectRoot.join('node_modules', 'yjs').value,
|
||||
lit: ProjectRoot.join('node_modules', 'lit').value,
|
||||
'@preact/signals-core': ProjectRoot.join(
|
||||
'node_modules',
|
||||
'@preact',
|
||||
'signals-core'
|
||||
).value,
|
||||
},
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//#region module config
|
||||
module: {
|
||||
parser: {
|
||||
javascript: {
|
||||
// Do not mock Node.js globals
|
||||
node: false,
|
||||
requireJs: false,
|
||||
import: true,
|
||||
// Treat as missing export as error
|
||||
strictExportPresence: true,
|
||||
},
|
||||
},
|
||||
//#region rules
|
||||
rules: [
|
||||
{ test: /\.m?js?$/, resolve: { fullySpecified: false } },
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: 'pre',
|
||||
include: /@blocksuite/,
|
||||
use: ['source-map-loader'],
|
||||
},
|
||||
{
|
||||
oneOf: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'swc-loader',
|
||||
options: {
|
||||
// https://swc.rs/docs/configuring-swc/
|
||||
jsc: {
|
||||
preserveAllComments: true,
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
dynamicImport: true,
|
||||
topLevelAwait: false,
|
||||
tsx: false,
|
||||
decorators: true,
|
||||
},
|
||||
target: 'es2022',
|
||||
externalHelpers: false,
|
||||
transform: {
|
||||
useDefineForClassFields: false,
|
||||
decoratorVersion: '2022-03',
|
||||
},
|
||||
},
|
||||
sourceMaps: true,
|
||||
inlineSourcesContent: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.tsx$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'swc-loader',
|
||||
options: {
|
||||
// https://swc.rs/docs/configuring-swc/
|
||||
jsc: {
|
||||
preserveAllComments: true,
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
dynamicImport: true,
|
||||
topLevelAwait: false,
|
||||
tsx: true,
|
||||
decorators: true,
|
||||
},
|
||||
target: 'es2022',
|
||||
externalHelpers: false,
|
||||
transform: {
|
||||
react: { runtime: 'automatic' },
|
||||
useDefineForClassFields: false,
|
||||
decoratorVersion: '2022-03',
|
||||
},
|
||||
},
|
||||
sourceMaps: true,
|
||||
inlineSourcesContent: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|svg|webp|mp4|zip)$/,
|
||||
type: 'asset/resource',
|
||||
},
|
||||
{ test: /\.(ttf|eot|woff|woff2)$/, type: 'asset/resource' },
|
||||
{ test: /\.txt$/, type: 'asset/source' },
|
||||
{ test: /\.inline\.svg$/, type: 'asset/inline' },
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
buildConfig.debug
|
||||
? 'style-loader'
|
||||
: rspack.CssExtractRspackPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
url: true,
|
||||
sourceMap: false,
|
||||
modules: false,
|
||||
import: true,
|
||||
importLoaders: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: pkg.join('tailwind.config.js').exists()
|
||||
? [
|
||||
[
|
||||
'@tailwindcss/postcss',
|
||||
require(pkg.join('tailwind.config.js').value),
|
||||
],
|
||||
['autoprefixer'],
|
||||
]
|
||||
: [
|
||||
cssnano({
|
||||
preset: ['default', { convertValues: false }],
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
//#endregion
|
||||
},
|
||||
//#endregion
|
||||
|
||||
//#region plugins
|
||||
plugins: compact([
|
||||
!IN_CI && new rspack.ProgressPlugin(),
|
||||
...createWebpackCompatibleHTMLPlugins(buildConfig, htmlConfig),
|
||||
new rspack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
||||
...Object.entries(buildConfig).reduce(
|
||||
(def, [k, v]) => {
|
||||
def[`BUILD_CONFIG.${k}`] = JSON.stringify(v);
|
||||
return def;
|
||||
},
|
||||
{} as Record<string, string>
|
||||
),
|
||||
}),
|
||||
!buildConfig.debug &&
|
||||
// todo: support multiple entry points
|
||||
new rspack.CssExtractRspackPlugin({
|
||||
filename: `[name].[contenthash:8].css`,
|
||||
ignoreOrder: true,
|
||||
}),
|
||||
new VanillaExtractPlugin(),
|
||||
!buildConfig.isAdmin &&
|
||||
new rspack.CopyRspackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
// copy the shared public assets into dist
|
||||
from: new Package('@affine/core').join('public').value,
|
||||
},
|
||||
],
|
||||
}),
|
||||
!buildConfig.debug &&
|
||||
(buildConfig.isWeb || buildConfig.isMobileWeb || buildConfig.isAdmin) &&
|
||||
process.env.R2_SECRET_ACCESS_KEY &&
|
||||
new WebpackS3Plugin(),
|
||||
process.env.SENTRY_AUTH_TOKEN &&
|
||||
process.env.SENTRY_ORG &&
|
||||
process.env.SENTRY_PROJECT &&
|
||||
sentryWebpackPlugin({
|
||||
org: process.env.SENTRY_ORG,
|
||||
project: process.env.SENTRY_PROJECT,
|
||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||
}),
|
||||
// sourcemap url like # sourceMappingURL=76-6370cd185962bc89.js.map wont load in electron
|
||||
// this is because the default file:// protocol will be ignored by Chromium
|
||||
// so we need to replace the sourceMappingURL to assets:// protocol
|
||||
// for example:
|
||||
// replace # sourceMappingURL=76-6370cd185962bc89.js.map
|
||||
// to # sourceMappingURL=assets://./{dir}/76-6370cd185962bc89.js.map
|
||||
buildConfig.isElectron &&
|
||||
new rspack.SourceMapDevToolPlugin({
|
||||
append: (pathData: { filename?: string }) => {
|
||||
return `\n//# sourceMappingURL=assets://./${pathData.filename ?? ''}.map`;
|
||||
},
|
||||
filename: '[file].map',
|
||||
}),
|
||||
]),
|
||||
//#endregion
|
||||
|
||||
stats: { errorDetails: true },
|
||||
|
||||
//#region optimization
|
||||
optimization: {
|
||||
minimize: !buildConfig.debug,
|
||||
minimizer: [
|
||||
new rspack.SwcJsMinimizerRspackPlugin({
|
||||
extractComments: true,
|
||||
minimizerOptions: {
|
||||
ecma: 2020,
|
||||
compress: { unused: true },
|
||||
mangle: { keep_classnames: true },
|
||||
},
|
||||
}),
|
||||
],
|
||||
removeEmptyChunks: true,
|
||||
providedExports: true,
|
||||
usedExports: true,
|
||||
sideEffects: true,
|
||||
removeAvailableModules: true,
|
||||
runtimeChunk: { name: 'runtime' },
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
minSize: 1,
|
||||
minChunks: 1,
|
||||
maxInitialRequests: Number.MAX_SAFE_INTEGER,
|
||||
maxAsyncRequests: Number.MAX_SAFE_INTEGER,
|
||||
cacheGroups: {
|
||||
...productionCacheGroups,
|
||||
// Rspack tends to pull async node_modules into the initial vendor chunk
|
||||
// when `vendor` is configured as `chunks: 'all'`.
|
||||
vendor: {
|
||||
...productionCacheGroups.vendor,
|
||||
chunks: 'initial',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
//#endregion
|
||||
};
|
||||
|
||||
if (buildConfig.debug && !IN_CI) {
|
||||
config.optimization = {
|
||||
...config.optimization,
|
||||
minimize: false,
|
||||
runtimeChunk: false,
|
||||
splitChunks: {
|
||||
maxInitialRequests: Infinity,
|
||||
chunks: 'all',
|
||||
cacheGroups: {
|
||||
defaultVendors: {
|
||||
test: `[\\/]node_modules[\\/](?!.*vanilla-extract)`,
|
||||
priority: -10,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
default: { minChunks: 2, priority: -20, reuseExistingChunk: true },
|
||||
styles: {
|
||||
name: 'styles',
|
||||
type: 'css/mini-extract',
|
||||
chunks: 'all',
|
||||
enforce: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
export function createWorkerTargetConfig(
|
||||
pkg: Package,
|
||||
entry: string
|
||||
): Omit<RspackConfiguration, 'name'> & { name: string } {
|
||||
const workerName = path.basename(entry).replace(/\.worker\.ts$/, '');
|
||||
const buildConfig = getBuildConfigFromEnv(pkg);
|
||||
|
||||
return {
|
||||
name: entry,
|
||||
context: ProjectRoot.value,
|
||||
experiments: {
|
||||
topLevelAwait: true,
|
||||
outputModule: false,
|
||||
asyncWebAssembly: true,
|
||||
},
|
||||
entry: { [workerName]: entry },
|
||||
output: {
|
||||
filename: `js/${workerName}-${buildConfig.appVersion}.worker.js`,
|
||||
path: pkg.distPath.value,
|
||||
clean: false,
|
||||
globalObject: 'globalThis',
|
||||
// NOTE: always keep it '/'
|
||||
publicPath: '/',
|
||||
},
|
||||
target: ['webworker', 'es2022'],
|
||||
mode: buildConfig.debug ? 'development' : 'production',
|
||||
devtool: buildConfig.debug ? 'cheap-module-source-map' : 'source-map',
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
extensionAlias: { '.js': ['.js', '.ts'], '.mjs': ['.mjs', '.mts'] },
|
||||
extensions: ['.js', '.ts'],
|
||||
alias: { yjs: ProjectRoot.join('node_modules', 'yjs').value },
|
||||
},
|
||||
|
||||
module: {
|
||||
parser: {
|
||||
javascript: {
|
||||
// Do not mock Node.js globals
|
||||
node: false,
|
||||
requireJs: false,
|
||||
import: true,
|
||||
// Treat as missing export as error
|
||||
strictExportPresence: true,
|
||||
},
|
||||
},
|
||||
rules: [
|
||||
{ test: /\.m?js?$/, resolve: { fullySpecified: false } },
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: 'pre',
|
||||
include: /@blocksuite/,
|
||||
use: ['source-map-loader'],
|
||||
},
|
||||
{
|
||||
oneOf: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'swc-loader',
|
||||
options: {
|
||||
// https://swc.rs/docs/configuring-swc/
|
||||
jsc: {
|
||||
preserveAllComments: true,
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
dynamicImport: true,
|
||||
topLevelAwait: false,
|
||||
tsx: false,
|
||||
decorators: true,
|
||||
},
|
||||
target: 'es2022',
|
||||
externalHelpers: false,
|
||||
transform: {
|
||||
useDefineForClassFields: false,
|
||||
decoratorVersion: '2022-03',
|
||||
},
|
||||
},
|
||||
sourceMaps: true,
|
||||
inlineSourcesContent: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: compact([
|
||||
new rspack.DefinePlugin(
|
||||
Object.entries(buildConfig).reduce(
|
||||
(def, [k, v]) => {
|
||||
def[`BUILD_CONFIG.${k}`] = JSON.stringify(v);
|
||||
return def;
|
||||
},
|
||||
{} as Record<string, string>
|
||||
)
|
||||
),
|
||||
new rspack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
|
||||
process.env.SENTRY_AUTH_TOKEN &&
|
||||
process.env.SENTRY_ORG &&
|
||||
process.env.SENTRY_PROJECT &&
|
||||
sentryWebpackPlugin({
|
||||
org: process.env.SENTRY_ORG,
|
||||
project: process.env.SENTRY_PROJECT,
|
||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||
}),
|
||||
]),
|
||||
stats: { errorDetails: true },
|
||||
optimization: {
|
||||
minimize: !buildConfig.debug,
|
||||
minimizer: [
|
||||
new rspack.SwcJsMinimizerRspackPlugin({
|
||||
extractComments: true,
|
||||
minimizerOptions: {
|
||||
ecma: 2020,
|
||||
compress: { unused: true },
|
||||
mangle: { keep_classnames: true },
|
||||
},
|
||||
}),
|
||||
],
|
||||
removeEmptyChunks: true,
|
||||
providedExports: true,
|
||||
usedExports: true,
|
||||
sideEffects: true,
|
||||
removeAvailableModules: true,
|
||||
runtimeChunk: false,
|
||||
splitChunks: false,
|
||||
},
|
||||
performance: { hints: false },
|
||||
};
|
||||
}
|
||||
|
||||
export function createNodeTargetConfig(
|
||||
pkg: Package,
|
||||
entry: string
|
||||
): Omit<RspackConfiguration, 'name'> & { name: string } {
|
||||
const dev = process.env.NODE_ENV === 'development';
|
||||
return {
|
||||
name: entry,
|
||||
context: ProjectRoot.value,
|
||||
experiments: {
|
||||
topLevelAwait: true,
|
||||
outputModule: pkg.packageJson.type === 'module',
|
||||
asyncWebAssembly: true,
|
||||
},
|
||||
entry: { index: entry },
|
||||
output: {
|
||||
filename: `main.js`,
|
||||
path: pkg.distPath.value,
|
||||
clean: true,
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
target: ['node', 'es2022'],
|
||||
externals: ((data: any, callback: (err: null, value: boolean) => void) => {
|
||||
if (
|
||||
data.request &&
|
||||
// import ... from 'module'
|
||||
/^[a-zA-Z@]/.test(data.request) &&
|
||||
// not workspace deps
|
||||
!pkg.deps.some(dep => data.request!.startsWith(dep.name))
|
||||
) {
|
||||
callback(null, true);
|
||||
} else {
|
||||
callback(null, false);
|
||||
}
|
||||
}) as any,
|
||||
externalsPresets: { node: true },
|
||||
node: { __dirname: false, __filename: false },
|
||||
mode: dev ? 'development' : 'production',
|
||||
devtool: 'source-map',
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
extensionAlias: { '.js': ['.js', '.ts'], '.mjs': ['.mjs', '.mts'] },
|
||||
extensions: ['.js', '.ts', '.tsx', '.node'],
|
||||
alias: { yjs: ProjectRoot.join('node_modules', 'yjs').value },
|
||||
},
|
||||
module: {
|
||||
parser: {
|
||||
javascript: { url: false, importMeta: false, createRequire: false },
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
enforce: 'pre',
|
||||
include: /@blocksuite/,
|
||||
use: ['source-map-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.node$/,
|
||||
loader: Path.dir(import.meta.url).join('../webpack/node-loader.js')
|
||||
.value,
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'swc-loader',
|
||||
options: {
|
||||
// https://swc.rs/docs/configuring-swc/
|
||||
jsc: {
|
||||
preserveAllComments: true,
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
dynamicImport: true,
|
||||
topLevelAwait: true,
|
||||
tsx: true,
|
||||
decorators: true,
|
||||
},
|
||||
target: 'es2022',
|
||||
externalHelpers: false,
|
||||
transform: {
|
||||
legacyDecorator: true,
|
||||
decoratorMetadata: true,
|
||||
react: { runtime: 'automatic' },
|
||||
},
|
||||
},
|
||||
sourceMaps: true,
|
||||
inlineSourcesContent: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: compact([
|
||||
new rspack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
|
||||
new rspack.IgnorePlugin({
|
||||
checkResource(resource) {
|
||||
const lazyImports = [
|
||||
'@nestjs/microservices',
|
||||
'@nestjs/websockets/socket-module',
|
||||
'@apollo/subgraph',
|
||||
'@apollo/gateway',
|
||||
'@as-integrations/fastify',
|
||||
'ts-morph',
|
||||
'class-validator',
|
||||
'class-transformer',
|
||||
];
|
||||
return lazyImports.some(lazyImport =>
|
||||
resource.startsWith(lazyImport)
|
||||
);
|
||||
},
|
||||
}),
|
||||
new rspack.DefinePlugin({
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
}),
|
||||
]),
|
||||
stats: { errorDetails: true },
|
||||
optimization: {
|
||||
nodeEnv: false,
|
||||
minimize: !dev,
|
||||
minimizer: [
|
||||
new rspack.SwcJsMinimizerRspackPlugin({
|
||||
extractComments: true,
|
||||
minimizerOptions: {
|
||||
ecma: 2020,
|
||||
compress: { unused: true },
|
||||
mangle: { keep_classnames: true },
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
performance: { hints: false },
|
||||
ignoreWarnings: [/^(?!CriticalDependenciesWarning$)/],
|
||||
};
|
||||
}
|
||||
@@ -21,11 +21,18 @@ export const productionCacheGroups = {
|
||||
asyncVendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name(module: any) {
|
||||
const modulePath =
|
||||
module?.nameForCondition?.() || module?.context || module?.resource;
|
||||
|
||||
if (!modulePath || typeof modulePath !== 'string') {
|
||||
return 'app-async';
|
||||
}
|
||||
|
||||
// monorepo linked in node_modules, so it's not a npm package
|
||||
if (!module.context.includes('node_modules')) {
|
||||
if (!modulePath.includes('node_modules')) {
|
||||
return `app-async`;
|
||||
}
|
||||
const name = module.context.match(
|
||||
const name = modulePath.match(
|
||||
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
|
||||
)?.[1];
|
||||
return `npm-async-${name}`;
|
||||
|
||||
@@ -5,8 +5,31 @@ import { Path, ProjectRoot } from '@affine-tools/utils/path';
|
||||
import { Repository } from '@napi-rs/simple-git';
|
||||
import HTMLPlugin from 'html-webpack-plugin';
|
||||
import { once } from 'lodash-es';
|
||||
import type { Compiler, WebpackPluginInstance } from 'webpack';
|
||||
import webpack from 'webpack';
|
||||
import type { WebpackPluginInstance } from 'webpack';
|
||||
|
||||
type CompilerLike = {
|
||||
webpack?: {
|
||||
sources?: {
|
||||
RawSource?: new (source: string) => unknown;
|
||||
};
|
||||
};
|
||||
hooks: {
|
||||
compilation: {
|
||||
tap: (name: string, callback: (compilation: any) => void) => void;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
function createRawSource(compiler: CompilerLike, source: string) {
|
||||
const RawSource = compiler.webpack?.sources?.RawSource;
|
||||
if (!RawSource) {
|
||||
throw new Error(
|
||||
'compiler.webpack.sources.RawSource is required for html plugin assets emission'
|
||||
);
|
||||
}
|
||||
|
||||
return new RawSource(source);
|
||||
}
|
||||
|
||||
export const getPublicPath = (BUILD_CONFIG: BUILD_CONFIG_TYPE) => {
|
||||
const { BUILD_TYPE } = process.env;
|
||||
@@ -86,7 +109,7 @@ function getHTMLPluginOptions(BUILD_CONFIG: BUILD_CONFIG_TYPE) {
|
||||
}
|
||||
|
||||
const AssetsManifestPlugin = {
|
||||
apply(compiler: Compiler) {
|
||||
apply(compiler: CompilerLike) {
|
||||
compiler.hooks.compilation.tap('assets-manifest-plugin', compilation => {
|
||||
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
|
||||
'assets-manifest-plugin',
|
||||
@@ -94,7 +117,8 @@ const AssetsManifestPlugin = {
|
||||
if (!compilation.getAsset('assets-manifest.json')) {
|
||||
compilation.emitAsset(
|
||||
`assets-manifest.json`,
|
||||
new webpack.sources.RawSource(
|
||||
createRawSource(
|
||||
compiler,
|
||||
JSON.stringify(
|
||||
{
|
||||
...arg.assets,
|
||||
@@ -125,7 +149,7 @@ const AssetsManifestPlugin = {
|
||||
};
|
||||
|
||||
const GlobalErrorHandlerPlugin = {
|
||||
apply(compiler: Compiler) {
|
||||
apply(compiler: CompilerLike) {
|
||||
const globalErrorHandler = [
|
||||
'js/global-error-handler.js',
|
||||
readFileSync(currentDir.join('./error-handler.js').toString(), 'utf-8'),
|
||||
@@ -140,7 +164,7 @@ const GlobalErrorHandlerPlugin = {
|
||||
if (!compilation.getAsset(globalErrorHandler[0])) {
|
||||
compilation.emitAsset(
|
||||
globalErrorHandler[0],
|
||||
new webpack.sources.RawSource(globalErrorHandler[1])
|
||||
createRawSource(compiler, globalErrorHandler[1])
|
||||
);
|
||||
arg.assets.js.unshift(
|
||||
arg.assets.publicPath + globalErrorHandler[0]
|
||||
@@ -156,7 +180,7 @@ const GlobalErrorHandlerPlugin = {
|
||||
};
|
||||
|
||||
const CorsPlugin = {
|
||||
apply(compiler: Compiler) {
|
||||
apply(compiler: CompilerLike) {
|
||||
compiler.hooks.compilation.tap('html-js-cors-plugin', compilation => {
|
||||
HTMLPlugin.getHooks(compilation).alterAssetTags.tap(
|
||||
'html-js-cors-plugin',
|
||||
|
||||
@@ -119,6 +119,8 @@ __metadata:
|
||||
"@affine/s3-compat": "workspace:*"
|
||||
"@napi-rs/simple-git": "npm:^0.1.22"
|
||||
"@perfsee/webpack": "npm:^1.13.0"
|
||||
"@rspack/core": "npm:^1.7.6"
|
||||
"@rspack/dev-server": "npm:^1.1.3"
|
||||
"@sentry/webpack-plugin": "npm:^4.0.0"
|
||||
"@swc/core": "npm:^1.10.1"
|
||||
"@tailwindcss/postcss": "npm:^4.0.0"
|
||||
@@ -4899,13 +4901,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@emnapi/core@npm:^1.4.0, @emnapi/core@npm:^1.7.1":
|
||||
version: 1.7.1
|
||||
resolution: "@emnapi/core@npm:1.7.1"
|
||||
"@emnapi/core@npm:^1.4.0, @emnapi/core@npm:^1.5.0, @emnapi/core@npm:^1.7.1":
|
||||
version: 1.8.1
|
||||
resolution: "@emnapi/core@npm:1.8.1"
|
||||
dependencies:
|
||||
"@emnapi/wasi-threads": "npm:1.1.0"
|
||||
tslib: "npm:^2.4.0"
|
||||
checksum: 10/260841f6dd2a7823a964d9de6da3a5e6f565dac8d21a5bd8f6215b87c45c22a4dc371b9ad877961579ee3cca8a76e55e3dd033ae29cba1998999cda6d794bdab
|
||||
checksum: 10/904ea60c91fc7d8aeb4a8f2c433b8cfb47c50618f2b6f37429fc5093c857c6381c60628a5cfbc3a7b0d75b0a288f21d4ed2d4533e82f92c043801ef255fd6a5c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8247,6 +8249,61 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@module-federation/error-codes@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@module-federation/error-codes@npm:0.22.0"
|
||||
checksum: 10/4edb269e9f3039899f879788c84d2bfecff94ca8e87ffcd80dbf8589d8543ec32558b3fa05c8549a8abd3ac33e856ff2aacf458dea5c0d7bea608bf12bb13359
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@module-federation/runtime-core@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@module-federation/runtime-core@npm:0.22.0"
|
||||
dependencies:
|
||||
"@module-federation/error-codes": "npm:0.22.0"
|
||||
"@module-federation/sdk": "npm:0.22.0"
|
||||
checksum: 10/d21969198322b6f79e0513b702d0af5097613d47819724c849b6c677c163cd10fb8c89e3ff62b798bec498ee4d8e95dec71861071bc4ed74bd86a7e43193bc05
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@module-federation/runtime-tools@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@module-federation/runtime-tools@npm:0.22.0"
|
||||
dependencies:
|
||||
"@module-federation/runtime": "npm:0.22.0"
|
||||
"@module-federation/webpack-bundler-runtime": "npm:0.22.0"
|
||||
checksum: 10/0e7693c1ec02fc5bef770b478c8757cad9cfefb2310d1943151d0ad079b72472d9b2c8a087299e9124dfcd6b649c83290c7fdfa333865baab4ba193f39e7b6bd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@module-federation/runtime@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@module-federation/runtime@npm:0.22.0"
|
||||
dependencies:
|
||||
"@module-federation/error-codes": "npm:0.22.0"
|
||||
"@module-federation/runtime-core": "npm:0.22.0"
|
||||
"@module-federation/sdk": "npm:0.22.0"
|
||||
checksum: 10/eca608be999d7d2e83abc1169643c2f795a5ed950f9e2bdf7000400a30b3e1e0ca4bdaa5daa09f55e44868383d444707e40236cec1aaa7b40432b0cce800b7f3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@module-federation/sdk@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@module-federation/sdk@npm:0.22.0"
|
||||
checksum: 10/d7085d883730a33145052520787a7e59cf9c54b51b2946bebc7c63a6bb668bcc6cbdc27fa0b7354a62f5a7ee4e8829a66b84e644607498f2e37cfd5eb4ded0da
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@module-federation/webpack-bundler-runtime@npm:0.22.0":
|
||||
version: 0.22.0
|
||||
resolution: "@module-federation/webpack-bundler-runtime@npm:0.22.0"
|
||||
dependencies:
|
||||
"@module-federation/runtime": "npm:0.22.0"
|
||||
"@module-federation/sdk": "npm:0.22.0"
|
||||
checksum: 10/afd24406817dfc6474ebcf5be714ccf26690eb3f6f5172bda711c8f23dba149fe47293f7aa2d0733dfed0334c98d4d3d9e7c2da2be78750cae5a72d72f32ce93
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@monaco-editor/loader@npm:^1.5.0":
|
||||
version: 1.7.0
|
||||
resolution: "@monaco-editor/loader@npm:1.7.0"
|
||||
@@ -9131,6 +9188,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/wasm-runtime@npm:1.0.7":
|
||||
version: 1.0.7
|
||||
resolution: "@napi-rs/wasm-runtime@npm:1.0.7"
|
||||
dependencies:
|
||||
"@emnapi/core": "npm:^1.5.0"
|
||||
"@emnapi/runtime": "npm:^1.5.0"
|
||||
"@tybys/wasm-util": "npm:^0.10.1"
|
||||
checksum: 10/6bc32d32d486d07b83220a9b7b2b715e39acacbacef0011ebca05c00b41d80a0535123da10fea7a7d6d7e206712bb50dc50ac3cf88b770754d44378570fb5c05
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@napi-rs/wasm-runtime@npm:^0.2.5, @napi-rs/wasm-runtime@npm:^0.2.9":
|
||||
version: 0.2.9
|
||||
resolution: "@napi-rs/wasm-runtime@npm:0.2.9"
|
||||
@@ -15058,6 +15126,178 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-darwin-arm64@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-darwin-arm64@npm:1.7.6"
|
||||
conditions: os=darwin & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-darwin-x64@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-darwin-x64@npm:1.7.6"
|
||||
conditions: os=darwin & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-linux-arm64-gnu@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-linux-arm64-gnu@npm:1.7.6"
|
||||
conditions: os=linux & cpu=arm64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-linux-arm64-musl@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-linux-arm64-musl@npm:1.7.6"
|
||||
conditions: os=linux & cpu=arm64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-linux-x64-gnu@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-linux-x64-gnu@npm:1.7.6"
|
||||
conditions: os=linux & cpu=x64 & libc=glibc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-linux-x64-musl@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-linux-x64-musl@npm:1.7.6"
|
||||
conditions: os=linux & cpu=x64 & libc=musl
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-wasm32-wasi@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-wasm32-wasi@npm:1.7.6"
|
||||
dependencies:
|
||||
"@napi-rs/wasm-runtime": "npm:1.0.7"
|
||||
conditions: cpu=wasm32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-win32-arm64-msvc@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-win32-arm64-msvc@npm:1.7.6"
|
||||
conditions: os=win32 & cpu=arm64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-win32-ia32-msvc@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-win32-ia32-msvc@npm:1.7.6"
|
||||
conditions: os=win32 & cpu=ia32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding-win32-x64-msvc@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding-win32-x64-msvc@npm:1.7.6"
|
||||
conditions: os=win32 & cpu=x64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/binding@npm:1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/binding@npm:1.7.6"
|
||||
dependencies:
|
||||
"@rspack/binding-darwin-arm64": "npm:1.7.6"
|
||||
"@rspack/binding-darwin-x64": "npm:1.7.6"
|
||||
"@rspack/binding-linux-arm64-gnu": "npm:1.7.6"
|
||||
"@rspack/binding-linux-arm64-musl": "npm:1.7.6"
|
||||
"@rspack/binding-linux-x64-gnu": "npm:1.7.6"
|
||||
"@rspack/binding-linux-x64-musl": "npm:1.7.6"
|
||||
"@rspack/binding-wasm32-wasi": "npm:1.7.6"
|
||||
"@rspack/binding-win32-arm64-msvc": "npm:1.7.6"
|
||||
"@rspack/binding-win32-ia32-msvc": "npm:1.7.6"
|
||||
"@rspack/binding-win32-x64-msvc": "npm:1.7.6"
|
||||
dependenciesMeta:
|
||||
"@rspack/binding-darwin-arm64":
|
||||
optional: true
|
||||
"@rspack/binding-darwin-x64":
|
||||
optional: true
|
||||
"@rspack/binding-linux-arm64-gnu":
|
||||
optional: true
|
||||
"@rspack/binding-linux-arm64-musl":
|
||||
optional: true
|
||||
"@rspack/binding-linux-x64-gnu":
|
||||
optional: true
|
||||
"@rspack/binding-linux-x64-musl":
|
||||
optional: true
|
||||
"@rspack/binding-wasm32-wasi":
|
||||
optional: true
|
||||
"@rspack/binding-win32-arm64-msvc":
|
||||
optional: true
|
||||
"@rspack/binding-win32-ia32-msvc":
|
||||
optional: true
|
||||
"@rspack/binding-win32-x64-msvc":
|
||||
optional: true
|
||||
checksum: 10/fec6c978e51f20471e278a07018b414125cf3bccf9c6bd7032ca65603cfe5bf0fdd7f58c156c0640b5dfab05e82a1e1170ac6d1aacaf4f46b61564be77dbe41b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/core@npm:^1.7.6":
|
||||
version: 1.7.6
|
||||
resolution: "@rspack/core@npm:1.7.6"
|
||||
dependencies:
|
||||
"@module-federation/runtime-tools": "npm:0.22.0"
|
||||
"@rspack/binding": "npm:1.7.6"
|
||||
"@rspack/lite-tapable": "npm:1.1.0"
|
||||
peerDependencies:
|
||||
"@swc/helpers": ">=0.5.1"
|
||||
peerDependenciesMeta:
|
||||
"@swc/helpers":
|
||||
optional: true
|
||||
checksum: 10/9f23c4849926d9ddff34f703ab2be41878bca9e877c130d16d20d911ba4b13f15dfe96d7e86225d7f5a1e48034ab92cccec89f3765f84ff518538f6bb07f1f06
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/dev-server@npm:^1.1.3":
|
||||
version: 1.2.1
|
||||
resolution: "@rspack/dev-server@npm:1.2.1"
|
||||
dependencies:
|
||||
"@types/bonjour": "npm:^3.5.13"
|
||||
"@types/connect-history-api-fallback": "npm:^1.5.4"
|
||||
"@types/express": "npm:^4.17.25"
|
||||
"@types/express-serve-static-core": "npm:^4.17.21"
|
||||
"@types/serve-index": "npm:^1.9.4"
|
||||
"@types/serve-static": "npm:^1.15.5"
|
||||
"@types/sockjs": "npm:^0.3.36"
|
||||
"@types/ws": "npm:^8.5.10"
|
||||
ansi-html-community: "npm:^0.0.8"
|
||||
bonjour-service: "npm:^1.2.1"
|
||||
chokidar: "npm:^3.6.0"
|
||||
colorette: "npm:^2.0.10"
|
||||
compression: "npm:^1.8.1"
|
||||
connect-history-api-fallback: "npm:^2.0.0"
|
||||
express: "npm:^4.22.1"
|
||||
graceful-fs: "npm:^4.2.6"
|
||||
http-proxy-middleware: "npm:^2.0.9"
|
||||
ipaddr.js: "npm:^2.1.0"
|
||||
launch-editor: "npm:^2.6.1"
|
||||
open: "npm:^10.0.3"
|
||||
p-retry: "npm:^6.2.0"
|
||||
schema-utils: "npm:^4.2.0"
|
||||
selfsigned: "npm:^2.4.1"
|
||||
serve-index: "npm:^1.9.1"
|
||||
sockjs: "npm:^0.3.24"
|
||||
spdy: "npm:^4.0.2"
|
||||
webpack-dev-middleware: "npm:^7.4.2"
|
||||
ws: "npm:^8.18.0"
|
||||
peerDependencies:
|
||||
"@rspack/core": "*"
|
||||
checksum: 10/154808faef8079dc1d6eae1712455864cc7bc1ec686f3020f7117ad3e5f2906940f27ec514eb40230276132371570ecdf6b47f7ab117ad209462bcba7c2b0692
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rspack/lite-tapable@npm:1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "@rspack/lite-tapable@npm:1.1.0"
|
||||
checksum: 10/41ff73fe5e1b8dccaad746c9c1bd36dd67649e1ad35776f311b5ba94333a397704e11158579e25a6a7e677c51abe35e66987b1b000faef48d4e4ad2470fea150
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@scarf/scarf@npm:=1.4.0":
|
||||
version: 1.4.0
|
||||
resolution: "@scarf/scarf@npm:1.4.0"
|
||||
@@ -17079,15 +17319,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/express@npm:^4.17.13, @types/express@npm:^4.17.21":
|
||||
version: 4.17.22
|
||||
resolution: "@types/express@npm:4.17.22"
|
||||
"@types/express@npm:^4.17.13, @types/express@npm:^4.17.21, @types/express@npm:^4.17.25":
|
||||
version: 4.17.25
|
||||
resolution: "@types/express@npm:4.17.25"
|
||||
dependencies:
|
||||
"@types/body-parser": "npm:*"
|
||||
"@types/express-serve-static-core": "npm:^4.17.33"
|
||||
"@types/qs": "npm:*"
|
||||
"@types/serve-static": "npm:*"
|
||||
checksum: 10/9497634fc341ff4ac966ec0c529ded03bdacd2c3dae164f10a060ff250c66591b873aedce92d0239869cf3d05615ae9bcad584c7349fe68780242f6fef010c62
|
||||
"@types/serve-static": "npm:^1"
|
||||
checksum: 10/c309fdb79fb8569b5d8d8f11268d0160b271f8b38f0a82c20a0733e526baf033eb7a921cd51d54fe4333c616de9e31caf7d4f3ef73baaf212d61f23f460b0369
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -17610,13 +17850,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/send@npm:*":
|
||||
version: 0.17.4
|
||||
resolution: "@types/send@npm:0.17.4"
|
||||
"@types/send@npm:*, @types/send@npm:<1":
|
||||
version: 0.17.6
|
||||
resolution: "@types/send@npm:0.17.6"
|
||||
dependencies:
|
||||
"@types/mime": "npm:^1"
|
||||
"@types/node": "npm:*"
|
||||
checksum: 10/28320a2aa1eb704f7d96a65272a07c0bf3ae7ed5509c2c96ea5e33238980f71deeed51d3631927a77d5250e4091b3e66bce53b42d770873282c6a20bb8b0280d
|
||||
checksum: 10/4948ab32ab84a81a0073f8243dd48ee766bc80608d5391060360afd1249f83c08a7476f142669ac0b0b8831c89d909a88bcb392d1b39ee48b276a91b50f3d8d1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -17629,14 +17869,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/serve-static@npm:*, @types/serve-static@npm:^1.15.5":
|
||||
version: 1.15.7
|
||||
resolution: "@types/serve-static@npm:1.15.7"
|
||||
"@types/serve-static@npm:*, @types/serve-static@npm:^1, @types/serve-static@npm:^1.15.5":
|
||||
version: 1.15.10
|
||||
resolution: "@types/serve-static@npm:1.15.10"
|
||||
dependencies:
|
||||
"@types/http-errors": "npm:*"
|
||||
"@types/node": "npm:*"
|
||||
"@types/send": "npm:*"
|
||||
checksum: 10/c5a7171d5647f9fbd096ed1a26105759f3153ccf683824d99fee4c7eb9cde2953509621c56a070dd9fb1159e799e86d300cbe4e42245ebc5b0c1767e8ca94a67
|
||||
"@types/send": "npm:<1"
|
||||
checksum: 10/d9be72487540b9598e7d77260d533f241eb2e5db5181bb885ef2d6bc4592dad1c9e8c0e27f465d59478b2faf90edd2d535e834f20fbd9dd3c0928d43dc486404
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -19555,26 +19795,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"body-parser@npm:1.20.3":
|
||||
version: 1.20.3
|
||||
resolution: "body-parser@npm:1.20.3"
|
||||
dependencies:
|
||||
bytes: "npm:3.1.2"
|
||||
content-type: "npm:~1.0.5"
|
||||
debug: "npm:2.6.9"
|
||||
depd: "npm:2.0.0"
|
||||
destroy: "npm:1.2.0"
|
||||
http-errors: "npm:2.0.0"
|
||||
iconv-lite: "npm:0.4.24"
|
||||
on-finished: "npm:2.4.1"
|
||||
qs: "npm:6.13.0"
|
||||
raw-body: "npm:2.5.2"
|
||||
type-is: "npm:~1.6.18"
|
||||
unpipe: "npm:1.0.0"
|
||||
checksum: 10/8723e3d7a672eb50854327453bed85ac48d045f4958e81e7d470c56bf111f835b97e5b73ae9f6393d0011cc9e252771f46fd281bbabc57d33d3986edf1e6aeca
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"body-parser@npm:^2.2.0, body-parser@npm:^2.2.1":
|
||||
version: 2.2.2
|
||||
resolution: "body-parser@npm:2.2.2"
|
||||
@@ -19592,6 +19812,26 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"body-parser@npm:~1.20.3":
|
||||
version: 1.20.4
|
||||
resolution: "body-parser@npm:1.20.4"
|
||||
dependencies:
|
||||
bytes: "npm:~3.1.2"
|
||||
content-type: "npm:~1.0.5"
|
||||
debug: "npm:2.6.9"
|
||||
depd: "npm:2.0.0"
|
||||
destroy: "npm:~1.2.0"
|
||||
http-errors: "npm:~2.0.1"
|
||||
iconv-lite: "npm:~0.4.24"
|
||||
on-finished: "npm:~2.4.1"
|
||||
qs: "npm:~6.14.0"
|
||||
raw-body: "npm:~2.5.3"
|
||||
type-is: "npm:~1.6.18"
|
||||
unpipe: "npm:~1.0.0"
|
||||
checksum: 10/ff67e28d3f426707be8697a75fdf8d564dc50c341b41f054264d8ab6e2924e519c7ce8acc9d0de05328fdc41e1d9f3f200aec9c1cfb1867d6b676a410d97c689
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bonjour-service@npm:^1.2.1":
|
||||
version: 1.3.0
|
||||
resolution: "bonjour-service@npm:1.3.0"
|
||||
@@ -21034,18 +21274,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"compression@npm:^1.7.4":
|
||||
version: 1.8.0
|
||||
resolution: "compression@npm:1.8.0"
|
||||
"compression@npm:^1.7.4, compression@npm:^1.8.1":
|
||||
version: 1.8.1
|
||||
resolution: "compression@npm:1.8.1"
|
||||
dependencies:
|
||||
bytes: "npm:3.1.2"
|
||||
compressible: "npm:~2.0.18"
|
||||
debug: "npm:2.6.9"
|
||||
negotiator: "npm:~0.6.4"
|
||||
on-headers: "npm:~1.0.2"
|
||||
on-headers: "npm:~1.1.0"
|
||||
safe-buffer: "npm:5.2.1"
|
||||
vary: "npm:~1.1.2"
|
||||
checksum: 10/ca213b9bd03e56c7c3596399d846237b5f0b31ca4cdeaa76a9547cd3c1465fbcfcb0fe93a5d7ff64eff28383fc65b53f1ef8bb2720d11bb48ad8c0836c502506
|
||||
checksum: 10/e7552bfbd780f2003c6fe8decb44561f5cc6bc82f0c61e81122caff5ec656f37824084f52155b1e8ef31d7656cecbec9a2499b7a68e92e20780ffb39b479abb7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -21140,15 +21380,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"content-disposition@npm:0.5.4":
|
||||
version: 0.5.4
|
||||
resolution: "content-disposition@npm:0.5.4"
|
||||
dependencies:
|
||||
safe-buffer: "npm:5.2.1"
|
||||
checksum: 10/b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"content-disposition@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "content-disposition@npm:1.0.0"
|
||||
@@ -21158,6 +21389,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"content-disposition@npm:~0.5.4":
|
||||
version: 0.5.4
|
||||
resolution: "content-disposition@npm:0.5.4"
|
||||
dependencies:
|
||||
safe-buffer: "npm:5.2.1"
|
||||
checksum: 10/b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5":
|
||||
version: 1.0.5
|
||||
resolution: "content-type@npm:1.0.5"
|
||||
@@ -21249,14 +21489,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cookie@npm:0.7.1":
|
||||
version: 0.7.1
|
||||
resolution: "cookie@npm:0.7.1"
|
||||
checksum: 10/aec6a6aa0781761bf55d60447d6be08861d381136a0fe94aa084fddd4f0300faa2b064df490c6798adfa1ebaef9e0af9b08a189c823e0811b8b313b3d9a03380
|
||||
"cookie-signature@npm:~1.0.6":
|
||||
version: 1.0.7
|
||||
resolution: "cookie-signature@npm:1.0.7"
|
||||
checksum: 10/1a62808cd30d15fb43b70e19829b64d04b0802d8ef00275b57d152de4ae6a3208ca05c197b6668d104c4d9de389e53ccc2d3bc6bcaaffd9602461417d8c40710
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:~0.7.2":
|
||||
"cookie@npm:0.7.2, cookie@npm:^0.7.1, cookie@npm:~0.7.1, cookie@npm:~0.7.2":
|
||||
version: 0.7.2
|
||||
resolution: "cookie@npm:0.7.2"
|
||||
checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f
|
||||
@@ -22470,7 +22710,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"destroy@npm:1.2.0":
|
||||
"destroy@npm:1.2.0, destroy@npm:~1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "destroy@npm:1.2.0"
|
||||
checksum: 10/0acb300b7478a08b92d810ab229d5afe0d2f4399272045ab22affa0d99dbaf12637659411530a6fcd597a9bdac718fc94373a61a95b4651bbc7b83684a565e38
|
||||
@@ -23133,13 +23373,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"encodeurl@npm:~1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "encodeurl@npm:1.0.2"
|
||||
checksum: 10/e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"encoding@npm:^0.1.13":
|
||||
version: 0.1.13
|
||||
resolution: "encoding@npm:0.1.13"
|
||||
@@ -24075,42 +24308,42 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"express@npm:^4.21.1, express@npm:^4.21.2":
|
||||
version: 4.21.2
|
||||
resolution: "express@npm:4.21.2"
|
||||
"express@npm:^4.21.1, express@npm:^4.21.2, express@npm:^4.22.1":
|
||||
version: 4.22.1
|
||||
resolution: "express@npm:4.22.1"
|
||||
dependencies:
|
||||
accepts: "npm:~1.3.8"
|
||||
array-flatten: "npm:1.1.1"
|
||||
body-parser: "npm:1.20.3"
|
||||
content-disposition: "npm:0.5.4"
|
||||
body-parser: "npm:~1.20.3"
|
||||
content-disposition: "npm:~0.5.4"
|
||||
content-type: "npm:~1.0.4"
|
||||
cookie: "npm:0.7.1"
|
||||
cookie-signature: "npm:1.0.6"
|
||||
cookie: "npm:~0.7.1"
|
||||
cookie-signature: "npm:~1.0.6"
|
||||
debug: "npm:2.6.9"
|
||||
depd: "npm:2.0.0"
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
etag: "npm:~1.8.1"
|
||||
finalhandler: "npm:1.3.1"
|
||||
fresh: "npm:0.5.2"
|
||||
http-errors: "npm:2.0.0"
|
||||
finalhandler: "npm:~1.3.1"
|
||||
fresh: "npm:~0.5.2"
|
||||
http-errors: "npm:~2.0.0"
|
||||
merge-descriptors: "npm:1.0.3"
|
||||
methods: "npm:~1.1.2"
|
||||
on-finished: "npm:2.4.1"
|
||||
on-finished: "npm:~2.4.1"
|
||||
parseurl: "npm:~1.3.3"
|
||||
path-to-regexp: "npm:0.1.12"
|
||||
path-to-regexp: "npm:~0.1.12"
|
||||
proxy-addr: "npm:~2.0.7"
|
||||
qs: "npm:6.13.0"
|
||||
qs: "npm:~6.14.0"
|
||||
range-parser: "npm:~1.2.1"
|
||||
safe-buffer: "npm:5.2.1"
|
||||
send: "npm:0.19.0"
|
||||
serve-static: "npm:1.16.2"
|
||||
send: "npm:~0.19.0"
|
||||
serve-static: "npm:~1.16.2"
|
||||
setprototypeof: "npm:1.2.0"
|
||||
statuses: "npm:2.0.1"
|
||||
statuses: "npm:~2.0.1"
|
||||
type-is: "npm:~1.6.18"
|
||||
utils-merge: "npm:1.0.1"
|
||||
vary: "npm:~1.1.2"
|
||||
checksum: 10/34571c442fc8c9f2c4b442d2faa10ea1175cf8559237fc6a278f5ce6254a8ffdbeb9a15d99f77c1a9f2926ab183e3b7ba560e3261f1ad4149799e3412ab66bd1
|
||||
checksum: 10/f33c1bd0c7d36e2a1f18de9cdc176469d32f68e20258d2941b8d296ab9a4fd9011872c246391bf87714f009fac5114c832ec5ac65cbee39421f1258801eb8470
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -24483,21 +24716,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"finalhandler@npm:1.3.1":
|
||||
version: 1.3.1
|
||||
resolution: "finalhandler@npm:1.3.1"
|
||||
dependencies:
|
||||
debug: "npm:2.6.9"
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
on-finished: "npm:2.4.1"
|
||||
parseurl: "npm:~1.3.3"
|
||||
statuses: "npm:2.0.1"
|
||||
unpipe: "npm:~1.0.0"
|
||||
checksum: 10/4babe72969b7373b5842bc9f75c3a641a4d0f8eb53af6b89fa714d4460ce03fb92b28de751d12ba415e96e7e02870c436d67412120555e2b382640535697305b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"finalhandler@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "finalhandler@npm:2.1.0"
|
||||
@@ -24512,6 +24730,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"finalhandler@npm:~1.3.1":
|
||||
version: 1.3.2
|
||||
resolution: "finalhandler@npm:1.3.2"
|
||||
dependencies:
|
||||
debug: "npm:2.6.9"
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
on-finished: "npm:~2.4.1"
|
||||
parseurl: "npm:~1.3.3"
|
||||
statuses: "npm:~2.0.2"
|
||||
unpipe: "npm:~1.0.0"
|
||||
checksum: 10/6cb4f9f80eaeb5a0fac4fdbd27a65d39271f040a0034df16556d896bfd855fd42f09da886781b3102117ea8fceba97b903c1f8b08df1fb5740576d5e0f481eed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"find-cache-dir@npm:^3.3.2":
|
||||
version: 3.3.2
|
||||
resolution: "find-cache-dir@npm:3.3.2"
|
||||
@@ -24725,13 +24958,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fresh@npm:0.5.2":
|
||||
version: 0.5.2
|
||||
resolution: "fresh@npm:0.5.2"
|
||||
checksum: 10/64c88e489b5d08e2f29664eb3c79c705ff9a8eb15d3e597198ef76546d4ade295897a44abb0abd2700e7ef784b2e3cbf1161e4fbf16f59129193fd1030d16da1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fresh@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "fresh@npm:2.0.0"
|
||||
@@ -24739,6 +24965,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fresh@npm:~0.5.2":
|
||||
version: 0.5.2
|
||||
resolution: "fresh@npm:0.5.2"
|
||||
checksum: 10/64c88e489b5d08e2f29664eb3c79c705ff9a8eb15d3e597198ef76546d4ade295897a44abb0abd2700e7ef784b2e3cbf1161e4fbf16f59129193fd1030d16da1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fromentries@npm:^1.3.2":
|
||||
version: 1.3.2
|
||||
resolution: "fromentries@npm:1.3.2"
|
||||
@@ -25985,20 +26218,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"http-errors@npm:2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "http-errors@npm:2.0.0"
|
||||
dependencies:
|
||||
depd: "npm:2.0.0"
|
||||
inherits: "npm:2.0.4"
|
||||
setprototypeof: "npm:1.2.0"
|
||||
statuses: "npm:2.0.1"
|
||||
toidentifier: "npm:1.0.1"
|
||||
checksum: 10/0e7f76ee8ff8a33e58a3281a469815b893c41357378f408be8f6d4aa7d1efafb0da064625518e7078381b6a92325949b119dc38fcb30bdbc4e3a35f78c44c439
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"http-errors@npm:^2.0.0, http-errors@npm:~2.0.1":
|
||||
"http-errors@npm:^2.0.0, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "http-errors@npm:2.0.1"
|
||||
dependencies:
|
||||
@@ -26051,7 +26271,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"http-proxy-middleware@npm:^2.0.7":
|
||||
"http-proxy-middleware@npm:^2.0.7, http-proxy-middleware@npm:^2.0.9":
|
||||
version: 2.0.9
|
||||
resolution: "http-proxy-middleware@npm:2.0.9"
|
||||
dependencies:
|
||||
@@ -26196,15 +26416,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24":
|
||||
version: 0.4.24
|
||||
resolution: "iconv-lite@npm:0.4.24"
|
||||
dependencies:
|
||||
safer-buffer: "npm:>= 2.1.2 < 3"
|
||||
checksum: 10/6d3a2dac6e5d1fb126d25645c25c3a1209f70cceecc68b8ef51ae0da3cdc078c151fade7524a30b12a3094926336831fca09c666ef55b37e2c69638b5d6bd2e3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"iconv-lite@npm:0.6, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3":
|
||||
version: 0.6.3
|
||||
resolution: "iconv-lite@npm:0.6.3"
|
||||
@@ -26214,6 +26425,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24":
|
||||
version: 0.4.24
|
||||
resolution: "iconv-lite@npm:0.4.24"
|
||||
dependencies:
|
||||
safer-buffer: "npm:>= 2.1.2 < 3"
|
||||
checksum: 10/6d3a2dac6e5d1fb126d25645c25c3a1209f70cceecc68b8ef51ae0da3cdc078c151fade7524a30b12a3094926336831fca09c666ef55b37e2c69638b5d6bd2e3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0":
|
||||
version: 0.7.2
|
||||
resolution: "iconv-lite@npm:0.7.2"
|
||||
@@ -26401,7 +26621,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4":
|
||||
"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "inherits@npm:2.0.4"
|
||||
checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521
|
||||
@@ -30735,7 +30955,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"on-finished@npm:2.4.1, on-finished@npm:^2.4.1":
|
||||
"on-finished@npm:^2.4.1, on-finished@npm:~2.4.1":
|
||||
version: 2.4.1
|
||||
resolution: "on-finished@npm:2.4.1"
|
||||
dependencies:
|
||||
@@ -31406,13 +31626,6 @@ __metadata:
|
||||
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
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-to-regexp@npm:3.3.0":
|
||||
version: 3.3.0
|
||||
resolution: "path-to-regexp@npm:3.3.0"
|
||||
@@ -31441,6 +31654,13 @@ __metadata:
|
||||
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
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-type@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "path-type@npm:2.0.0"
|
||||
@@ -32457,21 +32677,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qs@npm:6.13.0":
|
||||
version: 6.13.0
|
||||
resolution: "qs@npm:6.13.0"
|
||||
dependencies:
|
||||
side-channel: "npm:^1.0.6"
|
||||
checksum: 10/f548b376e685553d12e461409f0d6e5c59ec7c7d76f308e2a888fd9db3e0c5e89902bedd0754db3a9038eda5f27da2331a6f019c8517dc5e0a16b3c9a6e9cef8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.7.0":
|
||||
version: 6.14.1
|
||||
resolution: "qs@npm:6.14.1"
|
||||
"qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.7.0, qs@npm:~6.14.0":
|
||||
version: 6.14.2
|
||||
resolution: "qs@npm:6.14.2"
|
||||
dependencies:
|
||||
side-channel: "npm:^1.1.0"
|
||||
checksum: 10/34b5ab00a910df432d55180ef39c1d1375e550f098b5ec153b41787f1a6a6d7e5f9495593c3b112b77dbc6709d0ae18e55b82847a4c2bbbb0de1e8ccbb1794c5
|
||||
checksum: 10/682933a85bb4b7bd0d66e13c0a40d9e612b5e4bcc2cb9238f711a9368cd22d91654097a74fff93551e58146db282c56ac094957dfdc60ce64ea72c3c9d7779ac
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -32573,18 +32784,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"raw-body@npm:2.5.2":
|
||||
version: 2.5.2
|
||||
resolution: "raw-body@npm:2.5.2"
|
||||
dependencies:
|
||||
bytes: "npm:3.1.2"
|
||||
http-errors: "npm:2.0.0"
|
||||
iconv-lite: "npm:0.4.24"
|
||||
unpipe: "npm:1.0.0"
|
||||
checksum: 10/863b5171e140546a4d99f349b720abac4410338e23df5e409cfcc3752538c9caf947ce382c89129ba976f71894bd38b5806c774edac35ebf168d02aa1ac11a95
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"raw-body@npm:^3.0.0, raw-body@npm:^3.0.1":
|
||||
version: 3.0.2
|
||||
resolution: "raw-body@npm:3.0.2"
|
||||
@@ -32597,6 +32796,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"raw-body@npm:~2.5.3":
|
||||
version: 2.5.3
|
||||
resolution: "raw-body@npm:2.5.3"
|
||||
dependencies:
|
||||
bytes: "npm:~3.1.2"
|
||||
http-errors: "npm:~2.0.1"
|
||||
iconv-lite: "npm:~0.4.24"
|
||||
unpipe: "npm:~1.0.0"
|
||||
checksum: 10/f35759fe5a6548e7c529121ead1de4dd163f899749a5896c42e278479df2d9d7f98b5bb17312737c03617765e5a1433e586f717616e5cfbebc13b4738b820601
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rc9@npm:^2.1.2":
|
||||
version: 2.1.2
|
||||
resolution: "rc9@npm:2.1.2"
|
||||
@@ -34159,27 +34370,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"send@npm:0.19.0":
|
||||
version: 0.19.0
|
||||
resolution: "send@npm:0.19.0"
|
||||
dependencies:
|
||||
debug: "npm:2.6.9"
|
||||
depd: "npm:2.0.0"
|
||||
destroy: "npm:1.2.0"
|
||||
encodeurl: "npm:~1.0.2"
|
||||
escape-html: "npm:~1.0.3"
|
||||
etag: "npm:~1.8.1"
|
||||
fresh: "npm:0.5.2"
|
||||
http-errors: "npm:2.0.0"
|
||||
mime: "npm:1.6.0"
|
||||
ms: "npm:2.1.3"
|
||||
on-finished: "npm:2.4.1"
|
||||
range-parser: "npm:~1.2.1"
|
||||
statuses: "npm:2.0.1"
|
||||
checksum: 10/1f6064dea0ae4cbe4878437aedc9270c33f2a6650a77b56a16b62d057527f2766d96ee282997dd53ec0339082f2aad935bc7d989b46b48c82fc610800dc3a1d0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"send@npm:^1.1.0, send@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "send@npm:1.2.0"
|
||||
@@ -34199,6 +34389,27 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"send@npm:~0.19.0, send@npm:~0.19.1":
|
||||
version: 0.19.2
|
||||
resolution: "send@npm:0.19.2"
|
||||
dependencies:
|
||||
debug: "npm:2.6.9"
|
||||
depd: "npm:2.0.0"
|
||||
destroy: "npm:1.2.0"
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
etag: "npm:~1.8.1"
|
||||
fresh: "npm:~0.5.2"
|
||||
http-errors: "npm:~2.0.1"
|
||||
mime: "npm:1.6.0"
|
||||
ms: "npm:2.1.3"
|
||||
on-finished: "npm:~2.4.1"
|
||||
range-parser: "npm:~1.2.1"
|
||||
statuses: "npm:~2.0.2"
|
||||
checksum: 10/e932a592f62c58560b608a402d52333a8ae98a5ada076feb5db1d03adaa77c3ca32a7befa1c4fd6dedc186e88f342725b0cb4b3d86835eaf834688b259bef18d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sentence-case@npm:^3.0.4":
|
||||
version: 3.0.4
|
||||
resolution: "sentence-case@npm:3.0.4"
|
||||
@@ -34258,18 +34469,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"serve-static@npm:1.16.2":
|
||||
version: 1.16.2
|
||||
resolution: "serve-static@npm:1.16.2"
|
||||
dependencies:
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
parseurl: "npm:~1.3.3"
|
||||
send: "npm:0.19.0"
|
||||
checksum: 10/7fa9d9c68090f6289976b34fc13c50ac8cd7f16ae6bce08d16459300f7fc61fbc2d7ebfa02884c073ec9d6ab9e7e704c89561882bbe338e99fcacb2912fde737
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"serve-static@npm:^2.2.0":
|
||||
version: 2.2.0
|
||||
resolution: "serve-static@npm:2.2.0"
|
||||
@@ -34282,6 +34481,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"serve-static@npm:~1.16.2":
|
||||
version: 1.16.3
|
||||
resolution: "serve-static@npm:1.16.3"
|
||||
dependencies:
|
||||
encodeurl: "npm:~2.0.0"
|
||||
escape-html: "npm:~1.0.3"
|
||||
parseurl: "npm:~1.3.3"
|
||||
send: "npm:~0.19.1"
|
||||
checksum: 10/149d6718dd9e53166784d0a65535e21a7c01249d9c51f57224b786a7306354c6807e7811a9f6c143b45c863b1524721fca2f52b5c81a8b5194e3dde034a03b9c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"serve@npm:^14.2.4":
|
||||
version: 14.2.4
|
||||
resolution: "serve@npm:14.2.4"
|
||||
@@ -35143,13 +35354,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"statuses@npm:2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "statuses@npm:2.0.1"
|
||||
checksum: 10/18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"statuses@npm:>= 1.4.0 < 2":
|
||||
version: 1.5.0
|
||||
resolution: "statuses@npm:1.5.0"
|
||||
@@ -35157,7 +35361,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"statuses@npm:^2.0.1, statuses@npm:^2.0.2, statuses@npm:~2.0.2":
|
||||
"statuses@npm:^2.0.1, statuses@npm:^2.0.2, statuses@npm:~2.0.1, statuses@npm:~2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "statuses@npm:2.0.2"
|
||||
checksum: 10/6927feb50c2a75b2a4caab2c565491f7a93ad3d8dbad7b1398d52359e9243a20e2ebe35e33726dee945125ef7a515e9097d8a1b910ba2bbd818265a2f6c39879
|
||||
@@ -36120,7 +36324,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"toidentifier@npm:1.0.1, toidentifier@npm:~1.0.1":
|
||||
"toidentifier@npm:~1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "toidentifier@npm:1.0.1"
|
||||
checksum: 10/952c29e2a85d7123239b5cfdd889a0dde47ab0497f0913d70588f19c53f7e0b5327c95f4651e413c74b785147f9637b17410ac8c846d5d4a20a5a33eb6dc3a45
|
||||
@@ -36787,7 +36991,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"unpipe@npm:1.0.0, unpipe@npm:~1.0.0":
|
||||
"unpipe@npm:~1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "unpipe@npm:1.0.0"
|
||||
checksum: 10/4fa18d8d8d977c55cb09715385c203197105e10a6d220087ec819f50cb68870f02942244f1017565484237f1f8c5d3cd413631b1ae104d3096f24fdfde1b4aa2
|
||||
|
||||
Reference in New Issue
Block a user