diff --git a/.eslintignore b/.eslintignore index 55b43acda07..bf61b3f7297 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,6 +4,7 @@ **/config/** **/build/** **/npm/** +!scripts/npm/** **/*.js.flow **/*.d.ts **/playwright*/** diff --git a/.eslintrc.js b/.eslintrc.js index b12491eb8b2..ab5e599fe7f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -51,6 +51,8 @@ module.exports = { // node scripts should be console logging so don't lint against that files: ['scripts/**/*.js'], rules: { + // https://github.com/Stuk/eslint-plugin-header/issues/39 + 'header/header': OFF, 'no-console': OFF, }, }, diff --git a/.flowconfig b/.flowconfig index c37a1b103fb..cb6c16f3d35 100644 --- a/.flowconfig +++ b/.flowconfig @@ -18,95 +18,71 @@ untyped-type-import=error server.max_workers=4 exact_by_default=true +;; [generated-start update-flowconfig] module.name_mapper='^lexical$' -> '/packages/lexical/flow/Lexical.js.flow' - -module.name_mapper='^@lexical/clipboard' -> '/packages/lexical-clipboard/flow/LexicalClipboard.js.flow' -module.name_mapper='^@lexical/devtools-core' -> '/packages/devtools-core/flow/LexicalDevToolsCore.js.flow' -module.name_mapper='^@lexical/list' -> '/packages/lexical-list/flow/LexicalList.js.flow' -module.name_mapper='^@lexical/table' -> '/packages/lexical-table/flow/LexicalTable.js.flow' -module.name_mapper='^@lexical/file' -> '/packages/lexical-file/flow/LexicalFile.js.flow' -module.name_mapper='^@lexical/hashtag' -> '/packages/lexical-hashtag/flow/LexicalHashtag.js.flow' -module.name_mapper='^@lexical/selection' -> '/packages/lexical-selection/flow/LexicalSelection.js.flow' -module.name_mapper='^@lexical/text' -> '/packages/lexical-text/flow/LexicalText.js.flow' -module.name_mapper='^@lexical/offset' -> '/packages/lexical-offset/flow/LexicalOffset.js.flow' -module.name_mapper='^@lexical/history' -> '/packages/lexical-history/flow/LexicalHistory.js.flow' -module.name_mapper='^@lexical/headless' -> '/packages/lexical-headless/flow/LexicalHeadless.js.flow' -module.name_mapper='^@lexical/html' -> '/packages/lexical-html/flow/LexicalHtml.js.flow' -module.name_mapper='^@lexical/utils' -> '/packages/lexical-utils/flow/LexicalUtils.js.flow' -module.name_mapper='^@lexical/code' -> '/packages/lexical-code/flow/LexicalCode.js.flow' -module.name_mapper='^@lexical/plain-text' -> '/packages/lexical-plain-text/flow/LexicalPlainText.js.flow' -module.name_mapper='^@lexical/rich-text' -> '/packages/lexical-rich-text/flow/LexicalRichText.js.flow' -module.name_mapper='^@lexical/dragon' -> '/packages/lexical-dragon/flow/LexicalDragon.js.flow' -module.name_mapper='^@lexical/link' -> '/packages/lexical-link/flow/LexicalLink.js.flow' -module.name_mapper='^@lexical/overflow' -> '/packages/lexical-overflow/flow/LexicalOverflow.js.flow' -module.name_mapper='^@lexical/markdown' -> '/packages/lexical-markdown/flow/LexicalMarkdown.js.flow' -module.name_mapper='^@lexical/mark' -> '/packages/lexical-mark/flow/LexicalMark.js.flow' - -module.name_mapper='^@lexical/react/LexicalComposer' -> '/packages/lexical-react/flow/LexicalComposer.js.flow' -module.name_mapper='^@lexical/react/LexicalComposerContext' -> '/packages/lexical-react/flow/LexicalComposerContext.js.flow' -module.name_mapper='^@lexical/react/LexicalNestedComposer' -> '/packages/lexical-react/flow/LexicalNestedComposer.js.flow' -module.name_mapper='^@lexical/react/LexicalContentEditable' -> '/packages/lexical-react/flow/LexicalContentEditable.js.flow' -module.name_mapper='^@lexical/react/LexicalTreeView' -> '/packages/lexical-react/flow/LexicalTreeView.js.flow' -module.name_mapper='^@lexical/react/LexicalHorizontalRuleNode' -> '/packages/lexical-react/flow/LexicalHorizontalRuleNode.js.flow' -module.name_mapper='^@lexical/react/LexicalHorizontalRulePlugin' -> '/packages/lexical-react/flow/LexicalHorizontalRulePlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalDecoratorBlockNode' -> '/packages/lexical-react/flow/LexicalDecoratorBlockNode.js.flow' -module.name_mapper='^@lexical/react/LexicalBlockWithAlignableContents' -> '/packages/lexical-react/flow/LexicalBlockWithAlignableContents.js.flow' -module.name_mapper='^@lexical/react/useLexicalIsTextContentEmpty' -> '/packages/lexical-react/flow/useLexicalIsTextContentEmpty.js.flow' -module.name_mapper='^@lexical/react/useLexicalNodeSelection' -> '/packages/lexical-react/flow/useLexicalNodeSelection.js.flow' -module.name_mapper='^@lexical/react/useLexicalTextEntity' -> '/packages/lexical-react/flow/useLexicalTextEntity.js.flow' -module.name_mapper='^@lexical/react/useLexicalSubscription' -> '/packages/lexical-react/flow/useLexicalSubscription.js.flow' -module.name_mapper='^@lexical/react/useLexicalEditable' -> '/packages/lexical-react/flow/useLexicalEditable.js.flow' - -# Composer Plugins -module.name_mapper='^@lexical/react/LexicalPlainTextPlugin' -> '/packages/lexical-react/flow/LexicalPlainTextPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalRichTextPlugin' -> '/packages/lexical-react/flow/LexicalRichTextPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalTypeaheadMenuPlugin' -> '/packages/lexical-react/flow/LexicalTypeaheadMenuPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalHistoryPlugin' -> '/packages/lexical-react/flow/LexicalHistoryPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalOnChangePlugin' -> '/packages/lexical-react/flow/LexicalOnChangePlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalHashtagPlugin' -> '/packages/lexical-react/flow/LexicalHashtagPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalErrorBoundary' -> '/packages/lexical-react/flow/LexicalErrorBoundary.js.flow' -module.name_mapper='^@lexical/react/LexicalMarkdownShortcutPlugin' -> '/packages/lexical-react/flow/LexicalMarkdownShortcutPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalAutoFocusPlugin' -> '/packages/lexical-react/flow/LexicalAutoFocusPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalTableOfContents' -> '/packages/lexical-react/flow/LexicalTableOfContents.js.flow' -module.name_mapper='^@lexical/react/LexicalAutoFormatterPlugin' -> '/packages/lexical-react/flow/LexicalAutoFormatterPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalCharacterLimitPlugin' -> '/packages/lexical-react/flow/LexicalCharacterLimitPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalClearEditorPlugin' -> '/packages/lexical-react/flow/LexicalClearEditorPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalClickableLinkPlugin' -> '/packages/lexical-react/flow/LexicalClickableLinkPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalCollaborationContext' -> '/packages/lexical-react/flow/LexicalCollaborationContext.js.flow' -module.name_mapper='^@lexical/react/LexicalCollaborationPlugin' -> '/packages/lexical-react/flow/LexicalCollaborationPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalTablePlugin' -> '/packages/lexical-react/flow/LexicalTablePlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalLinkPlugin' -> '/packages/lexical-react/flow/LexicalLinkPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalAutoLinkPlugin' -> '/packages/lexical-react/flow/LexicalAutoLinkPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalAutoEmbedPlugin' -> '/packages/lexical-react/flow/LexicalAutoEmbedPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalNodeEventPlugin' -> '/packages/lexical-react/flow/LexicalNodeEventPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalTabIndentationPlugin' -> '/packages/lexical-react/flow/LexicalTabIndentationPlugin.js.flow' - -module.name_mapper='^@lexical/react/LexicalListPlugin' -> '/packages/lexical-react/flow/LexicalListPlugin.js.flow' -module.name_mapper='^@lexical/react/LexicalCheckListPlugin' -> '/packages/lexical-react/flow/LexicalCheckListPlugin.js.flow' - -module.name_mapper='^@lexical/dragon/LexicalDragon' -> '/packages/lexical-dragon/flow/LexicalDragon.js.flow' -module.name_mapper='^@lexical/history/LexicalHistory' -> '/packages/lexical-history/flow/LexicalHistory.js.flow' -module.name_mapper='^@lexical/link/LexicalLink' -> '/packages/lexical-link/flow/LexicalLink.js.flow' -module.name_mapper='^@lexical/markdown/LexicalMarkdown' -> '/packages/lexical-markdown/flow/LexicalMarkdown.js.flow' -module.name_mapper='^@lexical/headless/LexicalHeadless' -> '/packages/lexical-markdown/flow/LexicalHeadless.js.flow' -module.name_mapper='^@lexical/offset/LexicalOffset' -> '/packages/lexical-offset/flow/LexicalOffset.js.flow' -module.name_mapper='^@lexical/overflow/LexicalOverflow' -> '/packages/lexical-overflow/flow/LexicalOverflow.js.flow' -module.name_mapper='^@lexical/plain-text/LexicalPlainText' -> '/packages/lexical-plain-text/flow/LexicalPlainText.js.flow' -module.name_mapper='^@lexical/rich-text/LexicalRichText' -> '/packages/lexical-rich-text/flow/LexicalRichText.js.flow' -module.name_mapper='^@lexical/selection/LexicalSelection' -> '/packages/lexical-selection/flow/LexicalSelection.js.flow' -module.name_mapper='^@lexical/text/LexicalText' -> '/packages/lexical-text/flow/LexicalText.js.flow' -module.name_mapper='^@lexical/utils/LexicalUtils' -> '/packages/lexical-utils/flow/LexicalUtils.js.flow' - +module.name_mapper='^@lexical/clipboard$' -> '/packages/lexical-clipboard/flow/LexicalClipboard.js.flow' +module.name_mapper='^@lexical/code$' -> '/packages/lexical-code/flow/LexicalCode.js.flow' +module.name_mapper='^@lexical/devtools-core$' -> '/packages/lexical-devtools-core/flow/LexicalDevtoolsCore.js.flow' +module.name_mapper='^@lexical/dragon$' -> '/packages/lexical-dragon/flow/LexicalDragon.js.flow' +module.name_mapper='^@lexical/file$' -> '/packages/lexical-file/flow/LexicalFile.js.flow' +module.name_mapper='^@lexical/hashtag$' -> '/packages/lexical-hashtag/flow/LexicalHashtag.js.flow' +module.name_mapper='^@lexical/headless$' -> '/packages/lexical-headless/flow/LexicalHeadless.js.flow' +module.name_mapper='^@lexical/history$' -> '/packages/lexical-history/flow/LexicalHistory.js.flow' +module.name_mapper='^@lexical/html$' -> '/packages/lexical-html/flow/LexicalHtml.js.flow' +module.name_mapper='^@lexical/link$' -> '/packages/lexical-link/flow/LexicalLink.js.flow' +module.name_mapper='^@lexical/list$' -> '/packages/lexical-list/flow/LexicalList.js.flow' +module.name_mapper='^@lexical/mark$' -> '/packages/lexical-mark/flow/LexicalMark.js.flow' +module.name_mapper='^@lexical/markdown$' -> '/packages/lexical-markdown/flow/LexicalMarkdown.js.flow' +module.name_mapper='^@lexical/offset$' -> '/packages/lexical-offset/flow/LexicalOffset.js.flow' +module.name_mapper='^@lexical/overflow$' -> '/packages/lexical-overflow/flow/LexicalOverflow.js.flow' +module.name_mapper='^@lexical/plain-text$' -> '/packages/lexical-plain-text/flow/LexicalPlainText.js.flow' +module.name_mapper='^@lexical/react/LexicalAutoEmbedPlugin$' -> '/packages/lexical-react/flow/LexicalAutoEmbedPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalAutoFocusPlugin$' -> '/packages/lexical-react/flow/LexicalAutoFocusPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalAutoLinkPlugin$' -> '/packages/lexical-react/flow/LexicalAutoLinkPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalBlockWithAlignableContents$' -> '/packages/lexical-react/flow/LexicalBlockWithAlignableContents.js.flow' +module.name_mapper='^@lexical/react/LexicalCharacterLimitPlugin$' -> '/packages/lexical-react/flow/LexicalCharacterLimitPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalCheckListPlugin$' -> '/packages/lexical-react/flow/LexicalCheckListPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalClearEditorPlugin$' -> '/packages/lexical-react/flow/LexicalClearEditorPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalClickableLinkPlugin$' -> '/packages/lexical-react/flow/LexicalClickableLinkPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalCollaborationContext$' -> '/packages/lexical-react/flow/LexicalCollaborationContext.js.flow' +module.name_mapper='^@lexical/react/LexicalCollaborationPlugin$' -> '/packages/lexical-react/flow/LexicalCollaborationPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalComposer$' -> '/packages/lexical-react/flow/LexicalComposer.js.flow' +module.name_mapper='^@lexical/react/LexicalComposerContext$' -> '/packages/lexical-react/flow/LexicalComposerContext.js.flow' +module.name_mapper='^@lexical/react/LexicalContentEditable$' -> '/packages/lexical-react/flow/LexicalContentEditable.js.flow' +module.name_mapper='^@lexical/react/LexicalContextMenuPlugin$' -> '/packages/lexical-react/flow/LexicalContextMenuPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalDecoratorBlockNode$' -> '/packages/lexical-react/flow/LexicalDecoratorBlockNode.js.flow' +module.name_mapper='^@lexical/react/LexicalEditorRefPlugin$' -> '/packages/lexical-react/flow/LexicalEditorRefPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalErrorBoundary$' -> '/packages/lexical-react/flow/LexicalErrorBoundary.js.flow' +module.name_mapper='^@lexical/react/LexicalHashtagPlugin$' -> '/packages/lexical-react/flow/LexicalHashtagPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalHistoryPlugin$' -> '/packages/lexical-react/flow/LexicalHistoryPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalHorizontalRuleNode$' -> '/packages/lexical-react/flow/LexicalHorizontalRuleNode.js.flow' +module.name_mapper='^@lexical/react/LexicalHorizontalRulePlugin$' -> '/packages/lexical-react/flow/LexicalHorizontalRulePlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalLinkPlugin$' -> '/packages/lexical-react/flow/LexicalLinkPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalListPlugin$' -> '/packages/lexical-react/flow/LexicalListPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalMarkdownShortcutPlugin$' -> '/packages/lexical-react/flow/LexicalMarkdownShortcutPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalNestedComposer$' -> '/packages/lexical-react/flow/LexicalNestedComposer.js.flow' +module.name_mapper='^@lexical/react/LexicalNodeEventPlugin$' -> '/packages/lexical-react/flow/LexicalNodeEventPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalNodeMenuPlugin$' -> '/packages/lexical-react/flow/LexicalNodeMenuPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalOnChangePlugin$' -> '/packages/lexical-react/flow/LexicalOnChangePlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalPlainTextPlugin$' -> '/packages/lexical-react/flow/LexicalPlainTextPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalRichTextPlugin$' -> '/packages/lexical-react/flow/LexicalRichTextPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalTabIndentationPlugin$' -> '/packages/lexical-react/flow/LexicalTabIndentationPlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalTableOfContents$' -> '/packages/lexical-react/flow/LexicalTableOfContents.js.flow' +module.name_mapper='^@lexical/react/LexicalTablePlugin$' -> '/packages/lexical-react/flow/LexicalTablePlugin.js.flow' +module.name_mapper='^@lexical/react/LexicalTreeView$' -> '/packages/lexical-react/flow/LexicalTreeView.js.flow' +module.name_mapper='^@lexical/react/LexicalTypeaheadMenuPlugin$' -> '/packages/lexical-react/flow/LexicalTypeaheadMenuPlugin.js.flow' +module.name_mapper='^@lexical/react/useLexicalEditable$' -> '/packages/lexical-react/flow/useLexicalEditable.js.flow' +module.name_mapper='^@lexical/react/useLexicalIsTextContentEmpty$' -> '/packages/lexical-react/flow/useLexicalIsTextContentEmpty.js.flow' +module.name_mapper='^@lexical/react/useLexicalNodeSelection$' -> '/packages/lexical-react/flow/useLexicalNodeSelection.js.flow' +module.name_mapper='^@lexical/react/useLexicalSubscription$' -> '/packages/lexical-react/flow/useLexicalSubscription.js.flow' +module.name_mapper='^@lexical/react/useLexicalTextEntity$' -> '/packages/lexical-react/flow/useLexicalTextEntity.js.flow' +module.name_mapper='^@lexical/rich-text$' -> '/packages/lexical-rich-text/flow/LexicalRichText.js.flow' +module.name_mapper='^@lexical/selection$' -> '/packages/lexical-selection/flow/LexicalSelection.js.flow' +module.name_mapper='^@lexical/table$' -> '/packages/lexical-table/flow/LexicalTable.js.flow' +module.name_mapper='^@lexical/text$' -> '/packages/lexical-text/flow/LexicalText.js.flow' +module.name_mapper='^@lexical/utils$' -> '/packages/lexical-utils/flow/LexicalUtils.js.flow' module.name_mapper='^@lexical/yjs$' -> '/packages/lexical-yjs/flow/LexicalYjs.js.flow' - -module.name_mapper='^shared/simpleDiffWithCursor' -> '/packages/shared/src/simpleDiffWithCursor.js' -module.name_mapper='^shared/invariant' -> '/packages/shared/src/invariant.js' -module.name_mapper='^shared/normalizeClassNames' -> '/packages/shared/src/normalizeClassNames.js' -module.name_mapper='^shared/warnOnlyOnce' -> '/packages/shared/src/warnOnlyOnce.js' -module.name_mapper='^shared/environment' -> '/packages/shared/src/environment.js' -module.name_mapper='^shared/useLayoutEffect' -> '/packages/shared/src/useLayoutEffect.js' -module.name_mapper='^shared/canUseDOM' -> '/packages/shared/src/canUseDOM.js' -module.name_mapper='^shared/caretFromPoint' -> '/packages/shared/src/caretFromPoint.js' +;; [generated-end update-flowconfig] munge_underscores=false diff --git a/.gitignore b/.gitignore index 875036ec0e9..1168f09509b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ node_modules base-build build -build coverage dist npm diff --git a/.prettierignore b/.prettierignore index 97fbe5bec01..0832734b4f9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -9,6 +9,7 @@ packages/playwright packages/playwright-core packages/**/vite.config.js packages/**/vite.prod.config.js +packages/lexical-website/docs/api **/*.md **/*.js.flow **/node_modules diff --git a/.size-limit.js b/.size-limit.js index 257ae9db04e..5b7dde88dad 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -32,24 +32,15 @@ const fs = require('fs-extra'); * Currently this alias map points at the cjs version of the build product, * as that is what was measured previously in #3600. */ +const {packagesManager} = require('./scripts/shared/packagesManager'); const alias = Object.fromEntries( - glob('./packages/*/package.json', {sync: true}).flatMap((fn) => { - const pkg = fs.readJsonSync(fn); - if (!pkg.private) { - return Object.entries(pkg.exports).flatMap(([k, v]) => { - if (k.endsWith('.js')) { - return []; - } - return [ - [ - `${pkg.name}${k.replace(/^\.(\/$)?/, '')}`, - path.resolve(path.dirname(fn), 'dist', v.require.default), - ], - ]; - }); - } - return []; - }), + packagesManager + .getPublicPackages() + .flatMap((pkg) => + pkg + .getNormalizedNpmModuleExportEntries() + .map(([k, v]) => [k, pkg.resolve('dist', v.require.default)]), + ), ); const extendConfig = {resolve: {alias}}; diff --git a/README.md b/README.md index 9390eb81122..a289f203139 100644 --- a/README.md +++ b/README.md @@ -367,6 +367,7 @@ editor.registerUpdateListener(({editorState}) => { - [Concepts](https://lexical.dev/docs/concepts/editor-state) - [How Lexical was designed](https://lexical.dev/docs/design) - [Testing](https://lexical.dev/docs/testing) +- [Maintainers' Guide](https://lexical.dev/docs/maintainers-guide) ## Browser Support diff --git a/examples/react-rich/package.json b/examples/react-rich/package.json index 2cdd4f582a5..65e8cfefa3f 100644 --- a/examples/react-rich/package.json +++ b/examples/react-rich/package.json @@ -15,10 +15,10 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "typescript": "^5.2.2", - "vite": "^5.1.4", - "@vitejs/plugin-react": "^4.2.1", "@types/react": "^18.2.59", - "@types/react-dom": "^18.2.19" + "@types/react-dom": "^18.2.19", + "@vitejs/plugin-react": "^4.2.1", + "typescript": "^5.2.2", + "vite": "^5.1.4" } } diff --git a/jest.config.js b/jest.config.js index 2aa0744776b..57b12d38ccc 100644 --- a/jest.config.js +++ b/jest.config.js @@ -8,10 +8,20 @@ 'use strict'; +const tsconfig = require('./tsconfig.json'); + const common = { modulePathIgnorePatterns: ['/npm'], }; +// Use tsconfig's paths to configure jest's module name mapper +const moduleNameMapper = Object.fromEntries( + Object.entries(tsconfig.compilerOptions.paths).map(([name, [firstPath]]) => [ + `^${name}$`, + firstPath.replace(/^\./, ''), + ]), +); + module.exports = { projects: [ { @@ -20,119 +30,19 @@ module.exports = { globals: { IS_REACT_ACT_ENVIRONMENT: true, __DEV__: true, - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, - }, - moduleNameMapper: { - '^./dist/(.+)': './src/$1', - '^@lexical/clipboard$': - '/packages/lexical-clipboard/src/index.ts', - '^@lexical/code$': '/packages/lexical-code/src/index.ts', - '^@lexical/devtools-core$': - '/packages/lexical-devools-core/src/index.ts', - '^@lexical/dragon$': '/packages/lexical-dragon/src/index.ts', - '^@lexical/file$': '/packages/lexical-file/src/index.ts', - '^@lexical/hashtag$': '/packages/lexical-hashtag/src/index.ts', - '^@lexical/headless$': - '/packages/lexical-headless/src/index.ts', - '^@lexical/history$': '/packages/lexical-history/src/index.ts', - '^@lexical/html$': '/packages/lexical-html/src/index.ts', - '^@lexical/link$': '/packages/lexical-link/src/index.ts', - '^@lexical/list$': '/packages/lexical-list/src/index.ts', - '^@lexical/mark$': '/packages/lexical-mark/src/index.ts', - '^@lexical/markdown$': - '/packages/lexical-markdown/src/index.ts', - '^@lexical/offset$': '/packages/lexical-offset/src/index.ts', - '^@lexical/overflow$': - '/packages/lexical-overflow/src/index.ts', - '^@lexical/plain-text$': - '/packages/lexical-plain-text/src/index.ts', - - '^@lexical/react/LexicalAutoEmbedPlugin$': - '/packages/lexical-react/src/LexicalAutoEmbedPlugin.tsx', - '^@lexical/react/LexicalAutoFocusPlugin$': - '/packages/lexical-react/src/LexicalAutoFocusPlugin.ts', - '^@lexical/react/LexicalAutoLinkPlugin$': - '/packages/lexical-react/src/LexicalAutoLinkPlugin.ts', - '^@lexical/react/LexicalCheckListPlugin$': - '/packages/lexical-react/src/LexicalCheckListPlugin.ts', - '^@lexical/react/LexicalCollaborationContext$': - '/packages/lexical-react/src/LexicalCollaborationContext.ts', - '^@lexical/react/LexicalCollaborationPlugin$': - '/packages/lexical-react/src/LexicalCollaborationPlugin.ts', - '^@lexical/react/LexicalComposer$': - '/packages/lexical-react/src/LexicalComposer.tsx', - '^@lexical/react/LexicalComposerContext$': - '/packages/lexical-react/src/LexicalComposerContext.ts', - '^@lexical/react/LexicalContentEditable$': - '/packages/lexical-react/src/LexicalContentEditable.tsx', - '^@lexical/react/LexicalErrorBoundary$': - '/packages/lexical-react/src/LexicalErrorBoundary.tsx', - '^@lexical/react/LexicalHistoryPlugin$': - '/packages/lexical-react/src/LexicalHistoryPlugin.ts', - '^@lexical/react/LexicalLinkPlugin$': - '/packages/lexical-react/src/LexicalLinkPlugin.ts', - '^@lexical/react/LexicalListPlugin$': - '/packages/lexical-react/src/LexicalListPlugin.ts', - '^@lexical/react/LexicalPlainTextPlugin$': - '/packages/lexical-react/src/LexicalPlainTextPlugin.ts', - '^@lexical/react/LexicalRichTextPlugin$': - '/packages/lexical-react/src/LexicalRichTextPlugin.tsx', - '^@lexical/react/LexicalTabIndentationPlugin$': - '/packages/lexical-react/src/LexicalTabIndentationPlugin.tsx', - '^@lexical/react/LexicalTablePlugin$': - '/packages/lexical-react/src/LexicalTablePlugin.ts', - '^@lexical/react/useLexicalCanShowPlaceholder$': - '/packages/lexical-react/src/useLexicalCanShowPlaceholder.ts', - '^@lexical/react/useLexicalDecorators$': - '/packages/lexical-react/src/useLexicalDecorators.ts', - '^@lexical/react/useLexicalEditable$': - '/packages/lexical-react/src/useLexicalEditable.ts', - '^@lexical/react/useLexicalEditor$': - '/packages/lexical-react/src/useLexicalEditor.ts', - '^@lexical/react/useLexicalSubscription$': - '/packages/lexical-react/src/useLexicalSubscription.ts', - '^@lexical/rich-text$': - '/packages/lexical-rich-text/src/index.ts', - '^@lexical/selection$': - '/packages/lexical-selection/src/index.ts', - '^@lexical/selection/src/__tests__/utils$': - '/packages/lexical-selection/src/__tests__/utils/index.ts', - '^@lexical/table$': '/packages/lexical-table/src/index.ts', - '^@lexical/text$': '/packages/lexical-text/src/index.ts', - '^@lexical/utils$': '/packages/lexical-utils/src/index.ts', - '^@lexical/yjs$': '/packages/lexical-yjs/src/index.ts', - '^@lexical/yjs/src/index$': - '/packages/lexical-yjs/src/index.ts', - '^lexical$': '/packages/lexical/src/index.ts', - '^lexical/src/([^/]+)$': '/packages/lexical/src/$1.ts', - '^lexical/src/__tests__/utils$': - '/packages/lexical/src/__tests__/utils/index.tsx', - '^lexical/src/nodes/([^/]+)$': - '/packages/lexical/src/nodes/$1.ts', - '^shared/canUseDOM$': '/packages/shared/src/canUseDOM.ts', - '^shared/caretFromPoint$': - '/packages/shared/src/caretFromPoint.ts', - '^shared/environment$': '/packages/shared/src/environment.ts', - '^shared/invariant$': '/packages/shared/src/invariant.ts', - '^shared/normalizeClassNames$': - '/packages/shared/src/normalizeClassNames.ts', - '^shared/simpleDiffWithCursor$': - '/packages/shared/src/simpleDiffWithCursor.ts', - '^shared/useLayoutEffect$': - '/packages/shared/src/useLayoutEffect.ts', - '^shared/warnOnlyOnce$': - '/packages/shared/src/warnOnlyOnce.ts', - formatProdErrorMessage: - '/scripts/error-codes/formatProdErrorMessage.js', }, + moduleNameMapper, preset: 'ts-jest', testEnvironment: 'jsdom', testMatch: ['**/__tests__/unit/**/*.test{.ts,.tsx,.js,.jsx}'], transform: { '^.+\\.jsx?$': 'babel-jest', - '^.+\\.tsx$': 'ts-jest', + '^.+\\.tsx?$': [ + 'ts-jest', + { + tsconfig: 'tsconfig.test.json', + }, + ], }, }, { diff --git a/package-lock.json b/package-lock.json index dce725aed4d..1dc03ce094c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,6 @@ "packages/*" ], "dependencies": { - "@types/katex": "^0.14.0", "yjs": "^13.5.42" }, "devDependencies": { @@ -32,6 +31,7 @@ "@size-limit/preset-big-lib": "^11.1.2", "@types/jest": "^29.4.0", "@types/jsdom": "^21.1.6", + "@types/katex": "^0.16.7", "@types/node": "^17.0.31", "@types/prismjs": "^1.26.0", "@types/react": "^18.0.8", @@ -62,10 +62,11 @@ "eslint-plugin-sort-keys-fix": "^1.1.2", "flow-bin": "^0.226.0", "fs-extra": "^10.0.0", - "gen-flow-files": "^0.4.11", "glob": "^7.2.0", "google-closure-compiler": "^20220202.0.0", "gzip-size": "^6.0.0", + "hermes-parser": "^0.20.1", + "hermes-transform": "^0.20.1", "husky": "^7.0.1", "jest": "^29.4.0", "jest-environment-jsdom": "^29.4.0", @@ -74,13 +75,14 @@ "minimist": "^1.2.5", "npm-run-all": "^4.1.5", "prettier": "^2.3.2", + "prettier-plugin-hermes-parser": "^0.20.1", "prettier-plugin-organize-attributes": "^0.0.5", "prettier-plugin-tailwindcss": "^0.4.1", "react-test-renderer": "^17.0.2", "rollup": "^2.75.5", "size-limit": "^11.1.2", "tmp": "^0.2.1", - "ts-jest": "^29.0.0", + "ts-jest": "^29.1.2", "ts-node": "^10.9.1", "typedoc": "^0.25.12", "typescript": "5.1.6" @@ -999,22 +1001,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-throw-expressions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.18.6.tgz", - "integrity": "sha512-WHOrJyhGoGrdtW480L79cF7Iq/gZDZ/z6OqK7mVyFR5I37dTpog/wNgb6hmaM3HYZtULEJl++7VaMWkNZsOcHg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-throw-expressions": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", @@ -1086,12 +1072,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.1.tgz", + "integrity": "sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { "node": ">=6.9.0" @@ -1244,21 +1230,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-throw-expressions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.18.6.tgz", - "integrity": "sha512-rp1CqEZXGv1z1YZ3qYffBH3rhnOxrTwQG8fh2yqulTurwv9zu3Gthfd+niZBLSOi1rY6146TgF+JmVeDXaX4TQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -1533,13 +1504,13 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.18.6.tgz", - "integrity": "sha512-wE0xtA7csz+hw4fKPwxmu5jnzAsXPIO57XnRwzXP3T19jWh1BODnPGoG9xKYwvAwusP7iUktHayRFbMPGtODaQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.1.tgz", + "integrity": "sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-flow": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-flow": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -2293,14 +2264,14 @@ } }, "node_modules/@babel/preset-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz", - "integrity": "sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.1.tgz", + "integrity": "sha512-sWCV2G9pcqZf+JHyv/RyqEIpFypxdCSxWIxQjpdaQxenNog7cN1pr76hg8u0Fz8Qgg0H4ETkGcJnXL8d4j0PPA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-flow-strip-types": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-transform-flow-strip-types": "^7.24.1" }, "engines": { "node": ">=6.9.0" @@ -6606,9 +6577,10 @@ "dev": true }, "node_modules/@types/katex": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz", - "integrity": "sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==" + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "dev": true }, "node_modules/@types/lodash": { "version": "4.14.182", @@ -10307,15 +10279,6 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", @@ -13241,6 +13204,12 @@ "node": ">=0.10.0" } }, + "node_modules/flow-enums-runtime": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", + "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==", + "dev": true + }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -13635,196 +13604,6 @@ "which": "bin/which" } }, - "node_modules/gen-flow-files": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/gen-flow-files/-/gen-flow-files-0.4.11.tgz", - "integrity": "sha512-88WjoL6gaxTaJtSal6Nsw9LerVKRVjQEAJy330VOmCS1k+lu2h1HJEJyU9LhviaphZBNG088j6JigA6YiP0xGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@babel/generator": "^7.7.4", - "@babel/parser": "^7.7.5", - "@babel/plugin-proposal-throw-expressions": "^7.7.4", - "@babel/plugin-syntax-flow": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "glob": "^7.1.6", - "mkdirp": "^0.5.1", - "yargs": "^15.0.2" - }, - "bin": { - "gen-flow-files": "bin/gen-flow-files.js" - } - }, - "node_modules/gen-flow-files/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/gen-flow-files/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/gen-flow-files/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/gen-flow-files/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/gen-flow-files/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gen-flow-files/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gen-flow-files/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gen-flow-files/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gen-flow-files/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/gen-flow-files/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/gen-flow-files/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gen-flow-files/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/gen-flow-files/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/gen-flow-files/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -14555,6 +14334,50 @@ "he": "bin/he" } }, + "node_modules/hermes-eslint": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-eslint/-/hermes-eslint-0.20.1.tgz", + "integrity": "sha512-EhdvFV6RkPIJvbqN8oqFZO1oF4NlPWMjhMjCWkUJX1YL1MZMfkF7nSdx6RKTq6xK17yo+Bgv88L21xuH9GtRpw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "hermes-estree": "0.20.1", + "hermes-parser": "0.20.1" + } + }, + "node_modules/hermes-estree": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz", + "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==", + "dev": true + }, + "node_modules/hermes-parser": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz", + "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==", + "dev": true, + "dependencies": { + "hermes-estree": "0.20.1" + } + }, + "node_modules/hermes-transform": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-transform/-/hermes-transform-0.20.1.tgz", + "integrity": "sha512-gpetyzAQvuLXVWIk8/I2A/ei/5+o8eT+QuSGd8FcWpXoYxVkYjVKLVNE9xKLsEkk2wQ1tXODY5OeOZoaz9jL7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "esquery": "^1.4.0", + "flow-enums-runtime": "^0.0.6", + "hermes-eslint": "0.20.1", + "hermes-estree": "0.20.1", + "hermes-parser": "0.20.1" + }, + "peerDependencies": { + "prettier": "^3.0.0 || ^2.7.1", + "prettier-plugin-hermes-parser": "0.20.1" + } + }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -21161,6 +20984,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, + "optional": true, "dependencies": { "minimist": "^1.2.6" }, @@ -22652,9 +22476,9 @@ } }, "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, "engines": { "node": ">= 6" @@ -23582,6 +23406,20 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-plugin-hermes-parser": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-hermes-parser/-/prettier-plugin-hermes-parser-0.20.1.tgz", + "integrity": "sha512-T6dfa1++ckTxd3MbLxS6sTv1T3yvTu1drahNt3g34hyCzSwYTKTByocLyhd1A9j9uCUlIPD+ogum7+i1h3+CEw==", + "dev": true, + "dependencies": { + "hermes-estree": "0.20.1", + "hermes-parser": "0.20.1", + "prettier-plugin-hermes-parser": "0.20.1" + }, + "peerDependencies": { + "prettier": "^3.0.0 || ^2.7.1" + } + }, "node_modules/prettier-plugin-organize-attributes": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/prettier-plugin-organize-attributes/-/prettier-plugin-organize-attributes-0.0.5.tgz", @@ -25431,12 +25269,6 @@ "node": "*" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "node_modules/requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -26130,12 +25962,6 @@ "node": ">= 0.8.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, "node_modules/set-value": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", @@ -27733,9 +27559,9 @@ "dev": true }, "node_modules/ts-jest": { - "version": "29.0.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", - "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", "dev": true, "dependencies": { "bs-logger": "0.x", @@ -27744,21 +27570,21 @@ "json5": "^2.2.3", "lodash.memoize": "4.x", "make-error": "1.x", - "semver": "7.x", + "semver": "^7.5.3", "yargs-parser": "^21.0.1" }, "bin": { "ts-jest": "cli.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", "@jest/types": "^29.0.0", "babel-jest": "^29.0.0", "jest": "^29.0.0", - "typescript": ">=4.3" + "typescript": ">=4.3 <6" }, "peerDependenciesMeta": { "@babel/core": { @@ -29693,12 +29519,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, "node_modules/widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -31342,7 +31162,7 @@ }, "packages/lexical-devtools": { "name": "@lexical/devtools", - "version": "0.0.0", + "version": "0.14.3", "hasInstallScript": true, "dependencies": { "@eduardoac-skimlinks/webext-redux": "3.0.1-release-candidate", @@ -31352,12 +31172,12 @@ "zustand": "^4.5.1" }, "devDependencies": { - "@lexical/devtools-core": "0.14.2", + "@lexical/devtools-core": "0.14.3", "@rollup/plugin-babel": "^6.0.4", "@types/react": "^18.2.46", "@types/react-dom": "^18.2.18", "@vitejs/plugin-react": "^4.2.1", - "lexical": "0.14.2", + "lexical": "0.14.3", "typescript": "^5.3.3", "vite": "^5.2.2", "wxt": "^0.17.0" @@ -31365,103 +31185,21 @@ }, "packages/lexical-devtools-core": { "name": "@lexical/devtools-core", - "version": "0.14.2", + "version": "0.14.3", "license": "MIT", "dependencies": { - "@lexical/html": "0.14.2", - "@lexical/link": "0.14.2", - "@lexical/mark": "0.14.2", - "@lexical/table": "0.14.2", - "@lexical/utils": "0.14.2", - "lexical": "0.14.2" + "@lexical/html": "0.14.3", + "@lexical/link": "0.14.3", + "@lexical/mark": "0.14.3", + "@lexical/table": "0.14.3", + "@lexical/utils": "0.14.3", + "lexical": "0.14.3" }, "peerDependencies": { "react": ">=17.x", "react-dom": ">=17.x" } }, - "packages/lexical-devtools-core/node_modules/@lexical/html": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.14.2.tgz", - "integrity": "sha512-5uL0wSfS9H5/HNeCM4QaJMekoL1w4D81361RlC2ppKt1diSzLiWOITX1qElaTcnDJBGez5mv1ZNiRTutYOPV4Q==", - "dependencies": { - "@lexical/selection": "0.14.2", - "@lexical/utils": "0.14.2" - }, - "peerDependencies": { - "lexical": "0.14.2" - } - }, - "packages/lexical-devtools-core/node_modules/@lexical/link": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.14.2.tgz", - "integrity": "sha512-XD4VdxtBm9Yx5vk2hDEDKY1BjgNVdfmxQHo6Y/kyImAHhGRiBWa6V1+l55qfgcjPW3tN2QY/gSKDCPQGk7vKJw==", - "dependencies": { - "@lexical/utils": "0.14.2" - }, - "peerDependencies": { - "lexical": "0.14.2" - } - }, - "packages/lexical-devtools-core/node_modules/@lexical/list": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.14.2.tgz", - "integrity": "sha512-74MVHcYtTC5Plj+GGRV08uk9qbI1AaKc37NGLe3T08aVBqzqxXl1qZK9BhrM2mqTVXB98ZnOXkBk+07vke+b0Q==", - "dependencies": { - "@lexical/utils": "0.14.2" - }, - "peerDependencies": { - "lexical": "0.14.2" - } - }, - "packages/lexical-devtools-core/node_modules/@lexical/mark": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.14.2.tgz", - "integrity": "sha512-8G1p2tuUkymWXvWgUUShZp5AgYIODUZrBYDpGsCBNkXuSdGagOirS5LhKeiT/68BnrPzGrlnCdmomnI/kMxh6w==", - "dependencies": { - "@lexical/utils": "0.14.2" - }, - "peerDependencies": { - "lexical": "0.14.2" - } - }, - "packages/lexical-devtools-core/node_modules/@lexical/selection": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.14.2.tgz", - "integrity": "sha512-M122XXGEiBgaxEhL63d+su0pPri67/GlFIwGC/j3D0TN4Giyt/j0ToHhqvlIF6TfuXlBusIYbSuJ19ny12lCEg==", - "peerDependencies": { - "lexical": "0.14.2" - } - }, - "packages/lexical-devtools-core/node_modules/@lexical/table": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.14.2.tgz", - "integrity": "sha512-iwsZ5AqkM7RGyU38daK0XgpC8DG0TlEqEYsXhOLjCpAERY/+bgfdjxP8YWtUV5eIgHX0yY7FkqCUZUJSEcbUeA==", - "dependencies": { - "@lexical/utils": "0.14.2" - }, - "peerDependencies": { - "lexical": "0.14.2" - } - }, - "packages/lexical-devtools-core/node_modules/@lexical/utils": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.14.2.tgz", - "integrity": "sha512-IGknsaSyQbBJYKJJrrjNPaZuQPsJmFqGrCmNR6DcQNenWrFnmAliQPFA7HbszwRSxOFTo/BCAsIgXRQob6RjOQ==", - "dependencies": { - "@lexical/list": "0.14.2", - "@lexical/selection": "0.14.2", - "@lexical/table": "0.14.2" - }, - "peerDependencies": { - "lexical": "0.14.2" - } - }, - "packages/lexical-devtools-core/node_modules/lexical": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.14.2.tgz", - "integrity": "sha512-Uxe0jD2T4XY/+WKiVgnV6OH/GmsF1I0YStcSuMR3Alfhnv5MEYuCa482zo+S5zOPjB1x9j/b+TOLtZEMArwELw==" - }, "packages/lexical-devtools/node_modules/@rollup/plugin-babel": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", @@ -31593,12 +31331,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "packages/lexical-devtools/node_modules/lexical": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.14.2.tgz", - "integrity": "sha512-Uxe0jD2T4XY/+WKiVgnV6OH/GmsF1I0YStcSuMR3Alfhnv5MEYuCa482zo+S5zOPjB1x9j/b+TOLtZEMArwELw==", - "dev": true - }, "packages/lexical-devtools/node_modules/react-refresh": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", @@ -31945,7 +31677,7 @@ }, "packages/lexical-website": { "name": "@lexical/website", - "version": "0.0.0", + "version": "0.14.3", "dependencies": { "@docusaurus/core": "^3.2.1", "@docusaurus/preset-classic": "^3.2.1", @@ -32688,16 +32420,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==" }, - "@babel/plugin-proposal-throw-expressions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.18.6.tgz", - "integrity": "sha512-WHOrJyhGoGrdtW480L79cF7Iq/gZDZ/z6OqK7mVyFR5I37dTpog/wNgb6hmaM3HYZtULEJl++7VaMWkNZsOcHg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-throw-expressions": "^7.18.6" - } - }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", @@ -32748,12 +32470,12 @@ } }, "@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.1.tgz", + "integrity": "sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.0" } }, "@babel/plugin-syntax-import-assertions": { @@ -32852,15 +32574,6 @@ "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/plugin-syntax-throw-expressions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.18.6.tgz", - "integrity": "sha512-rp1CqEZXGv1z1YZ3qYffBH3rhnOxrTwQG8fh2yqulTurwv9zu3Gthfd+niZBLSOi1rY6146TgF+JmVeDXaX4TQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, "@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -33027,13 +32740,13 @@ } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.18.6.tgz", - "integrity": "sha512-wE0xtA7csz+hw4fKPwxmu5jnzAsXPIO57XnRwzXP3T19jWh1BODnPGoG9xKYwvAwusP7iUktHayRFbMPGtODaQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.1.tgz", + "integrity": "sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-flow": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-flow": "^7.24.1" } }, "@babel/plugin-transform-for-of": { @@ -33521,14 +33234,14 @@ } }, "@babel/preset-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz", - "integrity": "sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.1.tgz", + "integrity": "sha512-sWCV2G9pcqZf+JHyv/RyqEIpFypxdCSxWIxQjpdaQxenNog7cN1pr76hg8u0Fz8Qgg0H4ETkGcJnXL8d4j0PPA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-flow-strip-types": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-transform-flow-strip-types": "^7.24.1" } }, "@babel/preset-modules": { @@ -35429,12 +35142,12 @@ "version": "file:packages/lexical-devtools", "requires": { "@eduardoac-skimlinks/webext-redux": "3.0.1-release-candidate", - "@lexical/devtools-core": "0.14.2", + "@lexical/devtools-core": "0.14.3", "@rollup/plugin-babel": "^6.0.4", "@types/react": "^18.2.46", "@types/react-dom": "^18.2.18", "@vitejs/plugin-react": "^4.2.1", - "lexical": "0.14.2", + "lexical": "0.14.3", "react": "^18.2.0", "react-dom": "^18.2.0", "typescript": "^5.3.3", @@ -35528,12 +35241,6 @@ "dev": true, "optional": true }, - "lexical": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.14.2.tgz", - "integrity": "sha512-Uxe0jD2T4XY/+WKiVgnV6OH/GmsF1I0YStcSuMR3Alfhnv5MEYuCa482zo+S5zOPjB1x9j/b+TOLtZEMArwELw==", - "dev": true - }, "react-refresh": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", @@ -35588,75 +35295,12 @@ "@lexical/devtools-core": { "version": "file:packages/lexical-devtools-core", "requires": { - "@lexical/html": "0.14.2", - "@lexical/link": "0.14.2", - "@lexical/mark": "0.14.2", - "@lexical/table": "0.14.2", - "@lexical/utils": "0.14.2", - "lexical": "0.14.2" - }, - "dependencies": { - "@lexical/html": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.14.2.tgz", - "integrity": "sha512-5uL0wSfS9H5/HNeCM4QaJMekoL1w4D81361RlC2ppKt1diSzLiWOITX1qElaTcnDJBGez5mv1ZNiRTutYOPV4Q==", - "requires": { - "@lexical/selection": "0.14.2", - "@lexical/utils": "0.14.2" - } - }, - "@lexical/link": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.14.2.tgz", - "integrity": "sha512-XD4VdxtBm9Yx5vk2hDEDKY1BjgNVdfmxQHo6Y/kyImAHhGRiBWa6V1+l55qfgcjPW3tN2QY/gSKDCPQGk7vKJw==", - "requires": { - "@lexical/utils": "0.14.2" - } - }, - "@lexical/list": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.14.2.tgz", - "integrity": "sha512-74MVHcYtTC5Plj+GGRV08uk9qbI1AaKc37NGLe3T08aVBqzqxXl1qZK9BhrM2mqTVXB98ZnOXkBk+07vke+b0Q==", - "requires": { - "@lexical/utils": "0.14.2" - } - }, - "@lexical/mark": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.14.2.tgz", - "integrity": "sha512-8G1p2tuUkymWXvWgUUShZp5AgYIODUZrBYDpGsCBNkXuSdGagOirS5LhKeiT/68BnrPzGrlnCdmomnI/kMxh6w==", - "requires": { - "@lexical/utils": "0.14.2" - } - }, - "@lexical/selection": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.14.2.tgz", - "integrity": "sha512-M122XXGEiBgaxEhL63d+su0pPri67/GlFIwGC/j3D0TN4Giyt/j0ToHhqvlIF6TfuXlBusIYbSuJ19ny12lCEg==" - }, - "@lexical/table": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.14.2.tgz", - "integrity": "sha512-iwsZ5AqkM7RGyU38daK0XgpC8DG0TlEqEYsXhOLjCpAERY/+bgfdjxP8YWtUV5eIgHX0yY7FkqCUZUJSEcbUeA==", - "requires": { - "@lexical/utils": "0.14.2" - } - }, - "@lexical/utils": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.14.2.tgz", - "integrity": "sha512-IGknsaSyQbBJYKJJrrjNPaZuQPsJmFqGrCmNR6DcQNenWrFnmAliQPFA7HbszwRSxOFTo/BCAsIgXRQob6RjOQ==", - "requires": { - "@lexical/list": "0.14.2", - "@lexical/selection": "0.14.2", - "@lexical/table": "0.14.2" - } - }, - "lexical": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.14.2.tgz", - "integrity": "sha512-Uxe0jD2T4XY/+WKiVgnV6OH/GmsF1I0YStcSuMR3Alfhnv5MEYuCa482zo+S5zOPjB1x9j/b+TOLtZEMArwELw==" - } + "@lexical/html": "0.14.3", + "@lexical/link": "0.14.3", + "@lexical/mark": "0.14.3", + "@lexical/table": "0.14.3", + "@lexical/utils": "0.14.3", + "lexical": "0.14.3" } }, "@lexical/dragon": { @@ -36923,9 +36567,10 @@ "dev": true }, "@types/katex": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz", - "integrity": "sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==" + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "dev": true }, "@types/lodash": { "version": "4.14.182", @@ -39641,12 +39286,6 @@ "ms": "2.1.2" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, "decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", @@ -41693,6 +41332,12 @@ "integrity": "sha512-q8hXSRhZ+I14jS0KGDDsPYCvPufvBexk6nJXSOsSP6DgCuXbvCOByWhsXRAjPtmXKmO8v9RKSJm1kRaWaf0fZw==", "dev": true }, + "flow-enums-runtime": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", + "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==", + "dev": true + }, "follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -41965,156 +41610,6 @@ } } }, - "gen-flow-files": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/gen-flow-files/-/gen-flow-files-0.4.11.tgz", - "integrity": "sha512-88WjoL6gaxTaJtSal6Nsw9LerVKRVjQEAJy330VOmCS1k+lu2h1HJEJyU9LhviaphZBNG088j6JigA6YiP0xGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@babel/generator": "^7.7.4", - "@babel/parser": "^7.7.5", - "@babel/plugin-proposal-throw-expressions": "^7.7.4", - "@babel/plugin-syntax-flow": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "glob": "^7.1.6", - "mkdirp": "^0.5.1", - "yargs": "^15.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -42657,6 +42152,46 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "hermes-eslint": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-eslint/-/hermes-eslint-0.20.1.tgz", + "integrity": "sha512-EhdvFV6RkPIJvbqN8oqFZO1oF4NlPWMjhMjCWkUJX1YL1MZMfkF7nSdx6RKTq6xK17yo+Bgv88L21xuH9GtRpw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "hermes-estree": "0.20.1", + "hermes-parser": "0.20.1" + } + }, + "hermes-estree": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz", + "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==", + "dev": true + }, + "hermes-parser": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz", + "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==", + "dev": true, + "requires": { + "hermes-estree": "0.20.1" + } + }, + "hermes-transform": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/hermes-transform/-/hermes-transform-0.20.1.tgz", + "integrity": "sha512-gpetyzAQvuLXVWIk8/I2A/ei/5+o8eT+QuSGd8FcWpXoYxVkYjVKLVNE9xKLsEkk2wQ1tXODY5OeOZoaz9jL7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.0", + "esquery": "^1.4.0", + "flow-enums-runtime": "^0.0.6", + "hermes-eslint": "0.20.1", + "hermes-estree": "0.20.1", + "hermes-parser": "0.20.1" + } + }, "highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -47188,6 +46723,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, + "optional": true, "requires": { "minimist": "^1.2.6" } @@ -48305,9 +47841,9 @@ "dev": true }, "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true }, "pkg-dir": { @@ -48862,6 +48398,17 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==" }, + "prettier-plugin-hermes-parser": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-hermes-parser/-/prettier-plugin-hermes-parser-0.20.1.tgz", + "integrity": "sha512-T6dfa1++ckTxd3MbLxS6sTv1T3yvTu1drahNt3g34hyCzSwYTKTByocLyhd1A9j9uCUlIPD+ogum7+i1h3+CEw==", + "dev": true, + "requires": { + "hermes-estree": "0.20.1", + "hermes-parser": "0.20.1", + "prettier-plugin-hermes-parser": "0.20.1" + } + }, "prettier-plugin-organize-attributes": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/prettier-plugin-organize-attributes/-/prettier-plugin-organize-attributes-0.0.5.tgz", @@ -50182,12 +49729,6 @@ "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==" }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -50729,12 +50270,6 @@ "send": "0.18.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, "set-value": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", @@ -51948,9 +51483,9 @@ "dev": true }, "ts-jest": { - "version": "29.0.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", - "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==", + "version": "29.1.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", + "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", "dev": true, "requires": { "bs-logger": "0.x", @@ -51959,7 +51494,7 @@ "json5": "^2.2.3", "lodash.memoize": "4.x", "make-error": "1.x", - "semver": "7.x", + "semver": "^7.5.3", "yargs-parser": "^21.0.1" } }, @@ -53333,12 +52868,6 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, "widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", diff --git a/package.json b/package.json index 8dec59ae5bf..7bc20010eb5 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,11 @@ "changelog": "func() { git --no-pager log --oneline ${1}...HEAD --pretty=format:\"- %s %an\"; }; func", "increment-version": "node ./scripts/npm/increment-version", "update-changelog": "node ./scripts/npm/update-changelog", + "update-docs": "node ./scripts/update-docs", "update-version": "node ./scripts/updateVersion", + "update-tsconfig": "node ./scripts/update-tsconfig", + "update-flowconfig": "node ./scripts/update-flowconfig", + "update-packages": "npm run update-version && npm run update-tsconfig && npm run update-flowconfig && npm run update-docs", "postversion": "git checkout -b ${npm_package_version}__release && npm install && npm run update-version && npm run update-changelog && git add -A && git commit -m v${npm_package_version} && git tag -a v${npm_package_version} -m v${npm_package_version}", "release": "npm run prepare-release && node ./scripts/npm/release.js", "size": "npm run build-prod && size-limit" @@ -117,6 +121,7 @@ "@size-limit/preset-big-lib": "^11.1.2", "@types/jest": "^29.4.0", "@types/jsdom": "^21.1.6", + "@types/katex": "^0.16.7", "@types/node": "^17.0.31", "@types/prismjs": "^1.26.0", "@types/react": "^18.0.8", @@ -147,10 +152,11 @@ "eslint-plugin-sort-keys-fix": "^1.1.2", "flow-bin": "^0.226.0", "fs-extra": "^10.0.0", - "gen-flow-files": "^0.4.11", "glob": "^7.2.0", "google-closure-compiler": "^20220202.0.0", "gzip-size": "^6.0.0", + "hermes-parser": "^0.20.1", + "hermes-transform": "^0.20.1", "husky": "^7.0.1", "jest": "^29.4.0", "jest-environment-jsdom": "^29.4.0", @@ -159,19 +165,19 @@ "minimist": "^1.2.5", "npm-run-all": "^4.1.5", "prettier": "^2.3.2", + "prettier-plugin-hermes-parser": "^0.20.1", "prettier-plugin-organize-attributes": "^0.0.5", "prettier-plugin-tailwindcss": "^0.4.1", "react-test-renderer": "^17.0.2", "rollup": "^2.75.5", "size-limit": "^11.1.2", "tmp": "^0.2.1", - "ts-jest": "^29.0.0", + "ts-jest": "^29.1.2", "ts-node": "^10.9.1", "typedoc": "^0.25.12", "typescript": "5.1.6" }, "dependencies": { - "@types/katex": "^0.14.0", "yjs": "^13.5.42" } } diff --git a/packages/lexical-code/src/CodeHighlighterPrism.ts b/packages/lexical-code/src/CodeHighlighterPrism.ts index 132c092941a..f69e65503ca 100644 --- a/packages/lexical-code/src/CodeHighlighterPrism.ts +++ b/packages/lexical-code/src/CodeHighlighterPrism.ts @@ -23,3 +23,9 @@ import 'prismjs/components/prism-swift'; import 'prismjs/components/prism-typescript'; import 'prismjs/components/prism-java'; import 'prismjs/components/prism-cpp'; + +declare global { + interface Window { + Prism: typeof import('prismjs'); + } +} diff --git a/packages/lexical-devtools-core/package.json b/packages/lexical-devtools-core/package.json index cf7645e988e..2d9cee4f4ff 100644 --- a/packages/lexical-devtools-core/package.json +++ b/packages/lexical-devtools-core/package.json @@ -8,16 +8,16 @@ "utils" ], "license": "MIT", - "version": "0.14.2", + "version": "0.14.3", "main": "LexicalDevtoolsCore.js", "types": "index.d.ts", "dependencies": { - "lexical": "0.14.2", - "@lexical/utils": "0.14.2", - "@lexical/table": "0.14.2", - "@lexical/html": "0.14.2", - "@lexical/mark": "0.14.2", - "@lexical/link": "0.14.2" + "@lexical/html": "0.14.3", + "@lexical/link": "0.14.3", + "@lexical/mark": "0.14.3", + "@lexical/table": "0.14.3", + "@lexical/utils": "0.14.3", + "lexical": "0.14.3" }, "peerDependencies": { "react": ">=17.x", @@ -34,11 +34,15 @@ ".": { "import": { "types": "./index.d.ts", + "development": "./LexicalDevtoolsCore.dev.mjs", + "production": "./LexicalDevtoolsCore.prod.mjs", "node": "./LexicalDevtoolsCore.node.mjs", "default": "./LexicalDevtoolsCore.mjs" }, "require": { "types": "./index.d.ts", + "development": "./LexicalDevtoolsCore.dev.js", + "production": "./LexicalDevtoolsCore.prod.js", "default": "./LexicalDevtoolsCore.js" } } diff --git a/packages/lexical-devtools/package.json b/packages/lexical-devtools/package.json index ed8e52a5b9c..edde3c2eb07 100644 --- a/packages/lexical-devtools/package.json +++ b/packages/lexical-devtools/package.json @@ -2,7 +2,7 @@ "name": "@lexical/devtools", "description": "Lexical DevTools browser extension", "private": true, - "version": "0.0.0", + "version": "0.14.3", "type": "module", "scripts": { "dev": "wxt", @@ -15,21 +15,21 @@ "postinstall": "wxt prepare" }, "dependencies": { + "@eduardoac-skimlinks/webext-redux": "3.0.1-release-candidate", "react": "^18.2.0", "react-dom": "^18.2.0", - "@eduardoac-skimlinks/webext-redux": "3.0.1-release-candidate", - "zustand": "^4.5.1", - "webext-bridge": "~6.0.1" + "webext-bridge": "~6.0.1", + "zustand": "^4.5.1" }, "devDependencies": { + "@lexical/devtools-core": "0.14.3", + "@rollup/plugin-babel": "^6.0.4", "@types/react": "^18.2.46", "@types/react-dom": "^18.2.18", "@vitejs/plugin-react": "^4.2.1", + "lexical": "0.14.3", "typescript": "^5.3.3", - "lexical": "0.14.2", - "@lexical/devtools-core": "0.14.2", - "wxt": "^0.17.0", "vite": "^5.2.2", - "@rollup/plugin-babel": "^6.0.4" + "wxt": "^0.17.0" } } diff --git a/packages/lexical-devtools/tsconfig.json b/packages/lexical-devtools/tsconfig.json index 919db6be896..350081311a6 100644 --- a/packages/lexical-devtools/tsconfig.json +++ b/packages/lexical-devtools/tsconfig.json @@ -6,14 +6,161 @@ "target": "ES2019", "allowImportingTsExtensions": true, "jsx": "react-jsx", + "allowJs": true, "paths": { - "lexical": ["../lexical/src/"], "lexicalOriginal": ["../lexical/src/"], - "@lexical/devtools-core": ["../lexical-devtools-core/src/"], + "lexical": ["../lexical/src/index.ts"], + "@lexical/clipboard": ["../lexical-clipboard/src/index.ts"], + "@lexical/code": ["../lexical-code/src/index.ts"], + "@lexical/devtools-core": ["../lexical-devtools-core/src/index.ts"], + "@lexical/dragon": ["../lexical-dragon/src/index.ts"], + "@lexical/file": ["../lexical-file/src/index.ts"], + "@lexical/hashtag": ["../lexical-hashtag/src/index.ts"], + "@lexical/headless": ["../lexical-headless/src/index.ts"], + "@lexical/history": ["../lexical-history/src/index.ts"], + "@lexical/html": ["../lexical-html/src/index.ts"], + "@lexical/link": ["../lexical-link/src/index.ts"], + "@lexical/list": ["../lexical-list/src/index.ts"], + "@lexical/mark": ["../lexical-mark/src/index.ts"], + "@lexical/markdown": ["../lexical-markdown/src/index.ts"], + "@lexical/offset": ["../lexical-offset/src/index.ts"], + "@lexical/overflow": ["../lexical-overflow/src/index.ts"], + "@lexical/plain-text": ["../lexical-plain-text/src/index.ts"], + "@lexical/react/LexicalAutoEmbedPlugin": [ + "../lexical-react/src/LexicalAutoEmbedPlugin.tsx" + ], + "@lexical/react/LexicalAutoFocusPlugin": [ + "../lexical-react/src/LexicalAutoFocusPlugin.ts" + ], + "@lexical/react/LexicalAutoLinkPlugin": [ + "../lexical-react/src/LexicalAutoLinkPlugin.ts" + ], + "@lexical/react/LexicalBlockWithAlignableContents": [ + "../lexical-react/src/LexicalBlockWithAlignableContents.tsx" + ], + "@lexical/react/LexicalCharacterLimitPlugin": [ + "../lexical-react/src/LexicalCharacterLimitPlugin.tsx" + ], + "@lexical/react/LexicalCheckListPlugin": [ + "../lexical-react/src/LexicalCheckListPlugin.tsx" + ], + "@lexical/react/LexicalClearEditorPlugin": [ + "../lexical-react/src/LexicalClearEditorPlugin.ts" + ], + "@lexical/react/LexicalClickableLinkPlugin": [ + "../lexical-react/src/LexicalClickableLinkPlugin.tsx" + ], + "@lexical/react/LexicalCollaborationContext": [ + "../lexical-react/src/LexicalCollaborationContext.ts" + ], + "@lexical/react/LexicalCollaborationPlugin": [ + "../lexical-react/src/LexicalCollaborationPlugin.ts" + ], + "@lexical/react/LexicalComposer": [ + "../lexical-react/src/LexicalComposer.tsx" + ], + "@lexical/react/LexicalComposerContext": [ + "../lexical-react/src/LexicalComposerContext.ts" + ], + "@lexical/react/LexicalContentEditable": [ + "../lexical-react/src/LexicalContentEditable.tsx" + ], + "@lexical/react/LexicalContextMenuPlugin": [ + "../lexical-react/src/LexicalContextMenuPlugin.tsx" + ], + "@lexical/react/LexicalDecoratorBlockNode": [ + "../lexical-react/src/LexicalDecoratorBlockNode.ts" + ], + "@lexical/react/LexicalEditorRefPlugin": [ + "../lexical-react/src/LexicalEditorRefPlugin.tsx" + ], + "@lexical/react/LexicalErrorBoundary": [ + "../lexical-react/src/LexicalErrorBoundary.tsx" + ], + "@lexical/react/LexicalHashtagPlugin": [ + "../lexical-react/src/LexicalHashtagPlugin.ts" + ], + "@lexical/react/LexicalHistoryPlugin": [ + "../lexical-react/src/LexicalHistoryPlugin.ts" + ], + "@lexical/react/LexicalHorizontalRuleNode": [ + "../lexical-react/src/LexicalHorizontalRuleNode.tsx" + ], + "@lexical/react/LexicalHorizontalRulePlugin": [ + "../lexical-react/src/LexicalHorizontalRulePlugin.ts" + ], + "@lexical/react/LexicalLinkPlugin": [ + "../lexical-react/src/LexicalLinkPlugin.ts" + ], + "@lexical/react/LexicalListPlugin": [ + "../lexical-react/src/LexicalListPlugin.ts" + ], + "@lexical/react/LexicalMarkdownShortcutPlugin": [ + "../lexical-react/src/LexicalMarkdownShortcutPlugin.tsx" + ], + "@lexical/react/LexicalNestedComposer": [ + "../lexical-react/src/LexicalNestedComposer.tsx" + ], + "@lexical/react/LexicalNodeEventPlugin": [ + "../lexical-react/src/LexicalNodeEventPlugin.ts" + ], + "@lexical/react/LexicalNodeMenuPlugin": [ + "../lexical-react/src/LexicalNodeMenuPlugin.tsx" + ], + "@lexical/react/LexicalOnChangePlugin": [ + "../lexical-react/src/LexicalOnChangePlugin.ts" + ], + "@lexical/react/LexicalPlainTextPlugin": [ + "../lexical-react/src/LexicalPlainTextPlugin.tsx" + ], + "@lexical/react/LexicalRichTextPlugin": [ + "../lexical-react/src/LexicalRichTextPlugin.tsx" + ], + "@lexical/react/LexicalTabIndentationPlugin": [ + "../lexical-react/src/LexicalTabIndentationPlugin.tsx" + ], + "@lexical/react/LexicalTableOfContents": [ + "../lexical-react/src/LexicalTableOfContents.tsx" + ], + "@lexical/react/LexicalTablePlugin": [ + "../lexical-react/src/LexicalTablePlugin.ts" + ], + "@lexical/react/LexicalTreeView": [ + "../lexical-react/src/LexicalTreeView.tsx" + ], + "@lexical/react/LexicalTypeaheadMenuPlugin": [ + "../lexical-react/src/LexicalTypeaheadMenuPlugin.tsx" + ], + "@lexical/react/useLexicalEditable": [ + "../lexical-react/src/useLexicalEditable.ts" + ], + "@lexical/react/useLexicalIsTextContentEmpty": [ + "../lexical-react/src/useLexicalIsTextContentEmpty.ts" + ], + "@lexical/react/useLexicalNodeSelection": [ + "../lexical-react/src/useLexicalNodeSelection.ts" + ], + "@lexical/react/useLexicalSubscription": [ + "../lexical-react/src/useLexicalSubscription.tsx" + ], + "@lexical/react/useLexicalTextEntity": [ + "../lexical-react/src/useLexicalTextEntity.ts" + ], + "@lexical/rich-text": ["../lexical-rich-text/src/index.ts"], + "@lexical/selection": ["../lexical-selection/src/index.ts"], + "@lexical/table": ["../lexical-table/src/index.ts"], + "@lexical/text": ["../lexical-text/src/index.ts"], + "@lexical/utils": ["../lexical-utils/src/index.ts"], + "@lexical/yjs": ["../lexical-yjs/src/index.ts"], "shared/canUseDOM": ["../shared/src/canUseDOM.ts"], - "shared/normalizeClassNames": ["../shared/src/normalizeClassNames.ts"], + "shared/caretFromPoint": ["../shared/src/caretFromPoint.ts"], + "shared/environment": ["../shared/src/environment.ts"], "shared/invariant": ["../shared/src/invariant.ts"], - "shared/environment": ["../shared/src/environment.ts"] + "shared/normalizeClassNames": ["../shared/src/normalizeClassNames.ts"], + "shared/simpleDiffWithCursor": ["../shared/src/simpleDiffWithCursor.ts"], + "shared/useLayoutEffect": ["../shared/src/useLayoutEffect.ts"], + "shared/warnOnlyOnce": ["../shared/src/warnOnlyOnce.ts"] } - } + }, + "exclude": ["../.output", "../../libdefs/*.js"] } diff --git a/packages/lexical-react/src/__tests__/unit/utils.tsx b/packages/lexical-react/src/__tests__/unit/utils.tsx index 7ad79b4da1a..da06ddd35de 100644 --- a/packages/lexical-react/src/__tests__/unit/utils.tsx +++ b/packages/lexical-react/src/__tests__/unit/utils.tsx @@ -6,7 +6,7 @@ * */ -import {UserState} from '@lexical/yjs/src/index'; +import {UserState} from '@lexical/yjs'; import {LexicalEditor} from 'lexical'; import * as React from 'react'; import {createRoot, Root} from 'react-dom/client'; diff --git a/packages/lexical-website/docs/collaboration/react.md b/packages/lexical-website/docs/collaboration/react.md index 291946730d3..23ef9d65eee 100644 --- a/packages/lexical-website/docs/collaboration/react.md +++ b/packages/lexical-website/docs/collaboration/react.md @@ -11,7 +11,7 @@ import {$getRoot, $createParagraphNode, $createTextNode} from 'lexical'; import {LexicalComposer} from '@lexical/react/LexicalComposer'; import {ContentEditable} from '@lexical/react/LexicalContentEditable'; import {PlainTextPlugin} from '@lexical/react/LexicalPlainTextPlugin'; -import {CollaborationPlugin} from "@lexical/react/LexicalCollaborationPlugin"; +import {CollaborationPlugin} from '@lexical/react/LexicalCollaborationPlugin'; import * as Y from 'yjs'; import {WebsocketProvider} from 'y-websocket'; diff --git a/packages/lexical-website/docs/maintainers-guide.md b/packages/lexical-website/docs/maintainers-guide.md new file mode 100644 index 00000000000..52a2ef1b3d1 --- /dev/null +++ b/packages/lexical-website/docs/maintainers-guide.md @@ -0,0 +1,122 @@ +# Maintainers' Guide + +This is the grimoire of arcane knowledge covering the overall organization +of the Lexical monorepo, including its conventions, quirks, and +configurations. + +## Monorepo Organization + +### Workspaces + +The top-level `package.json` uses +[npm workspaces](https://docs.npmjs.com/cli/v10/using-npm/workspaces) to +configure the monorepo. This mostly means that all packages share a +top-level `package-lock.json` and `npm run {command} -w {package}` is often +used to run a command from a nested package's package.json. + +### Private + +Some packages in the monorepo do not get published to npm, for example: + +* `packages/lexical-devtools` - browser extension for working with Lexical + sites +* `packages/lexical-playground` - the + [playground.lexical.dev](https://playground.lexical.dev/) demo site +* `packages/lexical-website` - the [lexical.dev](https://lexical.dev/) + docusaurus website that you may even be reading right now +* `packages/shared` - internal code that is used by more than one repository + but should not be a public API + +It is required that these packages, and any other package that should not be +published to npm, have a `"private": true` property in their `package.json`. +If you have an in-progress package that will eventually be public, but is +not ready for consumption, it should probably still be set to +`"private": true` otherwise the tooling will find it and publish it. + +## Package naming conventions + +### Overall + +| Usage | Convention | +| -- | -- | +| Directory name | `packages/lexical-package-name` | +| Entrypoint | `packages/lexical-package-name/index.ts` | +| Flow types | `packages/lexical-package/flow/LexicalPackage.js.flow` | +| package.json name | `@lexical/package-name` | + +### Multiple module export (@lexical/react) + +Instead of having a single module, some packages may have many modules +(currently only `@lexical/react`) that are each exported separately. +In that scenario, there should be no `index.ts` file and every module +at the top-level should be an entrypoint. All entrypoints should be a +TypeScript file, not a subdirectory containing an index.ts file. + +The [update-packages](#npm-run-update-packages) script will ensure that the exports match the files +on disk. + +## Scripts for development + +### npm run update-packages + +This script runs: update-version, update-tsconfig, update-flowconfig, and +update-docs. This is safe to do at any time and will ensure that package.json +files are all at the correct versions, paths are set up correctly for module +resolution of all public exports, and that various defaults are filled in. + +These scripts can be run individually, but unless you're working on one +of these scripts you might as well run them all. + +### npm run prepare-release + +This runs all of the pre-release steps and will let you inspect the artifacts +that would be uploaded to npm. Each public package will have a npm directory, e.g. +`packages/lexical/npm` that contains those artifacts. + +### npm run ci-check + +Check flow, TypeScript, prettier and eslint for issues. A good command to run +after committing (which will auto-fix most prettier issues) and before pushing +a PR. + +### npm run flow + +Check the Flow types + +### npm run tsc + +Check the TypeScript types + +### npm run tsc-extension + +Check the TypeScript types of the lexical-devtools extension + +### npm run test-unit + +Run the unit tests + +### npm run lint + +Run eslint + +## Scripts for release managers + +### npm run increment-version + +Increment the monorepo version. Make sure to run `npm run update-packages` +after this. + +### npm run extract-codes + +Extract error codes for the production build. Essential to run before a release. + +### npm run changelog + +Update the changelog from git history. + +### npm run release + +*Prerequisites:* all of the previous release manager scripts, +plus creating a tag in git, and likely other steps. + +Runs prepare-release to do a full build and then uploads to npm. diff --git a/packages/lexical-website/docusaurus.config.js b/packages/lexical-website/docusaurus.config.js index bbd7ff80874..53c50e589e7 100644 --- a/packages/lexical-website/docusaurus.config.js +++ b/packages/lexical-website/docusaurus.config.js @@ -10,11 +10,12 @@ // @ts-check // Note: type annotations allow type checking and IDEs autocompletion -const fs = require('fs-extra'); const {github: lightCodeTheme, dracula: darkCodeTheme} = require('prism-react-renderer').themes; const importPlugin = require('remark-import-partial'); const slugifyPlugin = require('./src/plugins/lexical-remark-slugify-anchors'); +const {packagesManager} = require('../../scripts/shared/packagesManager'); +const path = require('node:path'); const TITLE = 'Lexical'; const GITHUB_REPO_URL = 'https://github.com/facebook/lexical'; // TODO: Update when repo name updated @@ -29,25 +30,6 @@ function sourceLinkOptions() { }; } -function lexicalReactEntryPoints() { - return Object.keys( - fs.readJsonSync('../lexical-react/package.json').exports, - ).flatMap((k) => { - const m = /\.\/([^.]+)$/.exec(k); - if (!m) { - return []; - } - const prefix = `../lexical-react/src/${m[1]}`; - for (const ext of ['.tsx', '.ts']) { - const fn = `${prefix}${ext}`; - if (fs.existsSync(fn)) { - return [fn]; - } - } - throw Error(`No entry point found for ${prefix}`); - }); -} - /** @type {import('@docusaurus/types').Config} */ const config = { baseUrl: '/', @@ -67,32 +49,18 @@ const config = { 'docusaurus-plugin-typedoc', { ...sourceLinkOptions(), - entryPoints: [ - '../lexical/src/index.ts', - '../lexical-clipboard/src/index.ts', - '../lexical-code/src/index.ts', - '../lexical-devtools-core/src/index.ts', - '../lexical-dragon/src/index.ts', - '../lexical-file/src/index.ts', - '../lexical-hashtag/src/index.ts', - '../lexical-headless/src/index.ts', - '../lexical-history/src/index.ts', - '../lexical-html/src/index.ts', - '../lexical-link/src/index.ts', - '../lexical-list/src/index.ts', - '../lexical-mark/src/index.ts', - '../lexical-markdown/src/index.ts', - '../lexical-offset/src/index.ts', - '../lexical-overflow/src/index.ts', - '../lexical-plain-text/src/index.ts', - ...lexicalReactEntryPoints(), - '../lexical-rich-text/src/index.ts', - '../lexical-selection/src/index.ts', - '../lexical-table/src/index.ts', - '../lexical-text/src/index.ts', - '../lexical-utils/src/index.ts', - '../lexical-yjs/src/index.ts', - ], + entryPoints: packagesManager + .getPublicPackages() + .flatMap((pkg) => + pkg + .getExportedNpmModuleEntries() + .map((entry) => [ + path.relative( + __dirname, + pkg.resolve('src', entry.sourceFileName), + ), + ]), + ), excludeInternal: true, plugin: [ './src/plugins/lexical-typedoc-plugin-no-inherit', diff --git a/packages/lexical-website/package.json b/packages/lexical-website/package.json index 23d6a57c96e..e7f31579912 100644 --- a/packages/lexical-website/package.json +++ b/packages/lexical-website/package.json @@ -1,6 +1,6 @@ { "name": "@lexical/website", - "version": "0.0.0", + "version": "0.14.3", "private": true, "scripts": { "docusaurus": "docusaurus", diff --git a/packages/lexical/src/__tests__/unit/LexicalListPlugin.test.tsx b/packages/lexical/src/__tests__/unit/LexicalListPlugin.test.tsx index dc625395509..37c0aa4de3a 100644 --- a/packages/lexical/src/__tests__/unit/LexicalListPlugin.test.tsx +++ b/packages/lexical/src/__tests__/unit/LexicalListPlugin.test.tsx @@ -15,7 +15,7 @@ import { INDENT_CONTENT_COMMAND, LexicalEditor, OUTDENT_CONTENT_COMMAND, -} from 'lexical/src'; +} from 'lexical'; import { expectHtmlToBeEqual, html, diff --git a/packages/lexical/src/__tests__/utils/index.tsx b/packages/lexical/src/__tests__/utils/index.tsx index 694d30cbfe2..c09e062d8f0 100644 --- a/packages/lexical/src/__tests__/utils/index.tsx +++ b/packages/lexical/src/__tests__/utils/index.tsx @@ -27,12 +27,9 @@ import { $isRangeSelection, createEditor, DecoratorNode, - ElementNode, - TextNode, -} from 'lexical'; -import { EditorState, EditorThemeClasses, + ElementNode, Klass, LexicalEditor, LexicalNode, @@ -40,7 +37,8 @@ import { SerializedElementNode, SerializedLexicalNode, SerializedTextNode, -} from 'lexical/src'; + TextNode, +} from 'lexical'; import {format} from 'prettier'; import * as React from 'react'; import {createRef} from 'react'; diff --git a/packages/shared/viteModuleResolution.ts b/packages/shared/viteModuleResolution.ts index 95a64582bc1..f83d620faf7 100644 --- a/packages/shared/viteModuleResolution.ts +++ b/packages/shared/viteModuleResolution.ts @@ -6,164 +6,31 @@ * */ -import * as fs from 'fs'; -import * as path from 'path'; +import type { + ModuleExportEntry, + PackageMetadata, +} from '../../scripts/shared/PackageMetadata'; + +import {packagesManager} from '../../scripts/shared/packagesManager'; + +function toAlias(pkg: PackageMetadata, entry: ModuleExportEntry) { + return { + find: entry.name, + replacement: pkg.resolve('src', entry.sourceFileName), + }; +} const moduleResolution = [ - { - find: /lexical$/, - replacement: path.resolve('../lexical/src/index.ts'), - }, - { - find: '@lexical/clipboard', - replacement: path.resolve('../lexical-clipboard/src/index.ts'), - }, - { - find: '@lexical/selection', - replacement: path.resolve('../lexical-selection/src/index.ts'), - }, - { - find: '@lexical/text', - replacement: path.resolve('../lexical-text/src/index.ts'), - }, - { - find: '@lexical/headless', - replacement: path.resolve('../lexical-headless/src/index.ts'), - }, - { - find: '@lexical/html', - replacement: path.resolve('../lexical-html/src/index.ts'), - }, - { - find: '@lexical/hashtag', - replacement: path.resolve('../lexical-hashtag/src/index.ts'), - }, - { - find: '@lexical/history', - replacement: path.resolve('../lexical-history/src/index.ts'), - }, - { - find: '@lexical/list', - replacement: path.resolve('../lexical-list/src/index.ts'), - }, - { - find: '@lexical/file', - replacement: path.resolve('../lexical-file/src/index.ts'), - }, - { - find: '@lexical/table', - replacement: path.resolve('../lexical-table/src/index.ts'), - }, - { - find: '@lexical/offset', - replacement: path.resolve('../lexical-offset/src/index.ts'), - }, - { - find: '@lexical/utils', - replacement: path.resolve('../lexical-utils/src/index.ts'), - }, - { - find: '@lexical/code', - replacement: path.resolve('../lexical-code/src/index.ts'), - }, - { - find: '@lexical/plain-text', - replacement: path.resolve('../lexical-plain-text/src/index.ts'), - }, - { - find: '@lexical/rich-text', - replacement: path.resolve('../lexical-rich-text/src/index.ts'), - }, - { - find: '@lexical/dragon', - replacement: path.resolve('../lexical-dragon/src/index.ts'), - }, - { - find: '@lexical/link', - replacement: path.resolve('../lexical-link/src/index.ts'), - }, - { - find: '@lexical/overflow', - replacement: path.resolve('../lexical-overflow/src/index.ts'), - }, - { - find: '@lexical/markdown', - replacement: path.resolve('../lexical-markdown/src/index.ts'), - }, - { - find: '@lexical/mark', - replacement: path.resolve('../lexical-mark/src/index.ts'), - }, - { - find: '@lexical/yjs', - replacement: path.resolve('../lexical-yjs/src/index.ts'), - }, - { - find: '@lexical/devtools-core', - replacement: path.resolve('../lexical-devtools-core/src/index.ts'), - }, - { - find: 'shared', - replacement: path.resolve('../shared/src'), - }, + ...packagesManager + .getPublicPackages() + .flatMap((pkg) => + pkg.getExportedNpmModuleEntries().map(toAlias.bind(null, pkg)), + ), + ...['shared'] + .map((name) => packagesManager.getPackageByDirectoryName(name)) + .flatMap((pkg) => + pkg.getPrivateModuleEntries().map(toAlias.bind(null, pkg)), + ), ]; -// Lexical React -[ - 'LexicalTreeView', - 'LexicalComposer', - 'LexicalComposerContext', - 'useLexicalIsTextContentEmpty', - 'useLexicalTextEntity', - 'useLexicalSubscription', - 'useLexicalEditable', - 'LexicalContentEditable', - 'LexicalNestedComposer', - 'LexicalHorizontalRuleNode', - 'LexicalHorizontalRulePlugin', - 'LexicalDecoratorBlockNode', - 'LexicalBlockWithAlignableContents', - 'useLexicalNodeSelection', - 'LexicalMarkdownShortcutPlugin', - 'LexicalCharacterLimitPlugin', - 'LexicalHashtagPlugin', - 'LexicalErrorBoundary', - 'LexicalPlainTextPlugin', - 'LexicalRichTextPlugin', - 'LexicalClearEditorPlugin', - 'LexicalClickableLinkPlugin', - 'LexicalCollaborationContext', - 'LexicalCollaborationPlugin', - 'LexicalHistoryPlugin', - 'LexicalTypeaheadMenuPlugin', - 'LexicalNodeMenuPlugin', - 'LexicalContextMenuPlugin', - 'LexicalTablePlugin', - 'LexicalLinkPlugin', - 'LexicalListPlugin', - 'LexicalCheckListPlugin', - 'LexicalAutoFocusPlugin', - 'LexicalTableOfContents', - 'LexicalAutoLinkPlugin', - 'LexicalAutoEmbedPlugin', - 'LexicalOnChangePlugin', - 'LexicalNodeEventPlugin', - 'LexicalTabIndentationPlugin', - 'LexicalEditorRefPlugin', -].forEach((module) => { - let resolvedPath = path.resolve(`../lexical-react/src/${module}.ts`); - - if (fs.existsSync(resolvedPath)) { - moduleResolution.push({ - find: `@lexical/react/${module}`, - replacement: resolvedPath, - }); - } else { - resolvedPath = path.resolve(`../lexical-react/src/${module}.tsx`); - moduleResolution.push({ - find: `@lexical/react/${module}`, - replacement: resolvedPath, - }); - } -}); export default moduleResolution; diff --git a/scripts/__tests__/unit/build.test.js b/scripts/__tests__/unit/build.test.js new file mode 100644 index 00000000000..3a49a080af0 --- /dev/null +++ b/scripts/__tests__/unit/build.test.js @@ -0,0 +1,116 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +'use strict'; + +const fs = require('fs-extra'); +const glob = require('glob'); +const path = require('node:path'); +const {packagesManager} = require('../../shared/packagesManager'); + +const monorepoPackageJson = require('../../shared/readMonorepoPackageJson')(); + +const publicNpmNames = new Set( + packagesManager.getPublicPackages().map((pkg) => pkg.getNpmName()), +); + +describe('public package.json audits (`npm run update-version` to fix most issues)', () => { + packagesManager.getPublicPackages().forEach((pkg) => { + const npmName = pkg.getNpmName(); + const packageJson = pkg.packageJson; + describe(npmName, () => { + const sourceFiles = fs + .readdirSync(pkg.resolve('src')) + .filter((str) => /\.tsx?/.test(str)) + .map((str) => str.replace(/\.tsx?$/, '', str)) + .sort(); + const exportedModules = pkg.getExportedNpmModuleNames().sort(); + const {dependencies = {}, peerDependencies = {}} = packageJson; + if (packageJson.main) { + it('should only export the main module with main set', () => { + expect(exportedModules).toEqual([npmName]); + }); + } + it('has *.flow types', () => { + expect(glob.sync(pkg.resolve('flow', '*.flow'))).not.toEqual([]); + }); + it('uses the expected directory/npm naming convention', () => { + expect(npmName.replace(/^@/, '').replace('/', '-')).toBe( + pkg.getDirectoryName(), + ); + }); + it('matches monorepo version', () => { + expect(packageJson.version).toBe(monorepoPackageJson.version); + }); + it('must not have a direct dependency on react or react-dom', () => { + expect(dependencies).not.toContain('react'); + expect(dependencies).not.toContain('react-dom'); + }); + it('must not have monorepo peerDependencies', () => { + expect( + Object.keys(peerDependencies).filter((dep) => + publicNpmNames.has(dep), + ), + ).toEqual([]); + }); + it('monorepo dependencies must use the exact monorepo version', () => { + Object.entries(dependencies).forEach(([dep, version]) => { + if (publicNpmNames.has(dep)) { + expect([dep, version]).toEqual([dep, monorepoPackageJson.version]); + } + }); + }); + it('must export at least one module', () => { + expect(exportedModules.length).toBeGreaterThanOrEqual(1); + }); + test.each(exportedModules)( + `should have a source file for exported module %s`, + (exportedModule) => { + expect(sourceFiles).toContain( + exportedModule.slice(npmName.length + 1) || 'index', + ); + }, + ); + if (!sourceFiles.includes('index')) { + it('must not export a top-level module without an index.tsx?', () => { + expect(exportedModules).not.toContain(npmName); + }); + test.each(sourceFiles)( + `%s.tsx? must have an exported module`, + (sourceFile) => { + expect(exportedModules).toContain(`${npmName}/${sourceFile}`); + }, + ); + } + }); + }); +}); + +describe('documentation audits (`npm run update-docs` to fix most issues)', () => { + const webPkg = packagesManager.getPackageByDirectoryName('lexical-website'); + packagesManager.getPublicPackages().forEach((pkg) => { + const npmName = pkg.getNpmName(); + describe(npmName, () => { + const root = pkg.resolve('..', '..'); + [ + pkg.resolve('README.md'), + webPkg.resolve('docs', 'packages', `${pkg.getDirectoryName()}.md`), + ].forEach((docPath) => { + describe(path.relative(root, docPath), () => { + it('exists', () => expect(fs.existsSync(docPath)).toBe(true)); + if (path.basename(docPath) === 'README.md') { + it('does not have the TODO description', () => { + expect(fs.readFileSync(docPath, 'utf8')).not.toContain( + 'TODO: This package needs a description!', + ); + }); + } + }); + }); + }); + }); +}); diff --git a/scripts/build.js b/scripts/build.js index 68dd38bcdd5..d271fcdf63c 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -22,11 +22,13 @@ const alias = require('@rollup/plugin-alias'); const compiler = require('@ampproject/rollup-plugin-closure-compiler'); const terser = require('@rollup/plugin-terser'); const {exec} = require('child-process-promise'); +const {packagesManager} = require('./shared/packagesManager'); +const npmToWwwName = require('./www/npmToWwwName'); -const license = ` * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree.`; +const headerTemplate = fs.readFileSync( + path.resolve(__dirname, 'www', 'headerTemplate.js'), + 'utf8', +); const isProduction = argv.prod; const isRelease = argv.release; @@ -47,29 +49,13 @@ const closureOptions = { }; const wwwMappings = { - '@lexical/clipboard': 'LexicalClipboard', - '@lexical/code': 'LexicalCode', - '@lexical/devtools-core': 'LexicalDevtoolsCore', - '@lexical/dragon': 'LexicalDragon', - '@lexical/file': 'LexicalFile', - '@lexical/hashtag': 'LexicalHashtag', - '@lexical/headless': 'LexicalHeadless', - '@lexical/history': 'LexicalHistory', - '@lexical/html': 'LexicalHtml', - '@lexical/link': 'LexicalLink', - '@lexical/list': 'LexicalList', - '@lexical/mark': 'LexicalMark', - '@lexical/markdown': 'LexicalMarkdown', - '@lexical/offset': 'LexicalOffset', - '@lexical/overflow': 'LexicalOverflow', - '@lexical/plain-text': 'LexicalPlainText', - '@lexical/rich-text': 'LexicalRichText', - '@lexical/selection': 'LexicalSelection', - '@lexical/table': 'LexicalTable', - '@lexical/text': 'LexicalText', - '@lexical/utils': 'LexicalUtils', - '@lexical/yjs': 'LexicalYjs', - lexical: 'Lexical', + ...Object.fromEntries( + packagesManager + .getPublicPackages() + .flatMap((pkg) => + pkg.getExportedNpmModuleNames().map((npm) => [npm, npmToWwwName(npm)]), + ), + ), 'prismjs/components/prism-c': 'prism-c', 'prismjs/components/prism-clike': 'prism-clike', 'prismjs/components/prism-core': 'prismjs', @@ -88,22 +74,13 @@ const wwwMappings = { 'react-dom': 'ReactDOMComet', }; -const lexicalReactModules = fs - .readdirSync(path.resolve('./packages/lexical-react/src')) - .filter( - (str) => - !str.includes('__tests__') && - !str.includes('shared') && - !str.includes('test-utils'), - ); - -const lexicalReactModuleExternals = lexicalReactModules.map((module) => { - const basename = path.basename(path.basename(module, '.ts'), '.tsx'); - const external = `@lexical/react/${basename}`; - wwwMappings[external] = basename; - return external; -}); - +/** + * Fix ESM imports of prismjs components that rely on a wildcard export, these + * must have a '.js' extension to be resolved correctly. + * + * @param {string} id the module id to resolve + * @returns {string} the module name with '.js' extension if necessary + */ function resolveExternalEsm(id) { if (/^prismjs\/components\/prism-/.test(id)) { return `${id}.js`; @@ -111,52 +88,19 @@ function resolveExternalEsm(id) { return id; } +/** + * The set of all modules that should remain external to our published + * packages, should include all public monorepo packages and the third + * party dependencies or peerDependencies that we do not want to include + * in the bundles. + */ const externals = [ - 'lexical', - 'prismjs/components/prism-core', - 'prismjs/components/prism-clike', - 'prismjs/components/prism-javascript', - 'prismjs/components/prism-markup', - 'prismjs/components/prism-markdown', - 'prismjs/components/prism-c', - 'prismjs/components/prism-css', - 'prismjs/components/prism-objectivec', - 'prismjs/components/prism-sql', - 'prismjs/components/prism-python', - 'prismjs/components/prism-rust', - 'prismjs/components/prism-swift', - 'prismjs/components/prism-typescript', - 'prismjs/components/prism-java', - 'prismjs/components/prism-cpp', - '@lexical/list', - '@lexical/table', - '@lexical/file', - '@lexical/clipboard', - '@lexical/devtools-core', - '@lexical/hashtag', - '@lexical/headless', - '@lexical/html', - '@lexical/history', - '@lexical/selection', - '@lexical/text', - '@lexical/offset', - '@lexical/utils', - '@lexical/code', - '@lexical/yjs', - '@lexical/plain-text', - '@lexical/rich-text', - '@lexical/mark', - '@lexical/dragon', - '@lexical/overflow', - '@lexical/link', - '@lexical/markdown', + ...Object.entries(wwwMappings).flat(), 'react-dom', 'react', 'yjs', 'y-websocket', - ...lexicalReactModuleExternals, - ...Object.values(wwwMappings), -]; +].sort(); const errorCodeOpts = { errorMapFilePath: 'scripts/error-codes/codes.json', @@ -171,10 +115,24 @@ Object.keys(wwwMappings).forEach((mapping) => { strictWWWMappings[`'${mapping}'`] = `'${wwwMappings[mapping]}'`; }); +/** + * @param {'esm'|'cjs'} format + * @returns {'.mjs'|'.js'} the correct file extension for this export format + */ function getExtension(format) { return `.${format === 'esm' ? 'm' : ''}js`; } +/** + * + * @param {string} name + * @param {string} inputFile + * @param {string} outputPath + * @param {string} outputFile + * @param {boolean} isProd + * @param {'cjs'|'esm'} format + * @returns {Promise>} the exports of the built module + */ async function build(name, inputFile, outputPath, outputFile, isProd, format) { const extensions = ['.js', '.jsx', '.ts', '.tsx']; const inputOptions = { @@ -308,21 +266,29 @@ async function build(name, inputFile, outputPath, outputFile, isProd, format) { } function getComment() { - const lines = ['/**', license]; - if (isWWW) { - lines.push( - '*', - '* @fullSyntaxTransform', - '* @generated', - '* @noflow', - '* @nolint', - '* @oncall lexical_web_text_editor', - '* @preserve-invariant-messages', - '* @preserve-whitespace', - '* @preventMunge', + if (!isWWW) { + return headerTemplate; + } + const lines = headerTemplate.split(/\n/g); + const idx = lines.indexOf(' */'); + if (idx === -1) { + throw new Error( + `Expecting scripts/www/headerTemplate.js to have a ' */' line`, ); } - lines.push(' */'); + lines.splice( + idx, + 0, + ' *', + ' * @fullSyntaxTransform', + ' * @generated', + ' * @noflow', + ' * @nolint', + ' * @oncall lexical_web_text_editor', + ' * @preserve-invariant-messages', + ' * @preserve-whitespace', + ' * @preventMunge', + ); return lines.join('\n'); } @@ -334,320 +300,38 @@ function getFileName(fileName, isProd, format) { return `${fileName}${extension}`; } -const packages = [ - { - modules: [ - { - outputFileName: 'Lexical', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Core', - outputPath: './packages/lexical/dist/', - packageName: 'lexical', - sourcePath: './packages/lexical/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalList', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical List', - outputPath: './packages/lexical-list/dist/', - packageName: 'lexical-list', - sourcePath: './packages/lexical-list/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalTable', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Table', - outputPath: './packages/lexical-table/dist/', - packageName: 'lexical-table', - sourcePath: './packages/lexical-table/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalFile', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical File', - outputPath: './packages/lexical-file/dist/', - packageName: 'lexical-file', - sourcePath: './packages/lexical-file/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalClipboard', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical File', - outputPath: './packages/lexical-clipboard/dist/', - packageName: 'lexical-clipboard', - sourcePath: './packages/lexical-clipboard/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalHashtag', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Hashtag', - outputPath: './packages/lexical-hashtag/dist/', - packageName: 'lexical-hashtag', - sourcePath: './packages/lexical-hashtag/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalHistory', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical History', - outputPath: './packages/lexical-history/dist/', - packageName: 'lexical-history', - sourcePath: './packages/lexical-history/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalSelection', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Selection', - outputPath: './packages/lexical-selection/dist/', - packageName: 'lexical-selection', - sourcePath: './packages/lexical-selection/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalText', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Text', - outputPath: './packages/lexical-text/dist/', - packageName: 'lexical-text', - sourcePath: './packages/lexical-text/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalOffset', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Offset', - outputPath: './packages/lexical-offset/dist/', - packageName: 'lexical-offset', - sourcePath: './packages/lexical-offset/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalUtils', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Utils', - outputPath: './packages/lexical-utils/dist/', - packageName: 'lexical-utils', - sourcePath: './packages/lexical-utils/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalCode', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Code', - outputPath: './packages/lexical-code/dist/', - packageName: 'lexical-code', - sourcePath: './packages/lexical-code/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalDragon', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Dragon', - outputPath: './packages/lexical-dragon/dist/', - packageName: 'lexical-dragon', - sourcePath: './packages/lexical-dragon/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalDevtoolsCore', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Devtools Core', - outputPath: './packages/lexical-devtools-core/dist/', - packageName: 'lexical-devtools-core', - sourcePath: './packages/lexical-devtools-core/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalLink', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Link', - outputPath: './packages/lexical-link/dist/', - packageName: 'lexical-link', - sourcePath: './packages/lexical-link/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalOverflow', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Overflow', - outputPath: './packages/lexical-overflow/dist/', - packageName: 'lexical-overflow', - sourcePath: './packages/lexical-overflow/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalPlainText', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Plain Text', - outputPath: './packages/lexical-plain-text/dist/', - packageName: 'lexical-plain-text', - sourcePath: './packages/lexical-plain-text/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalRichText', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Rich Text', - outputPath: './packages/lexical-rich-text/dist/', - packageName: 'lexical-rich-text', - sourcePath: './packages/lexical-rich-text/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalMarkdown', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Markdown', - outputPath: './packages/lexical-markdown/dist/', - packageName: 'lexical-markdown', - sourcePath: './packages/lexical-markdown/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalHeadless', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Headless', - outputPath: './packages/lexical-headless/dist/', - packageName: 'lexical-headless', - sourcePath: './packages/lexical-headless/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalHtml', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical HTML', - outputPath: './packages/lexical-html/dist/', - packageName: 'lexical-html', - sourcePath: './packages/lexical-html/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalMark', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Mark', - outputPath: './packages/lexical-mark/dist/', - packageName: 'lexical-mark', - sourcePath: './packages/lexical-mark/src/', - }, - { - modules: lexicalReactModules - .filter((module) => { - // We don't want to sync these modules, as they're bundled in the other - // modules already. - const ignoredModules = [ - 'useLexicalDragonSupport', - 'usePlainTextSetup', - 'useRichTextSetup', - 'useYjsCollaboration', - ]; - - return !ignoredModules.includes(module); - }) - .map((module) => { - const basename = path.basename(path.basename(module, '.ts'), '.tsx'); - return { - name: basename, - outputFileName: basename, - sourceFileName: module, - }; - }), - name: 'Lexical React', - outputPath: './packages/lexical-react/dist/', - packageName: 'lexical-react', - sourcePath: './packages/lexical-react/src/', - }, - { - modules: [ - { - outputFileName: 'LexicalYjs', - sourceFileName: 'index.ts', - }, - ], - name: 'Lexical Yjs', - outputPath: './packages/lexical-yjs/dist/', - packageName: 'lexical-yjs', - sourcePath: './packages/lexical-yjs/src/', - }, -]; - +/** + * + * @param {string} packageName + * @param {string} outputPath + */ async function buildTSDeclarationFiles(packageName, outputPath) { await exec('tsc -p ./tsconfig.build.json'); } -async function moveTSDeclarationFilesIntoDist(packageName, outputPath) { - await fs.copy(`./.ts-temp/${packageName}/src`, outputPath); +/** + * + * @param {string} packageName + * @param {string} outputPath + */ +function moveTSDeclarationFilesIntoDist(packageName, outputPath) { + fs.copySync(`./.ts-temp/packages/${packageName}/src`, outputPath); } +/** + * @typedef {Object} ForkModuleContentOptions + * @property {string} devFileName + * @property {Array} exports + * @property {string} outputFileName + * @property {string} prodFileName + */ + +/** + * + * @param {ForkModuleContentOptions} opts + * @param {'cjs'|'esm'|'node'} target + * @returns {string} + */ function forkModuleContent( {devFileName, exports, outputFileName, prodFileName}, target, @@ -682,20 +366,25 @@ function forkModuleContent( return lines.join('\n'); } +/** + * + * @param {string} outputPath + * @param {string} outputFileName + * @param {'cjs'|'esm'} format + * @param {Array} exports + */ function buildForkModules(outputPath, outputFileName, format, exports) { const extension = getExtension(format); const devFileName = `./${outputFileName}.dev${extension}`; const prodFileName = `./${outputFileName}.prod${extension}`; const opts = {devFileName, exports, outputFileName, prodFileName}; fs.outputFileSync( - path.resolve(path.join(`${outputPath}${outputFileName}${extension}`)), + path.resolve(outputPath, `${outputFileName}${extension}`), forkModuleContent(opts, format), ); if (format === 'esm') { fs.outputFileSync( - path.resolve( - path.join(`${outputPath}${outputFileName}.node${extension}`), - ), + path.resolve(outputPath, `${outputFileName}.node${extension}`), forkModuleContent(opts, 'node'), ); } @@ -706,32 +395,22 @@ async function buildAll() { await buildTSDeclarationFiles(); } - for (const pkg of packages) { - const {name, sourcePath, outputPath, packageName, modules} = pkg; - + const formats = isWWW ? ['cjs'] : ['cjs', 'esm']; + for (const pkg of packagesManager.getPublicPackages()) { + const {name, sourcePath, outputPath, packageName, modules} = + pkg.getPackageBuildDefinition(); for (const module of modules) { - for (const format of ['cjs', 'esm']) { - if (isWWW && format === 'esm') { - break; - } - + for (const format of formats) { const {sourceFileName, outputFileName} = module; - let inputFile = path.resolve( - path.join(`${sourcePath}${sourceFileName}`), - ); + const inputFile = path.resolve(sourcePath, sourceFileName); await build( `${name}${module.name ? '-' + module.name : ''}`, inputFile, outputPath, path.resolve( - path.join( - `${outputPath}${getFileName( - outputFileName, - isProduction, - format, - )}`, - ), + outputPath, + getFileName(outputFileName, isProduction, format), ), isProduction, format, @@ -743,9 +422,8 @@ async function buildAll() { inputFile, outputPath, path.resolve( - path.join( - `${outputPath}${getFileName(outputFileName, false, format)}`, - ), + outputPath, + getFileName(outputFileName, false, format), ), false, format, @@ -756,7 +434,7 @@ async function buildAll() { } if (!isWWW && (isRelease || isProduction)) { - await moveTSDeclarationFilesIntoDist(packageName, outputPath); + moveTSDeclarationFilesIntoDist(packageName, outputPath); } } } diff --git a/scripts/clean.js b/scripts/clean.js index 3febac50b1a..4f0bda094c5 100644 --- a/scripts/clean.js +++ b/scripts/clean.js @@ -9,12 +9,12 @@ 'use strict'; const fs = require('fs-extra'); -const path = require('path'); -const {LEXICAL_PKG, DEFAULT_PKGS, SHARED_PKG} = require('./npm/packages'); +const path = require('node:path'); +const {packagesManager} = require('./shared/packagesManager'); -const packages = [LEXICAL_PKG, ...DEFAULT_PKGS, SHARED_PKG]; -packages.forEach((pkg) => { - fs.removeSync(path.resolve(`./.ts-temp`)); - fs.removeSync(path.resolve(`./packages/${pkg}/dist`)); - fs.removeSync(path.resolve(`./packages/${pkg}/npm`)); -}); +fs.removeSync(path.resolve(`./.ts-temp`)); +packagesManager + .getPublicPackages() + .forEach((pkg) => + ['dist', 'npm'].forEach((subdir) => fs.removeSync(pkg.resolve(subdir))), + ); diff --git a/scripts/error-codes/extract-errors.js b/scripts/error-codes/extract-errors.js index fc12e8c9739..0720f8b20ad 100644 --- a/scripts/error-codes/extract-errors.js +++ b/scripts/error-codes/extract-errors.js @@ -9,7 +9,7 @@ 'use strict'; const parser = require('@babel/parser'); -const fs = require('fs'); +const fs = require('fs-extra'); const path = require('path'); const traverse = require('@babel/traverse').default; const evalToString = require('./evalToString'); @@ -42,14 +42,11 @@ module.exports = function (opts) { const errorMapFilePath = opts.errorMapFilePath; let existingErrorMap; try { - // Using `fs.readFileSync` instead of `require` here, because `require()` + // Using `fs.readJsonSync` instead of `require` here, because `require()` // calls are cached, and the cache map is not properly invalidated after // file changes. - existingErrorMap = JSON.parse( - fs.readFileSync( - path.join(__dirname, path.basename(errorMapFilePath)), - 'utf8', - ), + existingErrorMap = fs.readJsonSync( + path.join(__dirname, path.basename(errorMapFilePath)), ); } catch (e) { existingErrorMap = {}; @@ -95,11 +92,9 @@ module.exports = function (opts) { } function flush(cb) { - fs.writeFileSync( - errorMapFilePath, - JSON.stringify(invertObject(existingErrorMap), null, 2) + '\n', - 'utf-8', - ); + fs.writeJsonSync(errorMapFilePath, invertObject(existingErrorMap), { + spaces: 2, + }); } return function extractErrors(source) { diff --git a/scripts/error-codes/transform-error-messages.js b/scripts/error-codes/transform-error-messages.js index 6dd338703fe..4bf93a80284 100644 --- a/scripts/error-codes/transform-error-messages.js +++ b/scripts/error-codes/transform-error-messages.js @@ -8,7 +8,7 @@ 'use strict'; -const fs = require('fs'); +const fs = require('fs-extra'); const evalToString = require('./evalToString'); const invertObject = require('./invertObject'); const helperModuleImports = require('@babel/helper-module-imports'); @@ -82,9 +82,7 @@ module.exports = function (babel) { } // Avoid caching because we write it as we go. - const existingErrorMap = JSON.parse( - fs.readFileSync(__dirname + '/codes.json', 'utf-8'), - ); + const existingErrorMap = fs.readJsonSync(__dirname + '/codes.json'); const errorMap = invertObject(existingErrorMap); let prodErrorId = errorMap[errorMsgLiteral]; diff --git a/scripts/generate-flow-types.sh b/scripts/generate-flow-types.sh deleted file mode 100755 index 189ddc145e7..00000000000 --- a/scripts/generate-flow-types.sh +++ /dev/null @@ -1,24 +0,0 @@ -for package in 'lexical' \ - 'lexical-react' \ - 'lexical-yjs' \ - 'lexical-list' \ - 'lexical-table' \ - 'lexical-file' \ - 'lexical-clipboard' \ - 'lexical-hashtag' \ - 'lexical-history' \ - 'lexical-selection' \ - 'lexical-offset' \ - 'lexical-code' \ - 'lexical-plain-text' \ - 'lexical-rich-text' \ - 'lexical-utils' \ - 'lexical-dragon' \ - 'lexical-overflow' \ - 'lexical-link' \ - 'lexical-text' \ - 'lexical-markdown' \ - 'lexical-mark' -do - gen-flow-files "./packages/${package}/src" --out-dir "./packages/${package}/dist" -done \ No newline at end of file diff --git a/scripts/npm/increment-version.js b/scripts/npm/increment-version.js index aea4a940d46..2e802a510d9 100644 --- a/scripts/npm/increment-version.js +++ b/scripts/npm/increment-version.js @@ -12,6 +12,7 @@ const {exec} = require('child-process-promise'); const argv = require('minimist')(process.argv.slice(2)); + const increment = argv.i; const validIncrements = new Set(['minor', 'patch', 'prerelease']); if (!validIncrements.has(increment)) { @@ -19,11 +20,11 @@ if (!validIncrements.has(increment)) { process.exit(1); } -async function incrementVersion(increment) { +async function incrementVersion() { const preId = increment === 'prerelease' ? '--preid next' : ''; const workspaces = ''; const command = `npm --no-git-tag-version version ${increment} --include-workspace-root true ${preId} ${workspaces}`; await exec(command); } -incrementVersion(increment); +incrementVersion(); diff --git a/scripts/npm/packages.js b/scripts/npm/packages.js deleted file mode 100644 index 2e553353f00..00000000000 --- a/scripts/npm/packages.js +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env node - -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -'use strict'; - -const LEXICAL_PKG = 'lexical'; -const DEFAULT_PKGS = [ - 'lexical-react', - 'lexical-yjs', - 'lexical-list', - 'lexical-table', - 'lexical-file', - 'lexical-clipboard', - 'lexical-hashtag', - 'lexical-headless', - 'lexical-html', - 'lexical-history', - 'lexical-selection', - 'lexical-offset', - 'lexical-code', - 'lexical-plain-text', - 'lexical-rich-text', - 'lexical-utils', - 'lexical-dragon', - 'lexical-overflow', - 'lexical-link', - 'lexical-text', - 'lexical-markdown', - 'lexical-mark', -]; -const SHARED_PKG = 'shared'; - -module.exports = { - DEFAULT_PKGS, - LEXICAL_PKG, - SHARED_PKG, -}; diff --git a/scripts/npm/prepare-release.js b/scripts/npm/prepare-release.js index b7ba6646165..f3b25f7727a 100644 --- a/scripts/npm/prepare-release.js +++ b/scripts/npm/prepare-release.js @@ -10,46 +10,48 @@ 'use strict'; -const {exec} = require('child-process-promise'); -const {LEXICAL_PKG, DEFAULT_PKGS} = require('./packages'); +const fs = require('fs-extra'); +const glob = require('glob'); +const path = require('node:path'); +const {packagesManager} = require('../shared/packagesManager'); -async function prepareLexicalPackage() { - await exec(`rm -rf ./packages/${LEXICAL_PKG}/npm`); - await exec(`mkdir ./packages/${LEXICAL_PKG}/npm`); - await exec( - `cp -R ./packages/${LEXICAL_PKG}/dist/* ./packages/${LEXICAL_PKG}/npm`, - ); - - // Other bits - await exec( - `cp -R ./packages/${LEXICAL_PKG}/package.json ./packages/${LEXICAL_PKG}/npm`, +/** + * Cleans the npm dir from the package and constructs it with: + * - All the files from the pkg dist (recursively) + * - All of the *.flow files from the pkg flow (not recursively) + * - The package.json and README.md from pkg + * - The LICENSE file from the monorepo root + * + * @param {import('../shared/PackageMetadata').PackageMetadata} pkg the directory name of the package to process (e.g. 'lexical-rich-text') + */ +function preparePackage(pkg) { + console.log( + `Preparing packages/${pkg.getDirectoryName()} for release as ${pkg.getNpmName()}`, ); - await exec(`cp -R LICENSE ./packages/${LEXICAL_PKG}/npm`); - await exec( - `cp -R ./packages/${LEXICAL_PKG}/README.md ./packages/${LEXICAL_PKG}/npm`, + fs.removeSync(pkg.resolve('npm')); + fs.ensureDirSync(pkg.resolve('npm')); + fs.copySync(pkg.resolve('dist'), pkg.resolve('npm')); + const flowSources = glob.sync(pkg.resolve('flow', '*.flow')); + if (flowSources.length === 0) { + console.error( + `Missing Flow type definitions for package ${pkg.getDirectoryName()}`, + ); + } + flowSources.forEach((flowSource) => + fs.copySync(flowSource, pkg.resolve('npm', path.basename(flowSource))), ); - // Flow Types - await exec( - `cp -R ./packages/${LEXICAL_PKG}/flow/*.flow ./packages/${LEXICAL_PKG}/npm`, + ['package.json', 'README.md'].forEach((fn) => + fs.copySync(pkg.resolve(fn), pkg.resolve('npm', fn)), ); + fs.copySync('LICENSE', pkg.resolve('npm', 'LICENSE')); } -async function prepareDefaultPackages() { - for (let i = 0; i < DEFAULT_PKGS.length; i++) { - const pkg = DEFAULT_PKGS[i]; - await exec(`rm -rf ./packages/${pkg}/npm`); - await exec(`mkdir ./packages/${pkg}/npm`); - await exec(`cp -R ./packages/${pkg}/dist/* ./packages/${pkg}/npm`); - try { - await exec(`cp -R ./packages/${pkg}/flow/*.flow ./packages/${pkg}/npm`); - } catch { - console.error(`Missing Flow type definitions for package ${pkg}`); - } - await exec(`cp -R ./packages/${pkg}/package.json ./packages/${pkg}/npm`); - await exec(`cp -R LICENSE ./packages/${pkg}/npm`); - await exec(`cp -R ./packages/${pkg}/README.md ./packages/${pkg}/npm`); - } +/** + * Prepares the npm directories for all public packages. If a package should + * not be published, make sure to set `"private": true` in its package.json. + */ +function preparePublicPackages() { + packagesManager.getPublicPackages().forEach(preparePackage); } -prepareLexicalPackage(); -prepareDefaultPackages(); +preparePublicPackages(); diff --git a/scripts/npm/release.js b/scripts/npm/release.js index 6dd1094e7ce..03f09e38f63 100644 --- a/scripts/npm/release.js +++ b/scripts/npm/release.js @@ -12,7 +12,7 @@ const readline = require('readline'); const {exec} = require('child-process-promise'); -const {LEXICAL_PKG, DEFAULT_PKGS} = require('./packages'); +const {packagesManager} = require('../shared/packagesManager'); const argv = require('minimist')(process.argv.slice(2)); const nonInteractive = argv['non-interactive']; @@ -25,23 +25,22 @@ if (!validChannels.has(channel)) { } async function publish() { - const pkgs = [LEXICAL_PKG, ...DEFAULT_PKGS]; + const pkgs = packagesManager.getPublicPackages(); if (!nonInteractive) { console.info( `You're about to publish: - ${pkgs.join('\n')} + ${pkgs.map((pkg) => pkg.getNpmName()).join('\n')} Type "publish" to confirm.`, ); await waitForInput(); } - for (let i = 0; i < pkgs.length; i++) { - const pkg = pkgs[i]; - console.info(`Publishing ${pkg}...`); + for (const pkg of pkgs) { + console.info(`Publishing ${pkg.getNpmName()}...`); if (dryRun === undefined || dryRun === 0) { await exec( - `cd ./packages/${pkg}/npm && npm publish --access public --tag ${channel}`, + `cd ./packages/${pkg.getDirectoryName()}/npm && npm publish --access public --tag ${channel}`, ); console.info(`Done!`); } else { diff --git a/scripts/shared/PackageMetadata.js b/scripts/shared/PackageMetadata.js new file mode 100644 index 00000000000..fcc9b0861ff --- /dev/null +++ b/scripts/shared/PackageMetadata.js @@ -0,0 +1,210 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +// @ts-check +'use strict'; + +const path = require('node:path'); +const fs = require('fs-extra'); +const npmToWwwName = require('../www/npmToWwwName'); + +/** + * @typedef {Object} ModuleBuildDefinition + * @property {string} outputFileName + * @property {string} sourceFileName + */ + +/** + * @typedef {Object} PackageBuildDefinition + * @property {Array} modules + * @property {string} name + * @property {string} outputPath + * @property {string} packageName + * @property {string} sourcePath + */ + +/** + * @typedef {Object} ModuleExportEntry + * @property {string} name + * @property {string} sourceFileName + */ + +/** + * @typedef {readonly [string, Record<'import'|'require', Object>]} NpmModuleExportEntry + */ + +/** + * + * @param {string} wwwName + * @returns {string} An easier to read name ('Lexical' -> 'Lexical Core', 'LexicalRichText' -> 'Lexical Rich Text') + */ +function readableName(wwwName) { + return wwwName === 'Lexical' + ? 'Lexical Core' + : wwwName.replace(/([A-Z])/g, ' $1').trim(); +} + +/** + * Metadata abstraction for a package.json file + */ +class PackageMetadata { + /** @type {string} the path to the package.json file */ + packageJsonPath; + /** @type {Record} the parsed package.json */ + packageJson; + + /** + * @param {string} packageJsonPath the path to the package.json file + */ + constructor(packageJsonPath) { + this.packageJsonPath = packageJsonPath; + this.packageJson = fs.readJsonSync(packageJsonPath); + } + + /** + * @param {...string} paths to resolve in this package's directory + * @returns {string} Resolve a path in this package's directory + */ + resolve(...paths) { + return path.resolve(path.dirname(this.packageJsonPath), ...paths); + } + + /** + * @returns {string} the directory name of the package, e.g. 'lexical-rich-text' + */ + getDirectoryName() { + return path.basename(path.dirname(this.packageJsonPath)); + } + + /** + * @returns {string} the npm name of the package, e.g. '@lexical/rich-text' + */ + getNpmName() { + return this.packageJson.name; + } + + /** + * @returns {boolean} whether the package is marked private (not published to npm) + */ + isPrivate() { + return !!this.packageJson.private; + } + + /** + * Get an array of (fully qualified) exported module names and their + * corresponding export map. Ignores the backwards compatibility '.js' + * exports and replaces /^.[/]?/ with the npm name of the package. + * + * E.g. [['lexical', {...}]] or [['@lexical/react/LexicalComposer', {...}] + * + * @returns {Array} + */ + getNormalizedNpmModuleExportEntries() { + // It doesn't make much sense to do this for private modules + if (this.isPrivate()) { + throw new Error('This should only be called on public packages'); + } + // All our packages should have exports if update-version has been run + if (!this.packageJson.exports) { + throw new Error( + 'This package should have exports, try `npm run update-version` first', + ); + } + /** @type {Array} */ + const entries = []; + for (const [key, value] of Object.entries(this.packageJson.exports)) { + if (key.endsWith('.js')) { + continue; + } + entries.push([`${this.getNpmName()}${key.replace(/^./, '')}`, value]); + } + return entries.sort((a, b) => a[0].localeCompare(b[0])); + } + + /** + * @returns {Array} the npm module names that this package exports + */ + getExportedNpmModuleNames() { + return this.getNormalizedNpmModuleExportEntries().map(([name]) => name); + } + + /** + * The entries of npm module names to their .tsx? source files + * + * @returns {Array} + */ + getExportedNpmModuleEntries() { + const npmName = this.getNpmName(); + return this.getExportedNpmModuleNames().map((name) => { + const outputFileName = npmToWwwName(name); + const sourceBaseName = name === npmName ? 'index' : outputFileName; + const sourceCandidates = ['.ts', '.tsx'].map( + (ext) => sourceBaseName + ext, + ); + const sourceFileName = sourceCandidates.find((fn) => + fs.existsSync(this.resolve('src', fn)), + ); + if (!sourceFileName) { + throw new Error( + `Could not find source file for ${name} at packages/${this.getDirectoryName()}/src/${ + sourceCandidates[0] + }?`, + ); + } + return {name, sourceFileName}; + }); + } + + /** + * The map of import module names to their .tsx? source files + * (for private modules such as shared) + * + * @returns {Array} + */ + getPrivateModuleEntries() { + const npmName = this.getNpmName(); + const entries = []; + for (const sourceFileName of fs.readdirSync(this.resolve('src'))) { + const m = /^([^.]+)\.tsx?$/.exec(sourceFileName); + if (m) { + entries.push({ + name: m[1] === 'index' ? npmName : `${npmName}/${m[1]}`, + sourceFileName, + }); + } + } + return entries.sort((a, b) => a.name.localeCompare(b.name)); + } + + /** + * @returns {PackageBuildDefinition} + */ + getPackageBuildDefinition() { + const npmName = this.getNpmName(); + return { + modules: this.getExportedNpmModuleEntries().map( + ({name, sourceFileName}) => ({ + outputFileName: npmToWwwName(name), + sourceFileName, + }), + ), + name: readableName(npmToWwwName(npmName)), + outputPath: this.resolve('dist/'), + packageName: this.getDirectoryName(), + sourcePath: this.resolve('src/'), + }; + } + + /** + * Writes this.packageJson back to this.packageJsonPath + */ + writeSync() { + fs.writeJsonSync(this.packageJsonPath, this.packageJson, {spaces: 2}); + } +} + +exports.PackageMetadata = PackageMetadata; diff --git a/scripts/shared/packagesManager.js b/scripts/shared/packagesManager.js new file mode 100644 index 00000000000..6042a6e0970 --- /dev/null +++ b/scripts/shared/packagesManager.js @@ -0,0 +1,97 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +// @ts-check +'use strict'; + +const path = require('node:path'); +const glob = require('glob'); + +const {PackageMetadata} = require('./PackageMetadata'); + +/** + * + * @param {PackageMetadata} a + * @param {PackageMetadata} b + * @returns {number} + */ +function packageSort(a, b) { + return a.getDirectoryName().localeCompare(b.getDirectoryName()); +} + +/** Cache of all PackageMetadata for the packages directory */ +class PackagesManager { + /** @type {Array} */ + packages; + + /** + * @param {Array} packagePaths + */ + constructor(packagePaths) { + this.packages = packagePaths + .map((packagePath) => new PackageMetadata(packagePath)) + .sort(packageSort); + } + + /** + * Get the PackageMetadata for a package by its npm name. + * @param {string} name + * @returns {PackageMetadata} + */ + getPackageByNpmName(name) { + const pkg = this.packages.find( + (candidate) => candidate.getNpmName() === name, + ); + if (!pkg) { + throw new Error(`Missing package with npm name '${name}'`); + } + return pkg; + } + + /** + * Get the PackageMetadata for a package by its npm name. + * @param {string} name + * @returns {PackageMetadata} + */ + getPackageByDirectoryName(name) { + const pkg = this.packages.find( + (candidate) => candidate.getDirectoryName() === name, + ); + if (!pkg) { + throw new Error(`Missing package with directory name '${name}'`); + } + return pkg; + } + + /** + * Get the cached metadata for all packages in the packages directory, + * sorted by directory name. + * @returns {Array} + */ + getPackages() { + return this.packages; + } + + /** + * Get the cached metadata for packages in the packages directory + * where the private field is not set to true, sorted by directory + * name ('lexical' will come before 'lexical-*'). + * @returns {Array} + */ + getPublicPackages() { + return this.packages.filter((pkg) => !pkg.isPrivate()); + } +} + +exports.packagesManager = new PackagesManager( + glob.sync( + path.resolve( + path.dirname(path.dirname(__dirname)), + 'packages/*/package.json', + ), + ), +); diff --git a/scripts/shared/readMonorepoPackageJson.js b/scripts/shared/readMonorepoPackageJson.js new file mode 100644 index 00000000000..b905b31eb22 --- /dev/null +++ b/scripts/shared/readMonorepoPackageJson.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +// @ts-check +'use strict'; + +const fs = require('fs-extra'); +const path = require('node:path'); + +module.exports = function readMonorepoPackageJson() { + return fs.readJsonSync(path.resolve(__dirname, '../../package.json')); +}; diff --git a/scripts/update-docs.js b/scripts/update-docs.js new file mode 100644 index 00000000000..6bbfd68cf1e --- /dev/null +++ b/scripts/update-docs.js @@ -0,0 +1,69 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +// @ts-check +'use strict'; + +const fs = require('fs-extra'); +const path = require('node:path'); +const {packagesManager} = require('./shared/packagesManager'); + +const webPkg = packagesManager.getPackageByDirectoryName('lexical-website'); + +function sidebarTemplate(npmName, readmePath) { + return ( + ` +--- +title: '' +sidebar_label: '${npmName}' +--- + +{@import ${readmePath}} +`.trim() + '\n' + ); +} + +function readmeTemplate(npmName) { + return ( + ` + # \`${npmName}\` + +[![See API Documentation](https://lexical.dev/img/see-api-documentation.svg)](https://lexical.dev/docs/api/modules/lexical_devtools_core) + +TODO: This package needs a description! +`.trim() + '\n' + ); +} + +function updateDocs() { + packagesManager.getPublicPackages().forEach((pkg) => { + const npmName = pkg.getNpmName(); + const root = pkg.resolve('..', '..'); + const readmePath = pkg.resolve('README.md'); + const sidebarPath = webPkg.resolve( + 'docs', + 'packages', + `${pkg.getDirectoryName()}.md`, + ); + if (!fs.existsSync(readmePath)) { + console.log(`Creating ${path.relative(root, readmePath)}`); + fs.writeFileSync(readmePath, readmeTemplate(npmName)); + } + if (!fs.existsSync(sidebarPath)) { + console.log(`Creating ${path.relative(root, sidebarPath)}`); + fs.writeFileSync( + sidebarPath, + sidebarTemplate( + npmName, + path.relative(path.dirname(sidebarPath), readmePath), + ), + ); + } + }); +} + +updateDocs(); diff --git a/scripts/update-flowconfig.js b/scripts/update-flowconfig.js new file mode 100644 index 00000000000..50bdbca46e8 --- /dev/null +++ b/scripts/update-flowconfig.js @@ -0,0 +1,73 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +// @ts-check +'use strict'; + +const fs = require('fs-extra'); +const path = require('node:path'); +const {packagesManager} = require('./shared/packagesManager'); +const npmToWwwName = require('./www/npmToWwwName'); + +const BLOCK_REGEX = + /^([\s\S]+?\n;; \[generated-start update-flowconfig\]\n)([\s\S]*?)(;; \[generated-end update-flowconfig\][\s\S]+)$/; + +/** + * @param {string} configContents + * @param {string} generatedCode + */ +function replaceBlock(configContents, generatedCode) { + const m = configContents.match(BLOCK_REGEX); + if (!m) { + throw new Error( + `update-flowconfig block not found in .flowconfig, expecting ';; [generated-start update-flowconfig]' followed by ';; [generated-end update-flowconfig]`, + ); + } + return `${m[1]}${generatedCode}${m[3]}`; +} + +function updateFlowconfig(flowconfigPath = './.flowconfig') { + const prevConfig = fs.readFileSync(flowconfigPath, 'utf8'); + const configDir = path.resolve(path.dirname(flowconfigPath)); + /** @type {Array} */ + const generatedBlock = []; + const emit = (moduleName, flowFilename) => + generatedBlock.push( + `module.name_mapper='^${moduleName}$' -> '${flowFilename}'\n`, + ); + for (const pkg of packagesManager.getPackages()) { + const resolveRelative = (...subPaths) => + '/' + + path.relative(configDir, pkg.resolve(...subPaths)).replace(/^(?!\.)/, ''); + if (pkg.isPrivate()) { + if (pkg.getDirectoryName() !== 'shared') { + continue; + } + if (process.env.TODO_DOES_WWW_NEED_SHARED_FILES === '1') { + // Do these even work? These .js files aren't on disk and `npm run flow` + // passes without them. Code is left in for demonstration purposes if + // this is needed for www. + for (const {name, sourceFileName} of pkg.getPrivateModuleEntries()) { + emit( + name, + resolveRelative('src', sourceFileName.replace(/\.tsx?$/, '.js')), + ); + } + } + } else { + for (const name of pkg.getExportedNpmModuleNames()) { + emit(name, resolveRelative('flow', `${npmToWwwName(name)}.js.flow`)); + } + } + } + const nextConfig = replaceBlock(prevConfig, generatedBlock.join('')); + if (prevConfig !== nextConfig) { + fs.writeFileSync(flowconfigPath, nextConfig); + } +} + +updateFlowconfig(); diff --git a/scripts/update-tsconfig.js b/scripts/update-tsconfig.js new file mode 100644 index 00000000000..4efa7a9cbd6 --- /dev/null +++ b/scripts/update-tsconfig.js @@ -0,0 +1,92 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +// @ts-check +'use strict'; + +const fs = require('fs-extra'); +const glob = require('glob'); +const path = require('node:path'); +const prettier = require('prettier'); +const {packagesManager} = require('./shared/packagesManager'); + +/** + * @typedef {Object} UpdateTsconfigOptions + * @property {string} jsonFileName path to the tsconfig.json + * @property {boolean} test true to include the test paths (default: false) + * @property {Array<[string, Array]>} extraPaths additional paths to add + */ + +/** + * @param {opts} UpdateTsconfigOptions + */ +function updateTsconfig({jsonFileName, test = false, extraPaths = []}) { + const tsconfig = fs.readJsonSync(jsonFileName); + const prev = JSON.stringify(tsconfig.compilerOptions.paths); + const publicPaths = []; + const privatePaths = []; + const testPaths = []; + const configDir = path.resolve(path.dirname(jsonFileName)); + for (const pkg of packagesManager.getPackages()) { + const resolveRelative = (...subPaths) => + path + .relative(configDir, pkg.resolve(...subPaths)) + .replace(/^(?!\.)/, './'); + + if (pkg.isPrivate()) { + if (pkg.getDirectoryName() !== 'shared') { + continue; + } + for (const {name, sourceFileName} of pkg.getPrivateModuleEntries()) { + privatePaths.push([name, [resolveRelative('src', sourceFileName)]]); + } + } else { + for (const {name, sourceFileName} of pkg.getExportedNpmModuleEntries()) { + publicPaths.push([name, [resolveRelative('src', sourceFileName)]]); + } + } + if (test) { + testPaths.push([`${pkg.getNpmName()}/src`, [resolveRelative('src')]]); + for (const fn of glob.sync( + pkg.resolve('src', '__tests__', 'utils', '*.{ts,tsx,mjs,jsx}'), + )) { + testPaths.push([ + `${pkg.getNpmName()}/src/__tests__/utils`, + [resolveRelative(fn)], + ]); + } + } + } + const paths = Object.fromEntries([ + ...extraPaths, + ...publicPaths, + ...privatePaths, + ...testPaths, + ]); + if (JSON.stringify(paths) !== prev) { + tsconfig.compilerOptions.paths = paths; + fs.writeFileSync( + jsonFileName, + prettier.format(JSON.stringify(tsconfig), {filepath: jsonFileName}), + ); + } +} +updateTsconfig({ + extraPaths: [], + jsonFileName: './tsconfig.json', + test: true, +}); +updateTsconfig({ + extraPaths: [], + jsonFileName: './tsconfig.build.json', + test: false, +}); +updateTsconfig({ + extraPaths: [['lexicalOriginal', ['../lexical/src/']]], + jsonFileName: './packages/lexical-devtools/tsconfig.json', + test: false, +}); diff --git a/scripts/updateVersion.js b/scripts/updateVersion.js index 7964ef4ecb7..ffcdb5e529d 100644 --- a/scripts/updateVersion.js +++ b/scripts/updateVersion.js @@ -10,70 +10,47 @@ const fs = require('fs-extra'); const glob = require('glob'); +const {packagesManager} = require('./shared/packagesManager'); +const {PackageMetadata} = require('./shared/PackageMetadata'); -const packages = { - '@lexical/clipboard': 'lexical-clipboard', - '@lexical/code': 'lexical-code', - '@lexical/dragon': 'lexical-dragon', - '@lexical/file': 'lexical-file', - '@lexical/hashtag': 'lexical-hashtag', - '@lexical/headless': 'lexical-headless', - '@lexical/history': 'lexical-history', - '@lexical/html': 'lexical-html', - '@lexical/link': 'lexical-link', - '@lexical/list': 'lexical-list', - '@lexical/mark': 'lexical-mark', - '@lexical/markdown': 'lexical-markdown', - '@lexical/offset': 'lexical-offset', - '@lexical/overflow': 'lexical-overflow', - '@lexical/plain-text': 'lexical-plain-text', - '@lexical/react': 'lexical-react', - '@lexical/rich-text': 'lexical-rich-text', - '@lexical/selection': 'lexical-selection', - '@lexical/table': 'lexical-table', - '@lexical/text': 'lexical-text', - '@lexical/utils': 'lexical-utils', - '@lexical/yjs': 'lexical-yjs', - lexical: 'lexical', - 'lexical-playground': 'lexical-playground', - shared: 'shared', -}; +const monorepoPackageJson = require('./shared/readMonorepoPackageJson')(); +// get version from monorepo package.json version +const version = monorepoPackageJson.version; + +const publicNpmNames = new Set( + packagesManager.getPublicPackages().map((pkg) => pkg.getNpmName()), +); + +/** + * - Set the version to the monorepo ./package.json version + * - Update dependencies, devDependencies, and peerDependencies + * - Update the exports map and set other required default fields + * @param {PackageMetadata} pkg + */ +function updatePackage(pkg) { + pkg.packageJson.version = version; + updateDependencies(pkg); + if (!pkg.isPrivate()) { + updatePublicPackage(pkg); + } + pkg.writeSync(); +} /** - * Update every package.json in the packages/ directory from the packages - * list above. + * Update every package.json in the packages/ and examples/ directories * * - Set the version to the monorepo ./package.json version - * - Update the dependencies and peerDependencies + * - Update the versions of monorepo dependencies, devDependencies, and peerDependencies * - Update the exports map and set other required default fields * - * Also scans the examples/ directory for package.json files and updates - * their dependencies as well, so the examples are kept up to date with - * the most recently published version of lexical. */ function updateVersion() { - // get version from monorepo package.json version - const basePackageJSON = fs.readJsonSync(`./package.json`); - const version = basePackageJSON.version; - // update individual packages - Object.values(packages).forEach((pkg) => { - const packageJSON = fs.readJsonSync(`./packages/${pkg}/package.json`); - packageJSON.version = version; - updateDependencies(packageJSON, version); - updateModule(packageJSON, pkg); - fs.writeJsonSync(`./packages/${pkg}/package.json`, packageJSON, { - spaces: 2, - }); - }); - // update dependencies in the examples - glob.sync('./examples/*/package.json').forEach((fn) => { - const packageJSON = fs.readJsonSync(fn); - packageJSON.version = version; - updateDependencies(packageJSON, version); - fs.writeJsonSync(fn, packageJSON, { - spaces: 2, - }); - }); + packagesManager.getPackages().forEach(updatePackage); + glob + .sync('./examples/*/package.json') + .forEach((packageJsonPath) => + updatePackage(new PackageMetadata(packageJsonPath)), + ); } /** @@ -91,29 +68,6 @@ function replaceExtension(fileName, ext) { return fileName.replace(/(\.m?js)$/, ext); } -/** - * Replace a .js filename with .mjs, this extension is required for maximal - * ESM compatibility because bundlers and node have hard-coded behavior for - * files of this extension. - * - * @param {string} fileName - * @returns {string} fileName with .mjs instead of .js - */ -function withEsmExtension(fileName) { - return replaceExtension(fileName, '.mjs'); -} - -/** - * Used for naming node condition ESM fork modules, which can use top-level - * await. - * - * @param {string} fileName - * @returns {string} fileName with .node.mjs extension - */ -function withNodeEsmExtension(fileName) { - return replaceExtension(fileName, '.node.mjs'); -} - /** * webpack can use these conditions to choose a dev or prod * build without a fork module, which is especially helpful @@ -132,106 +86,120 @@ function withEnvironments(fileName) { /** * Build an export map for a particular entry point in the package.json * - * @param {string} file the path to the cjs build product for an entry point (e.g. 'index.js') - * @param {string} types the path to the TypeScript .d.ts file + * @param {string} basename the name of the entry point module without an extension (e.g. 'index') * @returns {Record<'import'|'require', Record>} The export map for this file */ -function exportEntry(file, types) { +function exportEntry(basename, typesBasename = `${basename}.d.ts`) { // Bundlers such as webpack require 'types' to be first and 'default' to be // last per #5731. Keys are in descending priority order. + const prefix = `./${basename}`; + const types = `./${typesBasename}`; return { /* eslint-disable sort-keys-fix/sort-keys-fix */ import: { - types: `./${types}`, - ...withEnvironments(`./${withEsmExtension(file)}`), - node: `./${withNodeEsmExtension(file)}`, - default: `./${withEsmExtension(file)}`, + types, + ...withEnvironments(`${prefix}.mjs`), + node: `${prefix}.node.mjs`, + default: `${prefix}.mjs`, }, require: { - types: `./${types}`, - ...withEnvironments(`./${file}`), - default: `./${file}`, + types, + ...withEnvironments(`${prefix}.js`), + default: `${prefix}.js`, }, /* eslint-enable sort-keys-fix/sort-keys-fix */ }; } /** - * Update the parsed packageJSON in-place to add default configurations + * Update the public package's packageJson in-place to add default configurations * for `sideEffects` and `module` as well as to maintain the `exports` map. * - * @param {Record} packageJSON - * @param {string} pkg + * @param {PackageMetadata} pkg */ -function updateModule(packageJSON, pkg) { - if (packageJSON.sideEffects === undefined) { - packageJSON.sideEffects = false; +function updatePublicPackage(pkg) { + const {packageJson} = pkg; + if (packageJson.sideEffects === undefined) { + packageJson.sideEffects = false; } - if (packageJSON.main) { - packageJSON.module = withEsmExtension(packageJSON.main); - packageJSON.exports = { - '.': exportEntry(packageJSON.main, packageJSON.types || 'index.d.ts'), + // If there's a main we expect a single entry point + if (packageJson.main) { + packageJson.module = replaceExtension(packageJson.main, '.mjs'); + packageJson.exports = { + '.': exportEntry( + replaceExtension(packageJson.main, ''), + packageJson.types, + ), }; - } else if (fs.existsSync(`./packages/${pkg}/dist`)) { + } else { const exports = {}; - for (const file of fs.readdirSync(`./packages/${pkg}/dist`)) { - if (/^[^.]+\.js$/.test(file)) { - const entry = exportEntry(file, file.replace(/\.js$/, '.d.ts')); + // Export all src/*.tsx? files that do not have a prefix extension (e.g. no .d.ts) + for (const fn of fs.readdirSync(pkg.resolve('src'))) { + if (/^[^.]+\.tsx?$/.test(fn)) { + const basename = fn.replace(/\.tsx?$/, ''); + const entry = exportEntry(basename); // support for import "@lexical/react/LexicalComposer" - exports[`./${file.replace(/\.js$/, '')}`] = entry; + exports[`./${basename}`] = entry; // support for import "@lexical/react/LexicalComposer.js" // @mdxeditor/editor uses this at least as of 2.13.1 - exports[`./${file}`] = entry; + exports[`./${basename}.js`] = entry; } } - packageJSON.exports = exports; + packageJson.exports = exports; } } /** - * Replace the dependency map at packageJSON[key] in-place with + * Replace the dependency map at packageJson[key] in-place with * deps sorted lexically by key. If deps was empty, it will be removed. * - * @param {Record} packageJSON + * @param {Record} packageJson * @param {'dependencies'|'peerDependencies'} key * @param {Record} deps */ -function sortDependencies(packageJSON, key, deps) { +function sortDependencies(packageJson, key, deps) { const entries = Object.entries(deps); if (entries.length === 0) { - delete packageJSON[key]; + delete packageJson[key]; } else { - packageJSON[key] = Object.fromEntries( + packageJson[key] = Object.fromEntries( entries.sort((a, b) => a[0].localeCompare(b[0])), ); } } /** - * Update depdenencies and peerDependencies in packageJSON in-place. + * Update depdenencies and peerDependencies in pkg in-place. * All entries for monorepo packages will be updated to version. * All peerDependencies for monorepo packages will be moved to dependencies. * - * @param {Record} packageJSON - * @param {string} version + * @param {PackageMetadata} pkg */ -function updateDependencies(packageJSON, version) { - const {dependencies = {}, peerDependencies = {}} = packageJSON; - Object.keys(dependencies).forEach((dep) => { - if (packages[dep] !== undefined) { - dependencies[dep] = version; - } +function updateDependencies(pkg) { + const {packageJson} = pkg; + const { + dependencies = {}, + peerDependencies = {}, + devDependencies = {}, + } = packageJson; + [dependencies, devDependencies].forEach((deps) => { + Object.keys(deps).forEach((dep) => { + if (publicNpmNames.has(dep)) { + deps[dep] = version; + } + }); }); // Move peerDependencies on lexical monorepo packages to dependencies // per #5783 Object.keys(peerDependencies).forEach((peerDep) => { - if (packages[peerDep] !== undefined) { + if (publicNpmNames.has(peerDep)) { delete peerDependencies[peerDep]; dependencies[peerDep] = version; } }); - sortDependencies(packageJSON, 'dependencies', dependencies); - sortDependencies(packageJSON, 'peerDependencies', peerDependencies); + sortDependencies(packageJson, 'dependencies', dependencies); + sortDependencies(packageJson, 'devDependencies', devDependencies); + sortDependencies(packageJson, 'peerDependencies', peerDependencies); } updateVersion(); diff --git a/scripts/www/npmToWwwName.js b/scripts/www/npmToWwwName.js new file mode 100644 index 00000000000..7f3880d97a5 --- /dev/null +++ b/scripts/www/npmToWwwName.js @@ -0,0 +1,34 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ +'use strict'; + +/** + * Converts a package name in the npm name convention to the www + * convention, e.g.: + * '@lexical/rich-text' -> 'LexicalRichText' + * '@lexical/react/LexicalComposer' -> 'LexicalComposer' + * '@lexical/react/useLexicalEditor' -> 'useLexicalEditor' + * + * @param {string} name the npm or directory name of a package + * @returns {string} the name of the package in www format + */ +module.exports = function npmToWwwName(name) { + const parts = name.replace(/^@/, '').split(/\//g); + // Handle the @lexical/react/FlatNameSpace scenario + if (parts.length > 2) { + parts.splice(0, parts.length - 1); + } + return parts + .flatMap((part) => part.split('-')) + .map((part) => + part.startsWith('useLexical') + ? part + : part.charAt(0).toUpperCase() + part.slice(1), + ) + .join(''); +}; diff --git a/scripts/www/rewriteImports.js b/scripts/www/rewriteImports.js index 65a6d29ffc7..b27a1e35f8b 100644 --- a/scripts/www/rewriteImports.js +++ b/scripts/www/rewriteImports.js @@ -8,72 +8,78 @@ 'use strict'; +const fs = require('fs-extra'); const glob = require('glob'); -const {readFile, writeFile} = require('fs'); +const path = require('node:path'); +const {packagesManager} = require('../shared/packagesManager'); +const npmToWwwName = require('./npmToWwwName'); +const {t, transform} = require('hermes-transform'); -const options = {}; +const wwwMappings = Object.fromEntries( + packagesManager + .getPublicPackages() + .flatMap((pkg) => + pkg.getExportedNpmModuleNames().map((npm) => [npm, npmToWwwName(npm)]), + ), +); + +/** + * It would be nice to use jscodeshift for this but the flow sources are using + * ast features that are not supported in ast-types (as of 2024-04-11) so it's + * not possible to traverse the tree and replace the imports & comments. + * + * It might be possible going straight to flow-parser, but it was a slew of + * hardcoded regexps before and now it's at least automated based on the + * exports. + * + * @param {string} source + * @returns {Promise} transformed source + */ +async function transformFlowFileContents(source) { + return await transform( + source, + (context) => ({ + ImportDeclaration(node) { + const value = wwwMappings[node.source.value]; + if (value) { + context.replaceNode(node.source, t.StringLiteral({value})); + } + }, + Program(node) { + if ( + node.docblock && + node.docblock.comment && + node.docblock.comment.value.includes('@flow strict') + ) { + node.docblock.comment.value = node.docblock.comment.value.replace( + / \* @flow strict/g, + ' * @flow strict\n * @generated\n * @oncall lexical_web_text_editor', + ); + } + }, + }), + {}, + ); +} // This script attempts to find all Flow definition modules, and makes // them compatible with www. Specifically, it finds any imports that // reference lower case 'lexical' -> 'Lexical' and package references, -// such as 'lexical/Foo' -> 'LexicalFoo' and '@lexical/react/Foo' -> +// such as 'lexical/Foo' -> 'LexicalFoo' and '@lexical/react/LexicalFoo' -> // 'LexicalFoo'. Lastly, it creates these files in the 'dist' directory // for each package so they can easily be copied to www. - -glob('packages/**/flow/*.flow', options, function (error1, files) { - if (error1) { - throw error1; +async function rewriteImports() { + for (const pkg of packagesManager.getPackages()) { + for (const flowFile of glob.sync(pkg.resolve('flow', '*.flow'))) { + const data = fs.readFileSync(flowFile, 'utf8'); + const result = await transformFlowFileContents(data); + fs.writeFileSync( + pkg.resolve('dist', path.basename(flowFile)), + result, + 'utf8', + ); + } } - files.forEach((file) => { - readFile(file, 'utf8', function (error2, data) { - if (error2) { - throw error2; - } - const result = data - .replace( - / \* @flow strict/g, - ' * @flow strict\n * @generated\n * @oncall lexical_web_text_editor', - ) - .replace(/from 'lexical'/g, "from 'Lexical'") - .replace(/from 'lexical'/g, "from 'Lexical'") - .replace(/from 'lexical\/LinkNode'/g, "from 'LexicalLinkNode'") - .replace(/from '@lexical\/react\/Lexical/g, "from 'Lexical") - .replace(/from '@lexical\/utils\/'/g, "from 'LexicalUtils") - .replace(/from '@lexical\/clipboard\'/g, "from 'LexicalClipboard'") - .replace( - /from '@lexical\/devtools-core\'/g, - "from 'LexicalDevToolsCore'", - ) - .replace(/from '@lexical\/code\'/g, "from 'LexicalCode'") - .replace(/from '@lexical\/dragon\'/g, "from 'LexicalDragon'") - .replace(/from '@lexical\/file\'/g, "from 'LexicalFile'") - .replace(/from '@lexical\/hashtag\'/g, "from 'LexicalHashtag'") - .replace(/from '@lexical\/history\'/g, "from 'LexicalHistory'") - .replace(/from '@lexical\/link\'/g, "from 'LexicalLink'") - .replace(/from '@lexical\/list\'/g, "from 'LexicalList'") - .replace(/from '@lexical\/markdown\'/g, "from 'LexicalMarkdown'") - .replace(/from '@lexical\/headless\'/g, "from 'LexicalHeadless'") - .replace(/from '@lexical\/offset\'/g, "from 'LexicalOffset'") - .replace(/from '@lexical\/overflow\'/g, "from 'LexicalOverflow'") - .replace(/from '@lexical\/plain-text\'/g, "from 'LexicalPlainText'") - .replace(/from '@lexical\/rich-text\'/g, "from 'LexicalRichText'") - .replace(/from '@lexical\/selection\'/g, "from 'LexicalSelection'") - .replace(/from '@lexical\/table\'/g, "from 'LexicalTable'") - .replace(/from '@lexical\/text\'/g, "from 'LexicalText'") - .replace(/from '@lexical\/utils\'/g, "from 'LexicalUtils'") - .replace(/from '@lexical\/yjs\'/g, "from 'LexicalYjs'") - .replace( - /from 'lexical\/CodeHighlightNode'/g, - "from 'LexicalCodeHighlightNode'", - ); +} - const distDirectory = file.replace('/flow/', '/dist/'); - - writeFile(distDirectory, result, 'utf8', function (error3) { - if (error3) { - throw error3; - } - }); - }); - }); -}); +rewriteImports(); diff --git a/tsconfig.build.json b/tsconfig.build.json index 538ab2f8a5e..dc17b674c79 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -4,14 +4,175 @@ "declaration": true, "emitDeclarationOnly": true, "declarationDir": "./.ts-temp", - "strict": true + "strict": true, + "paths": { + "lexical": ["./packages/lexical/src/index.ts"], + "@lexical/clipboard": ["./packages/lexical-clipboard/src/index.ts"], + "@lexical/code": ["./packages/lexical-code/src/index.ts"], + "@lexical/devtools-core": [ + "./packages/lexical-devtools-core/src/index.ts" + ], + "@lexical/dragon": ["./packages/lexical-dragon/src/index.ts"], + "@lexical/file": ["./packages/lexical-file/src/index.ts"], + "@lexical/hashtag": ["./packages/lexical-hashtag/src/index.ts"], + "@lexical/headless": ["./packages/lexical-headless/src/index.ts"], + "@lexical/history": ["./packages/lexical-history/src/index.ts"], + "@lexical/html": ["./packages/lexical-html/src/index.ts"], + "@lexical/link": ["./packages/lexical-link/src/index.ts"], + "@lexical/list": ["./packages/lexical-list/src/index.ts"], + "@lexical/mark": ["./packages/lexical-mark/src/index.ts"], + "@lexical/markdown": ["./packages/lexical-markdown/src/index.ts"], + "@lexical/offset": ["./packages/lexical-offset/src/index.ts"], + "@lexical/overflow": ["./packages/lexical-overflow/src/index.ts"], + "@lexical/plain-text": ["./packages/lexical-plain-text/src/index.ts"], + "@lexical/react/LexicalAutoEmbedPlugin": [ + "./packages/lexical-react/src/LexicalAutoEmbedPlugin.tsx" + ], + "@lexical/react/LexicalAutoFocusPlugin": [ + "./packages/lexical-react/src/LexicalAutoFocusPlugin.ts" + ], + "@lexical/react/LexicalAutoLinkPlugin": [ + "./packages/lexical-react/src/LexicalAutoLinkPlugin.ts" + ], + "@lexical/react/LexicalBlockWithAlignableContents": [ + "./packages/lexical-react/src/LexicalBlockWithAlignableContents.tsx" + ], + "@lexical/react/LexicalCharacterLimitPlugin": [ + "./packages/lexical-react/src/LexicalCharacterLimitPlugin.tsx" + ], + "@lexical/react/LexicalCheckListPlugin": [ + "./packages/lexical-react/src/LexicalCheckListPlugin.tsx" + ], + "@lexical/react/LexicalClearEditorPlugin": [ + "./packages/lexical-react/src/LexicalClearEditorPlugin.ts" + ], + "@lexical/react/LexicalClickableLinkPlugin": [ + "./packages/lexical-react/src/LexicalClickableLinkPlugin.tsx" + ], + "@lexical/react/LexicalCollaborationContext": [ + "./packages/lexical-react/src/LexicalCollaborationContext.ts" + ], + "@lexical/react/LexicalCollaborationPlugin": [ + "./packages/lexical-react/src/LexicalCollaborationPlugin.ts" + ], + "@lexical/react/LexicalComposer": [ + "./packages/lexical-react/src/LexicalComposer.tsx" + ], + "@lexical/react/LexicalComposerContext": [ + "./packages/lexical-react/src/LexicalComposerContext.ts" + ], + "@lexical/react/LexicalContentEditable": [ + "./packages/lexical-react/src/LexicalContentEditable.tsx" + ], + "@lexical/react/LexicalContextMenuPlugin": [ + "./packages/lexical-react/src/LexicalContextMenuPlugin.tsx" + ], + "@lexical/react/LexicalDecoratorBlockNode": [ + "./packages/lexical-react/src/LexicalDecoratorBlockNode.ts" + ], + "@lexical/react/LexicalEditorRefPlugin": [ + "./packages/lexical-react/src/LexicalEditorRefPlugin.tsx" + ], + "@lexical/react/LexicalErrorBoundary": [ + "./packages/lexical-react/src/LexicalErrorBoundary.tsx" + ], + "@lexical/react/LexicalHashtagPlugin": [ + "./packages/lexical-react/src/LexicalHashtagPlugin.ts" + ], + "@lexical/react/LexicalHistoryPlugin": [ + "./packages/lexical-react/src/LexicalHistoryPlugin.ts" + ], + "@lexical/react/LexicalHorizontalRuleNode": [ + "./packages/lexical-react/src/LexicalHorizontalRuleNode.tsx" + ], + "@lexical/react/LexicalHorizontalRulePlugin": [ + "./packages/lexical-react/src/LexicalHorizontalRulePlugin.ts" + ], + "@lexical/react/LexicalLinkPlugin": [ + "./packages/lexical-react/src/LexicalLinkPlugin.ts" + ], + "@lexical/react/LexicalListPlugin": [ + "./packages/lexical-react/src/LexicalListPlugin.ts" + ], + "@lexical/react/LexicalMarkdownShortcutPlugin": [ + "./packages/lexical-react/src/LexicalMarkdownShortcutPlugin.tsx" + ], + "@lexical/react/LexicalNestedComposer": [ + "./packages/lexical-react/src/LexicalNestedComposer.tsx" + ], + "@lexical/react/LexicalNodeEventPlugin": [ + "./packages/lexical-react/src/LexicalNodeEventPlugin.ts" + ], + "@lexical/react/LexicalNodeMenuPlugin": [ + "./packages/lexical-react/src/LexicalNodeMenuPlugin.tsx" + ], + "@lexical/react/LexicalOnChangePlugin": [ + "./packages/lexical-react/src/LexicalOnChangePlugin.ts" + ], + "@lexical/react/LexicalPlainTextPlugin": [ + "./packages/lexical-react/src/LexicalPlainTextPlugin.tsx" + ], + "@lexical/react/LexicalRichTextPlugin": [ + "./packages/lexical-react/src/LexicalRichTextPlugin.tsx" + ], + "@lexical/react/LexicalTabIndentationPlugin": [ + "./packages/lexical-react/src/LexicalTabIndentationPlugin.tsx" + ], + "@lexical/react/LexicalTableOfContents": [ + "./packages/lexical-react/src/LexicalTableOfContents.tsx" + ], + "@lexical/react/LexicalTablePlugin": [ + "./packages/lexical-react/src/LexicalTablePlugin.ts" + ], + "@lexical/react/LexicalTreeView": [ + "./packages/lexical-react/src/LexicalTreeView.tsx" + ], + "@lexical/react/LexicalTypeaheadMenuPlugin": [ + "./packages/lexical-react/src/LexicalTypeaheadMenuPlugin.tsx" + ], + "@lexical/react/useLexicalEditable": [ + "./packages/lexical-react/src/useLexicalEditable.ts" + ], + "@lexical/react/useLexicalIsTextContentEmpty": [ + "./packages/lexical-react/src/useLexicalIsTextContentEmpty.ts" + ], + "@lexical/react/useLexicalNodeSelection": [ + "./packages/lexical-react/src/useLexicalNodeSelection.ts" + ], + "@lexical/react/useLexicalSubscription": [ + "./packages/lexical-react/src/useLexicalSubscription.tsx" + ], + "@lexical/react/useLexicalTextEntity": [ + "./packages/lexical-react/src/useLexicalTextEntity.ts" + ], + "@lexical/rich-text": ["./packages/lexical-rich-text/src/index.ts"], + "@lexical/selection": ["./packages/lexical-selection/src/index.ts"], + "@lexical/table": ["./packages/lexical-table/src/index.ts"], + "@lexical/text": ["./packages/lexical-text/src/index.ts"], + "@lexical/utils": ["./packages/lexical-utils/src/index.ts"], + "@lexical/yjs": ["./packages/lexical-yjs/src/index.ts"], + "shared/canUseDOM": ["./packages/shared/src/canUseDOM.ts"], + "shared/caretFromPoint": ["./packages/shared/src/caretFromPoint.ts"], + "shared/environment": ["./packages/shared/src/environment.ts"], + "shared/invariant": ["./packages/shared/src/invariant.ts"], + "shared/normalizeClassNames": [ + "./packages/shared/src/normalizeClassNames.ts" + ], + "shared/simpleDiffWithCursor": [ + "./packages/shared/src/simpleDiffWithCursor.ts" + ], + "shared/useLayoutEffect": ["./packages/shared/src/useLayoutEffect.ts"], + "shared/warnOnlyOnce": ["./packages/shared/src/warnOnlyOnce.ts"] + } }, "exclude": [ + "./libdefs/*.js", "**/__tests__/**", - "node_modules/**/*", - "packages/lexical-playground/**/*", - "packages/playwright-core/**/*", - "packages/lexical-devtools/**" + "**/dist/**", + "**/npm/**", + "**/node_modules/**", + "./packages/lexical-devtools/**", + "./packages/lexical-playground/**" ], "extends": "./tsconfig.json" } diff --git a/tsconfig.json b/tsconfig.json index 1fdebaa1be8..ea462543902 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,212 +12,207 @@ "typeRoots": ["node_modules/@types", "libdefs/globals"], "skipLibCheck": true, "resolveJsonModule": true, - + "allowJs": true, "paths": { - "lexical": ["./packages/lexical/src/"], - "@lexical/clipboard": ["./packages/lexical-clipboard/src/"], - "@lexical/list": ["./packages/lexical-list/src/"], - "@lexical/table": ["./packages/lexical-table/src/"], - "@lexical/file": ["./packages/lexical-file/src/"], - "@lexical/hashtag": ["./packages/lexical-hashtag/src/"], - "@lexical/selection": ["./packages/lexical-selection/src/"], - "@lexical/text": ["./packages/lexical-text/src/"], - "@lexical/offset": ["./packages/lexical-offset/src/"], - "@lexical/history": ["./packages/lexical-history/src/"], - "@lexical/headless": ["./packages/lexical-headless/src/"], - "@lexical/html": ["./packages/lexical-html/src/"], - "@lexical/utils": ["./packages/lexical-utils/src/"], - "@lexical/code": ["./packages/lexical-code/src/"], - "@lexical/plain-text": ["./packages/lexical-plain-text/src/"], - "@lexical/rich-text": ["./packages/lexical-rich-text/src/"], - "@lexical/dragon": ["./packages/lexical-dragon/src/"], - "@lexical/link": ["./packages/lexical-link/src/"], - "@lexical/overflow": ["./packages/lexical-overflow/src/"], - "@lexical/markdown": ["./packages/lexical-markdown/src/"], - "@lexical/mark": ["./packages/lexical-mark/src/"], - "@lexical/devtools-core": ["./packages/lexical-devtools-core/src/"], - - "@lexical/react/LexicalComposer": [ - "./packages/lexical-react/src/LexicalComposer.tsx" - ], - "@lexical/react/LexicalComposerContext": [ - "./packages/lexical-react/src/LexicalComposerContext.ts" + "lexical": ["./packages/lexical/src/index.ts"], + "@lexical/clipboard": ["./packages/lexical-clipboard/src/index.ts"], + "@lexical/code": ["./packages/lexical-code/src/index.ts"], + "@lexical/devtools-core": [ + "./packages/lexical-devtools-core/src/index.ts" + ], + "@lexical/dragon": ["./packages/lexical-dragon/src/index.ts"], + "@lexical/file": ["./packages/lexical-file/src/index.ts"], + "@lexical/hashtag": ["./packages/lexical-hashtag/src/index.ts"], + "@lexical/headless": ["./packages/lexical-headless/src/index.ts"], + "@lexical/history": ["./packages/lexical-history/src/index.ts"], + "@lexical/html": ["./packages/lexical-html/src/index.ts"], + "@lexical/link": ["./packages/lexical-link/src/index.ts"], + "@lexical/list": ["./packages/lexical-list/src/index.ts"], + "@lexical/mark": ["./packages/lexical-mark/src/index.ts"], + "@lexical/markdown": ["./packages/lexical-markdown/src/index.ts"], + "@lexical/offset": ["./packages/lexical-offset/src/index.ts"], + "@lexical/overflow": ["./packages/lexical-overflow/src/index.ts"], + "@lexical/plain-text": ["./packages/lexical-plain-text/src/index.ts"], + "@lexical/react/LexicalAutoEmbedPlugin": [ + "./packages/lexical-react/src/LexicalAutoEmbedPlugin.tsx" ], - "@lexical/react/LexicalNestedComposer": [ - "./packages/lexical-react/src/LexicalNestedComposer.tsx" + "@lexical/react/LexicalAutoFocusPlugin": [ + "./packages/lexical-react/src/LexicalAutoFocusPlugin.ts" ], - "@lexical/react/LexicalContentEditable": [ - "./packages/lexical-react/src/LexicalContentEditable.tsx" + "@lexical/react/LexicalAutoLinkPlugin": [ + "./packages/lexical-react/src/LexicalAutoLinkPlugin.ts" ], - "@lexical/react/LexicalTreeView": [ - "./packages/lexical-react/src/LexicalTreeView.tsx" + "@lexical/react/LexicalBlockWithAlignableContents": [ + "./packages/lexical-react/src/LexicalBlockWithAlignableContents.tsx" ], - "@lexical/react/LexicalHorizontalRuleNode": [ - "./packages/lexical-react/src/LexicalHorizontalRuleNode.tsx" + "@lexical/react/LexicalCharacterLimitPlugin": [ + "./packages/lexical-react/src/LexicalCharacterLimitPlugin.tsx" ], - "@lexical/react/LexicalHorizontalRulePlugin": [ - "./packages/lexical-react/src/LexicalHorizontalRulePlugin.ts" + "@lexical/react/LexicalCheckListPlugin": [ + "./packages/lexical-react/src/LexicalCheckListPlugin.tsx" ], - "@lexical/react/LexicalDecoratorBlockNode": [ - "./packages/lexical-react/src/LexicalDecoratorBlockNode.ts" + "@lexical/react/LexicalClearEditorPlugin": [ + "./packages/lexical-react/src/LexicalClearEditorPlugin.ts" ], - "@lexical/react/LexicalBlockWithAlignableContents": [ - "./packages/lexical-react/src/LexicalBlockWithAlignableContents.tsx" + "@lexical/react/LexicalClickableLinkPlugin": [ + "./packages/lexical-react/src/LexicalClickableLinkPlugin.tsx" ], - "@lexical/react/useLexicalIsTextContentEmpty": [ - "./packages/lexical-react/src/useLexicalIsTextContentEmpty.ts" + "@lexical/react/LexicalCollaborationContext": [ + "./packages/lexical-react/src/LexicalCollaborationContext.ts" ], - "@lexical/react/useLexicalNodeSelection": [ - "./packages/lexical-react/src/useLexicalNodeSelection.ts" + "@lexical/react/LexicalCollaborationPlugin": [ + "./packages/lexical-react/src/LexicalCollaborationPlugin.ts" ], - "@lexical/react/useLexicalTextEntity": [ - "./packages/lexical-react/src/useLexicalTextEntity.ts" + "@lexical/react/LexicalComposer": [ + "./packages/lexical-react/src/LexicalComposer.tsx" ], - "@lexical/react/useLexicalSubscription": [ - "./packages/lexical-react/src/useLexicalSubscription.ts" + "@lexical/react/LexicalComposerContext": [ + "./packages/lexical-react/src/LexicalComposerContext.ts" ], - "@lexical/react/useLexicalEditable": [ - "./packages/lexical-react/src/useLexicalEditable.ts" + "@lexical/react/LexicalContentEditable": [ + "./packages/lexical-react/src/LexicalContentEditable.tsx" ], - "@lexical/react/LexicalPlainTextPlugin": [ - "./packages/lexical-react/src/LexicalPlainTextPlugin.tsx" + "@lexical/react/LexicalContextMenuPlugin": [ + "./packages/lexical-react/src/LexicalContextMenuPlugin.tsx" ], - "@lexical/react/LexicalRichTextPlugin": [ - "./packages/lexical-react/src/LexicalRichTextPlugin.tsx" + "@lexical/react/LexicalDecoratorBlockNode": [ + "./packages/lexical-react/src/LexicalDecoratorBlockNode.ts" ], - "@lexical/react/LexicalTypeaheadMenuPlugin": [ - "packages/lexical-react/src/LexicalTypeaheadMenuPlugin.tsx" + "@lexical/react/LexicalEditorRefPlugin": [ + "./packages/lexical-react/src/LexicalEditorRefPlugin.tsx" ], - "@lexical/react/LexicalNodeMenuPlugin": [ - "packages/lexical-react/src/LexicalNodeMenuPlugin.tsx" + "@lexical/react/LexicalErrorBoundary": [ + "./packages/lexical-react/src/LexicalErrorBoundary.tsx" ], - "@lexical/react/LexicalContextMenuPlugin": [ - "packages/lexical-react/src/LexicalContextMenuPlugin.tsx" + "@lexical/react/LexicalHashtagPlugin": [ + "./packages/lexical-react/src/LexicalHashtagPlugin.ts" ], "@lexical/react/LexicalHistoryPlugin": [ "./packages/lexical-react/src/LexicalHistoryPlugin.ts" ], - "@lexical/react/LexicalOnChangePlugin": [ - "./packages/lexical-react/src/LexicalOnChangePlugin.ts" + "@lexical/react/LexicalHorizontalRuleNode": [ + "./packages/lexical-react/src/LexicalHorizontalRuleNode.tsx" ], - "@lexical/react/LexicalNodeEventPlugin": [ - "./packages/lexical-react/src/LexicalNodeEventPlugin.ts" + "@lexical/react/LexicalHorizontalRulePlugin": [ + "./packages/lexical-react/src/LexicalHorizontalRulePlugin.ts" ], - "@lexical/react/LexicalHashtagPlugin": [ - "./packages/lexical-react/src/LexicalHashtagPlugin.ts" + "@lexical/react/LexicalLinkPlugin": [ + "./packages/lexical-react/src/LexicalLinkPlugin.ts" ], - "@lexical/react/LexicalErrorBoundary": [ - "./packages/lexical-react/src/LexicalErrorBoundary.tsx" + "@lexical/react/LexicalListPlugin": [ + "./packages/lexical-react/src/LexicalListPlugin.ts" ], "@lexical/react/LexicalMarkdownShortcutPlugin": [ "./packages/lexical-react/src/LexicalMarkdownShortcutPlugin.tsx" ], - "@lexical/react/LexicalAutoFocusPlugin": [ - "./packages/lexical-react/src/LexicalAutoFocusPlugin.ts" + "@lexical/react/LexicalNestedComposer": [ + "./packages/lexical-react/src/LexicalNestedComposer.tsx" ], - "@lexical/react/LexicalTableOfContents": [ - "./packages/lexical-react/src/LexicalTableOfContents.tsx" + "@lexical/react/LexicalNodeEventPlugin": [ + "./packages/lexical-react/src/LexicalNodeEventPlugin.ts" ], - "@lexical/react/LexicalAutoFormatterPlugin": [ - "./packages/lexical-react/src/LexicalAutoFormatterPlugin.ts" + "@lexical/react/LexicalNodeMenuPlugin": [ + "./packages/lexical-react/src/LexicalNodeMenuPlugin.tsx" ], - "@lexical/react/LexicalCharacterLimitPlugin": [ - "./packages/lexical-react/src/LexicalCharacterLimitPlugin.tsx" + "@lexical/react/LexicalOnChangePlugin": [ + "./packages/lexical-react/src/LexicalOnChangePlugin.ts" ], - "@lexical/react/LexicalClearEditorPlugin": [ - "./packages/lexical-react/src/LexicalClearEditorPlugin.ts" + "@lexical/react/LexicalPlainTextPlugin": [ + "./packages/lexical-react/src/LexicalPlainTextPlugin.tsx" ], - "@lexical/react/LexicalClickableLinkPlugin": [ - "./packages/lexical-react/src/LexicalClickableLinkPlugin.tsx" + "@lexical/react/LexicalRichTextPlugin": [ + "./packages/lexical-react/src/LexicalRichTextPlugin.tsx" ], - "@lexical/react/LexicalCollaborationContext": [ - "./packages/lexical-react/src/LexicalCollaborationContext.ts" + "@lexical/react/LexicalTabIndentationPlugin": [ + "./packages/lexical-react/src/LexicalTabIndentationPlugin.tsx" ], - "@lexical/react/LexicalCollaborationPlugin": [ - "./packages/lexical-react/src/LexicalCollaborationPlugin.ts" + "@lexical/react/LexicalTableOfContents": [ + "./packages/lexical-react/src/LexicalTableOfContents.tsx" ], "@lexical/react/LexicalTablePlugin": [ "./packages/lexical-react/src/LexicalTablePlugin.ts" ], - "@lexical/react/LexicalLinkPlugin": [ - "./packages/lexical-react/src/LexicalLinkPlugin.ts" + "@lexical/react/LexicalTreeView": [ + "./packages/lexical-react/src/LexicalTreeView.tsx" ], - "@lexical/react/LexicalAutoLinkPlugin": [ - "./packages/lexical-react/src/LexicalAutoLinkPlugin.ts" + "@lexical/react/LexicalTypeaheadMenuPlugin": [ + "./packages/lexical-react/src/LexicalTypeaheadMenuPlugin.tsx" ], - "@lexical/react/LexicalAutoEmbedPlugin": [ - "./packages/lexical-react/src/LexicalAutoEmbedPlugin.tsx" + "@lexical/react/useLexicalEditable": [ + "./packages/lexical-react/src/useLexicalEditable.ts" ], - "@lexical/react/LexicalListPlugin": [ - "./packages/lexical-react/src/LexicalListPlugin.ts" + "@lexical/react/useLexicalIsTextContentEmpty": [ + "./packages/lexical-react/src/useLexicalIsTextContentEmpty.ts" ], - "@lexical/react/LexicalCheckListPlugin": [ - "./packages/lexical-react/src/LexicalCheckListPlugin.tsx" + "@lexical/react/useLexicalNodeSelection": [ + "./packages/lexical-react/src/useLexicalNodeSelection.ts" ], - "@lexical/react/LexicalTabIndentationPlugin": [ - "./packages/lexical-react/src/LexicalTabIndentationPlugin.tsx" + "@lexical/react/useLexicalSubscription": [ + "./packages/lexical-react/src/useLexicalSubscription.tsx" ], - "@lexical/react/LexicalEditorRefPlugin": [ - "packages/lexical-react/src/LexicalEditorRefPlugin.tsx" - ], - - "@lexical/dragon/LexicalDragon": ["./packages/lexical-dragon/src/"], - "@lexical/history/LexicalHistory": ["./packages/lexical-history/src/"], - "@lexical/link/LexicalLink": ["./packages/lexical-link/src/"], - "@lexical/markdown/LexicalMarkdown": ["./packages/lexical-markdown/src/"], - "@lexical/headless/LexicalHeadless": ["./packages/lexical-markdown/src/"], - "@lexical/offset/LexicalOffset": ["./packages/lexical-offset/src/"], - "@lexical/overflow/LexicalOverflow": ["./packages/lexical-overflow/src/"], - "@lexical/plain-text/LexicalPlainText": [ - "./packages/lexical-plain-text/src/" - ], - "@lexical/rich-text/LexicalRichText": [ - "./packages/lexical-rich-text/src/" - ], - "@lexical/selection/LexicalSelection": [ - "./packages/lexical-selection/src/" - ], - "@lexical/text/LexicalText": ["./packages/lexical-text/src/"], - "@lexical/utils/LexicalUtils": ["./packages/lexical-utils/src/"], - "@lexical/yjs": ["./packages/lexical-yjs/src/"], - + "@lexical/react/useLexicalTextEntity": [ + "./packages/lexical-react/src/useLexicalTextEntity.ts" + ], + "@lexical/rich-text": ["./packages/lexical-rich-text/src/index.ts"], + "@lexical/selection": ["./packages/lexical-selection/src/index.ts"], + "@lexical/table": ["./packages/lexical-table/src/index.ts"], + "@lexical/text": ["./packages/lexical-text/src/index.ts"], + "@lexical/utils": ["./packages/lexical-utils/src/index.ts"], + "@lexical/yjs": ["./packages/lexical-yjs/src/index.ts"], "shared/canUseDOM": ["./packages/shared/src/canUseDOM.ts"], "shared/caretFromPoint": ["./packages/shared/src/caretFromPoint.ts"], - "shared/simpleDiffWithCursor": [ - "packages/shared/src/simpleDiffWithCursor.ts" - ], + "shared/environment": ["./packages/shared/src/environment.ts"], "shared/invariant": ["./packages/shared/src/invariant.ts"], "shared/normalizeClassNames": [ "./packages/shared/src/normalizeClassNames.ts" ], - "shared/warnOnlyOnce": ["./packages/shared/src/warnOnlyOnce.ts"], - "shared/environment": ["./packages/shared/src/environment.ts"], + "shared/simpleDiffWithCursor": [ + "./packages/shared/src/simpleDiffWithCursor.ts" + ], "shared/useLayoutEffect": ["./packages/shared/src/useLayoutEffect.ts"], - - "lexical/src": ["./packages/lexical/src/"], + "shared/warnOnlyOnce": ["./packages/shared/src/warnOnlyOnce.ts"], + "lexical/src": ["./packages/lexical/src"], "lexical/src/__tests__/utils": [ "./packages/lexical/src/__tests__/utils/index.tsx" ], + "@lexical/clipboard/src": ["./packages/lexical-clipboard/src"], + "@lexical/code/src": ["./packages/lexical-code/src"], + "@lexical/devtools-core/src": ["./packages/lexical-devtools-core/src"], + "@lexical/dragon/src": ["./packages/lexical-dragon/src"], + "@lexical/file/src": ["./packages/lexical-file/src"], + "@lexical/hashtag/src": ["./packages/lexical-hashtag/src"], + "@lexical/headless/src": ["./packages/lexical-headless/src"], + "@lexical/history/src": ["./packages/lexical-history/src"], + "@lexical/html/src": ["./packages/lexical-html/src"], + "@lexical/link/src": ["./packages/lexical-link/src"], + "@lexical/list/src": ["./packages/lexical-list/src"], + "@lexical/mark/src": ["./packages/lexical-mark/src"], + "@lexical/markdown/src": ["./packages/lexical-markdown/src"], + "@lexical/offset/src": ["./packages/lexical-offset/src"], + "@lexical/overflow/src": ["./packages/lexical-overflow/src"], + "@lexical/plain-text/src": ["./packages/lexical-plain-text/src"], + "@lexical/react/src": ["./packages/lexical-react/src"], + "@lexical/rich-text/src": ["./packages/lexical-rich-text/src"], + "@lexical/selection/src": ["./packages/lexical-selection/src"], "@lexical/selection/src/__tests__/utils": [ "./packages/lexical-selection/src/__tests__/utils/index.ts" ], - "@lexical/yjs/src/index": ["./packages/lexical-yjs/src/index.ts"] + "@lexical/table/src": ["./packages/lexical-table/src"], + "@lexical/text/src": ["./packages/lexical-text/src"], + "@lexical/utils/src": ["./packages/lexical-utils/src"], + "@lexical/yjs/src": ["./packages/lexical-yjs/src"], + "shared/src": ["./packages/shared/src"] } }, "include": ["./libdefs", "./packages"], "exclude": [ + "./libdefs/*.js", "**/lexical-*/src/__tests__/**", "**/dist/**", "**/npm/**", "**/node_modules/**", - "./packages/playwright-core/**", "./packages/lexical-devtools/**" ], - "typedocOptions": { - "logLevel": "Verbose" - }, - "ts-node": { - "require": ["tsconfig-paths/register"], - "transpileOnly": true - } + "typedocOptions": {"logLevel": "Verbose"}, + "ts-node": {"require": ["tsconfig-paths/register"], "transpileOnly": true} } diff --git a/tsconfig.test.json b/tsconfig.test.json index ecd1ba3d8d7..dd6c48b0ab1 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -6,6 +6,7 @@ }, "include": ["./libdefs", "./packages"], "exclude": [ + "./libdefs/*.js", "**/dist/**", "**/npm/**", "**/node_modules/**",