From 15b1069bcc21d58752fd51f3c7f4ffb10013678b Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Mon, 29 Nov 2021 06:40:55 -0800 Subject: [PATCH] chore: Move to Typescript (#2783) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR moves the entire project to Typescript. Due to the ~1000 ignores this will lead to a messy codebase for a while, but the churn is worth it – all of those ignore comments are places that were never type-safe previously. closes #1282 --- .babelrc | 2 +- .circleci/config.yml | 4 +- .dockerignore | 5 +- .eslintrc | 85 +- .flowconfig | 44 - .vscode/settings.json | 8 +- README.md | 7 +- __mocks__/bull.js | 1 - app/.eslintrc | 9 + app/.jestconfig.json | 10 +- .../{collections.js => collections.tsx} | 19 +- .../definitions/{debug.js => debug.tsx} | 11 +- .../{documents.js => documents.tsx} | 47 +- .../{navigation.js => navigation.tsx} | 15 +- .../definitions/{settings.js => settings.tsx} | 14 +- .../definitions/{users.js => users.tsx} | 9 +- app/actions/{index.js => index.ts} | 43 +- app/actions/{root.js => root.ts} | 1 - app/actions/{sections.js => sections.ts} | 3 +- app/components/{Actions.js => Actions.ts} | 3 +- app/components/{Analytics.js => Analytics.ts} | 18 +- app/components/{Arrow.js => Arrow.tsx} | 1 - .../{GoogleLogo.js => GoogleLogo.tsx} | 7 +- .../{MicrosoftLogo.js => MicrosoftLogo.tsx} | 7 +- .../AuthLogo/{SlackLogo.js => SlackLogo.tsx} | 7 +- .../AuthLogo/{index.js => index.tsx} | 12 +- .../{Authenticated.js => Authenticated.tsx} | 13 +- .../Avatar/{Avatar.js => Avatar.tsx} | 27 +- ...WithPresence.js => AvatarWithPresence.tsx} | 33 +- app/components/Avatar/{index.js => index.ts} | 2 +- app/components/{Badge.js => Badge.ts} | 3 +- app/components/{Branding.js => Branding.tsx} | 5 +- .../{Breadcrumb.js => Breadcrumb.tsx} | 37 +- app/components/{Bubble.js => Bubble.tsx} | 9 +- app/components/{Button.js => Button.tsx} | 110 +- .../{ButtonLarge.js => ButtonLarge.ts} | 1 - .../{ButtonLink.js => ButtonLink.tsx} | 5 +- ...CenteredContent.js => CenteredContent.tsx} | 13 +- app/components/{Checkbox.js => Checkbox.tsx} | 33 +- ...ProgressBar.js => CircularProgressBar.tsx} | 18 +- ...lickablePadding.js => ClickablePadding.ts} | 3 +- .../{Collaborators.js => Collaborators.tsx} | 33 +- ...scription.js => CollectionDescription.tsx} | 44 +- .../{CollectionIcon.js => CollectionIcon.tsx} | 13 +- .../{CommandBar.js => CommandBar.tsx} | 15 +- .../{CommandBarItem.js => CommandBarItem.tsx} | 38 +- ...andBarResults.js => CommandBarResults.tsx} | 12 +- ...nnectionStatus.js => ConnectionStatus.tsx} | 9 +- ...ContentEditable.js => ContentEditable.tsx} | 52 +- .../ContextMenu/{Header.js => Header.ts} | 1 - .../ContextMenu/{MenuItem.js => MenuItem.tsx} | 30 +- ...owMenuButton.js => OverflowMenuButton.tsx} | 10 +- .../{Separator.js => Separator.tsx} | 3 +- app/components/ContextMenu/Template.js | 197 - app/components/ContextMenu/Template.tsx | 225 + .../ContextMenu/{index.js => index.tsx} | 78 +- ...{CopyToClipboard.js => CopyToClipboard.ts} | 21 +- .../{DelayedMount.js => DelayedMount.ts} | 5 +- app/components/{Dialogs.js => Dialogs.tsx} | 8 +- app/components/{Divider.js => Divider.ts} | 1 - ...ntBreadcrumb.js => DocumentBreadcrumb.tsx} | 73 +- ...DocumentHistory.js => DocumentHistory.tsx} | 50 +- .../{DocumentList.js => DocumentList.tsx} | 24 +- ...cumentListItem.js => DocumentListItem.tsx} | 72 +- .../{DocumentMeta.js => DocumentMeta.tsx} | 43 +- ...WithViews.js => DocumentMetaWithViews.tsx} | 29 +- .../{DocumentTasks.js => DocumentTasks.tsx} | 30 +- .../{DocumentViews.js => DocumentViews.tsx} | 32 +- app/components/{Editor.js => Editor.tsx} | 131 +- app/components/{Empty.js => Empty.ts} | 1 - .../{ErrorBoundary.js => ErrorBoundary.tsx} | 48 +- .../{EventBoundary.js => EventBoundary.tsx} | 8 +- .../{EventListItem.js => EventListItem.tsx} | 39 +- app/components/{Facepile.js => Facepile.tsx} | 25 +- app/components/{Fade.js => Fade.ts} | 5 +- .../{FilterOptions.js => FilterOptions.tsx} | 56 +- app/components/{Flex.js => Flex.tsx} | 33 +- ...screenLoading.js => FullscreenLoading.tsx} | 7 +- .../{GithubLogo.js => GithubLogo.tsx} | 7 +- .../{GroupListItem.js => GroupListItem.tsx} | 46 +- app/components/{Guide.js => Guide.tsx} | 22 +- app/components/{Header.js => Header.tsx} | 19 +- app/components/{Heading.js => Heading.ts} | 3 +- app/components/{HelpText.js => HelpText.ts} | 3 +- .../{Highlight.js => Highlight.tsx} | 17 +- .../{HoverPreview.js => HoverPreview.tsx} | 50 +- ...ewDocument.js => HoverPreviewDocument.tsx} | 20 +- .../{IconPicker.js => IconPicker.tsx} | 44 +- app/components/{Input.js => Input.tsx} | 94 +- .../{InputLarge.js => InputLarge.ts} | 1 - .../{InputRich.js => InputRich.tsx} | 33 +- .../{InputSearch.js => InputSearch.tsx} | 17 +- ...InputSearchPage.js => InputSearchPage.tsx} | 34 +- .../{InputSelect.js => InputSelect.tsx} | 98 +- ...ermission.js => InputSelectPermission.tsx} | 29 +- app/components/InputSelectRole.js | 25 - app/components/InputSelectRole.tsx | 39 + app/components/{Key.js => Key.ts} | 1 - app/components/{Labeled.js => Labeled.tsx} | 11 +- .../{LanguagePrompt.js => LanguagePrompt.tsx} | 24 +- app/components/{Layout.js => Layout.tsx} | 109 +- app/components/List/{Item.js => Item.tsx} | 67 +- app/components/List/{List.js => List.ts} | 1 - .../List/{Placeholder.js => Placeholder.tsx} | 9 +- app/components/List/{index.js => index.ts} | 2 +- .../LoadingIndicator/LoadingIndicator.js | 25 - .../LoadingIndicator/LoadingIndicator.ts | 16 + ...ndicatorBar.js => LoadingIndicatorBar.tsx} | 1 - .../LoadingIndicator/{index.js => index.ts} | 3 +- .../{LocaleTime.js => LocaleTime.tsx} | 36 +- ...{MenuIconWrapper.js => MenuIconWrapper.ts} | 1 - app/components/{Modal.js => Modal.tsx} | 48 +- app/components/NavLink.js | 26 - app/components/NavLink.tsx | 28 + app/components/{Notice.js => Notice.ts} | 1 - .../{NoticeAlert.js => NoticeAlert.tsx} | 17 +- app/components/{NoticeTip.js => NoticeTip.ts} | 1 - app/components/NudeButton.js | 20 - app/components/NudeButton.tsx | 20 + .../{OutlineLogo.js => OutlineLogo.tsx} | 7 +- app/components/{PageTheme.js => PageTheme.ts} | 5 +- .../{PageTitle.js => PageTitle.tsx} | 13 +- ...umentList.js => PaginatedDocumentList.tsx} | 33 +- ...tedEventList.js => PaginatedEventList.tsx} | 24 +- ...tedList.test.js => PaginatedList.test.tsx} | 45 +- .../{PaginatedList.js => PaginatedList.tsx} | 76 +- .../{PathToDocument.js => PathToDocument.tsx} | 30 +- ...derDocument.js => PlaceholderDocument.tsx} | 13 +- ...PlaceholderText.js => PlaceholderText.tsx} | 29 +- app/components/{Popover.js => Popover.tsx} | 10 +- .../{ProfiledRoute.js => ProfiledRoute.ts} | 9 +- ...{RegisterKeyDown.js => RegisterKeyDown.ts} | 7 +- app/components/{Scene.js => Scene.tsx} | 25 +- .../{ScrollToTop.js => ScrollToTop.ts} | 11 +- .../{Scrollable.js => Scrollable.tsx} | 32 +- app/components/Sidebar/{Main.js => Main.tsx} | 49 +- .../Sidebar/{Settings.js => Settings.tsx} | 16 +- .../Sidebar/{Sidebar.js => Sidebar.tsx} | 85 +- .../{ArchiveLink.js => ArchiveLink.tsx} | 23 +- .../{CollectionLink.js => CollectionLink.tsx} | 92 +- .../{Collections.js => Collections.tsx} | 30 +- .../{Disclosure.js => Disclosure.ts} | 1 - .../{DocumentLink.js => DocumentLink.tsx} | 114 +- .../{DropCursor.js => DropCursor.tsx} | 16 +- .../{DropToImport.js => DropToImport.tsx} | 44 +- .../{EditableTitle.js => EditableTitle.tsx} | 18 +- .../components/{Header.js => Header.ts} | 3 +- .../components/{NavLink.js => NavLink.tsx} | 58 +- ...lections.js => PlaceholderCollections.tsx} | 3 +- .../{ResizeBorder.js => ResizeBorder.ts} | 1 - .../components/{Section.js => Section.ts} | 3 +- .../{SidebarAction.js => SidebarAction.tsx} | 18 +- .../{SidebarLink.js => SidebarLink.tsx} | 56 +- .../components/{Starred.js => Starred.tsx} | 31 +- .../{StarredLink.js => StarredLink.tsx} | 59 +- .../{TeamButton.js => TeamButton.tsx} | 25 +- .../components/{Toggle.js => Toggle.tsx} | 14 +- .../{TrashLink.js => TrashLink.tsx} | 25 +- .../components/{Version.js => Version.tsx} | 5 +- app/components/Sidebar/{index.js => index.ts} | 2 +- .../{SkipNavContent.js => SkipNavContent.tsx} | 1 - .../{SkipNavLink.js => SkipNavLink.tsx} | 3 +- .../{SlackIcon.js => SlackIcon.tsx} | 3 +- .../{SocketProvider.js => SocketProvider.tsx} | 131 +- app/components/{Star.js => Star.tsx} | 14 +- .../{Subheading.js => Subheading.tsx} | 11 +- app/components/{Switch.js => Switch.tsx} | 30 +- app/components/{Tab.js => Tab.tsx} | 12 +- app/components/{Table.js => Table.tsx} | 80 +- app/components/{Tabs.js => Tabs.tsx} | 10 +- app/components/{TeamLogo.js => TeamLogo.ts} | 3 +- app/components/{Theme.js => Theme.tsx} | 29 +- app/components/{Time.js => Time.tsx} | 18 +- app/components/{Toast.js => Toast.tsx} | 39 +- app/components/{Toasts.js => Toasts.tsx} | 9 +- app/components/Tooltip.js | 73 - app/components/Tooltip.tsx | 69 + .../{ZapierIcon.js => ZapierIcon.tsx} | 3 +- app/components/withStores.tsx | 34 + app/env.js | 3 - app/env.ts | 11 + app/hooks/{useBoolean.js => useBoolean.ts} | 6 +- ...dBarActions.js => useCommandBarActions.ts} | 8 +- .../{useCurrentTeam.js => useCurrentTeam.ts} | 1 - ...{useCurrentToken.js => useCurrentToken.ts} | 1 - .../{useCurrentUser.js => useCurrentUser.ts} | 1 - ...cedCallback.js => useDebouncedCallback.ts} | 8 +- app/hooks/{useIdle.js => useIdle.ts} | 4 +- ...ImportDocument.js => useImportDocument.ts} | 15 +- .../{useIsMounted.js => useIsMounted.ts} | 2 - app/hooks/{useKeyDown.js => useKeyDown.ts} | 25 +- .../{useMediaQuery.js => useMediaQuery.ts} | 6 +- .../{useMenuHeight.js => useMenuHeight.ts} | 11 +- app/hooks/{useMobile.js => useMobile.ts} | 3 +- ...PageVisibility.js => usePageVisibility.ts} | 6 +- app/hooks/{usePrevious.js => usePrevious.ts} | 5 +- app/hooks/{useQuery.js => useQuery.ts} | 1 - app/hooks/{useSessions.js => useSessions.ts} | 16 +- app/hooks/useStores.js | 8 - app/hooks/useStores.ts | 7 + app/hooks/{useToasts.js => useToasts.ts} | 7 +- app/hooks/{useUnmount.js => useUnmount.ts} | 4 +- .../{useUserLocale.js => useUserLocale.ts} | 1 - ...Position.js => useWindowScrollPosition.ts} | 32 +- .../{useWindowSize.js => useWindowSize.ts} | 11 +- app/{index.js => index.tsx} | 34 +- app/menus/{AccountMenu.js => AccountMenu.tsx} | 38 +- .../{BreadcrumbMenu.js => BreadcrumbMenu.tsx} | 16 +- ...rMenu.js => CollectionGroupMemberMenu.tsx} | 22 +- .../{CollectionMenu.js => CollectionMenu.tsx} | 75 +- ...tionSortMenu.js => CollectionSortMenu.tsx} | 27 +- .../{DocumentMenu.js => DocumentMenu.tsx} | 173 +- ...OperationMenu.js => FileOperationMenu.tsx} | 21 +- ...GroupMemberMenu.js => GroupMemberMenu.tsx} | 19 +- app/menus/{GroupMenu.js => GroupMenu.tsx} | 32 +- app/menus/{MemberMenu.js => MemberMenu.tsx} | 19 +- ...cumentMenu.js => NewChildDocumentMenu.tsx} | 29 +- ...NewDocumentMenu.js => NewDocumentMenu.tsx} | 35 +- ...NewTemplateMenu.js => NewTemplateMenu.tsx} | 33 +- .../{RevisionMenu.js => RevisionMenu.tsx} | 49 +- app/menus/{ShareMenu.js => ShareMenu.tsx} | 37 +- ...ontentsMenu.js => TableOfContentsMenu.tsx} | 27 +- .../{TemplatesMenu.js => TemplatesMenu.tsx} | 31 +- app/menus/{UserMenu.js => UserMenu.tsx} | 55 +- app/menus/separator.js | 7 - app/menus/separator.ts | 7 + app/models/{ApiKey.js => ApiKey.ts} | 3 +- app/models/{BaseModel.js => BaseModel.ts} | 23 +- app/models/Collection.js | 129 - ...{Collection.test.js => Collection.test.ts} | 8 +- app/models/Collection.ts | 158 + ...ership.js => CollectionGroupMembership.ts} | 4 +- app/models/{Document.js => Document.ts} | 170 +- app/models/{Event.js => Event.ts} | 27 +- .../{FileOperation.js => FileOperation.ts} | 10 +- app/models/{Group.js => Group.ts} | 4 +- ...{GroupMembership.js => GroupMembership.ts} | 3 +- app/models/{Integration.js => Integration.ts} | 26 +- app/models/{Membership.js => Membership.ts} | 4 +- ...ationSetting.js => NotificationSetting.ts} | 2 +- app/models/{Policy.js => Policy.ts} | 6 +- app/models/{Revision.js => Revision.ts} | 6 +- app/models/{Share.js => Share.ts} | 13 +- app/models/{Team.js => Team.ts} | 15 +- app/models/{User.js => User.ts} | 13 +- app/models/{View.js => View.ts} | 6 +- ...erExtension.js => MultiplayerExtension.ts} | 3 +- .../{authenticated.js => authenticated.tsx} | 59 +- app/routes/index.js | 50 - app/routes/index.tsx | 69 + app/routes/{settings.js => settings.tsx} | 29 +- .../{APITokenNew.js => APITokenNew.tsx} | 35 +- app/scenes/{Archive.js => Archive.tsx} | 14 +- app/scenes/{Collection.js => Collection.tsx} | 132 +- ...llectionDelete.js => CollectionDelete.tsx} | 34 +- .../{CollectionEdit.js => CollectionEdit.tsx} | 54 +- ...llectionExport.js => CollectionExport.tsx} | 30 +- .../{CollectionNew.js => CollectionNew.tsx} | 84 +- ...ollection.js => AddGroupsToCollection.tsx} | 76 +- ...ollection.js => AddPeopleToCollection.tsx} | 71 +- ...m.js => CollectionGroupMemberListItem.tsx} | 40 +- .../{MemberListItem.js => MemberListItem.tsx} | 48 +- .../{UserListItem.js => UserListItem.tsx} | 19 +- .../{index.js => index.tsx} | 105 +- app/scenes/Document/{Shared.js => Shared.tsx} | 36 +- .../components/{Container.js => Container.ts} | 3 +- .../components/{Contents.js => Contents.tsx} | 28 +- .../{DataLoader.js => DataLoader.tsx} | 127 +- .../components/{Document.js => Document.tsx} | 244 +- .../{EditableTitle.js => EditableTitle.tsx} | 56 +- .../components/{Editor.js => Editor.tsx} | 65 +- .../components/{Header.js => Header.tsx} | 102 +- .../{HideSidebar.js => HideSidebar.ts} | 7 +- ...sButton.js => KeyboardShortcutsButton.tsx} | 12 +- .../components/{Loading.js => Loading.tsx} | 16 +- .../{MarkAsViewed.js => MarkAsViewed.ts} | 15 +- ...iplayerEditor.js => MultiplayerEditor.tsx} | 88 +- ...blicBreadcrumb.js => PublicBreadcrumb.tsx} | 38 +- ...blicReferences.js => PublicReferences.tsx} | 22 +- ...renceListItem.js => ReferenceListItem.tsx} | 29 +- app/scenes/Document/components/References.js | 82 - app/scenes/Document/components/References.tsx | 74 + .../{ShareButton.js => ShareButton.tsx} | 19 +- .../{SharePopover.js => SharePopover.tsx} | 80 +- .../{SocketPresence.js => SocketPresence.ts} | 24 +- app/scenes/Document/{index.js => index.tsx} | 40 +- .../{DocumentDelete.js => DocumentDelete.tsx} | 56 +- .../{DocumentMove.js => DocumentMove.tsx} | 55 +- .../{DocumentNew.js => DocumentNew.tsx} | 25 +- ...tDelete.js => DocumentPermanentDelete.tsx} | 44 +- ...cumentReparent.js => DocumentReparent.tsx} | 74 +- ...ntTemplatize.js => DocumentTemplatize.tsx} | 46 +- app/scenes/{Drafts.js => Drafts.tsx} | 80 +- app/scenes/{Error404.js => Error404.tsx} | 8 +- .../{ErrorOffline.js => ErrorOffline.tsx} | 8 +- .../{ErrorSuspended.js => ErrorSuspended.tsx} | 23 +- .../{GroupDelete.js => GroupDelete.tsx} | 37 +- app/scenes/{GroupEdit.js => GroupEdit.tsx} | 39 +- ...dPeopleToGroup.js => AddPeopleToGroup.tsx} | 74 +- .../{GroupMembers.js => GroupMembers.tsx} | 65 +- ...berListItem.js => GroupMemberListItem.tsx} | 27 +- .../{UserListItem.js => UserListItem.tsx} | 19 +- .../GroupMembers/{index.js => index.ts} | 2 +- app/scenes/{GroupNew.js => GroupNew.tsx} | 36 +- app/scenes/{Home.js => Home.tsx} | 37 +- app/scenes/{Invite.js => Invite.tsx} | 107 +- ...oardShortcuts.js => KeyboardShortcuts.tsx} | 39 +- app/scenes/Login/{Notices.js => Notices.tsx} | 5 +- .../Login/{Provider.js => Provider.tsx} | 53 +- app/scenes/Login/{index.js => index.tsx} | 54 +- app/scenes/{Logout.js => Logout.tsx} | 3 +- app/scenes/Search/{Search.js => Search.tsx} | 164 +- ...llectionFilter.js => CollectionFilter.tsx} | 16 +- app/scenes/Search/components/DateFilter.js | 35 - app/scenes/Search/components/DateFilter.tsx | 49 + .../{SearchInput.js => SearchInput.tsx} | 13 +- .../{StatusFilter.js => StatusFilter.tsx} | 14 +- .../{UserFilter.js => UserFilter.tsx} | 18 +- app/scenes/Search/{index.js => index.ts} | 2 +- .../Settings/{Details.js => Details.tsx} | 51 +- .../Settings/{Features.js => Features.tsx} | 24 +- app/scenes/Settings/{Groups.js => Groups.tsx} | 31 +- .../{ImportExport.js => ImportExport.tsx} | 118 +- .../{Notifications.js => Notifications.tsx} | 32 +- app/scenes/Settings/{People.js => People.tsx} | 54 +- .../Settings/{Profile.js => Profile.tsx} | 42 +- .../Settings/{Security.js => Security.tsx} | 42 +- app/scenes/Settings/{Shares.js => Shares.tsx} | 21 +- app/scenes/Settings/{Slack.js => Slack.tsx} | 64 +- app/scenes/Settings/{Tokens.js => Tokens.tsx} | 27 +- app/scenes/Settings/{Zapier.js => Zapier.tsx} | 11 +- ...nListItem.js => FileOperationListItem.tsx} | 24 +- .../{ImageUpload.js => ImageUpload.tsx} | 67 +- ...onListItem.js => NotificationListItem.tsx} | 17 +- .../{PeopleTable.js => PeopleTable.tsx} | 50 +- .../{ShareListItem.js => ShareListItem.tsx} | 19 +- .../{SlackButton.js => SlackButton.tsx} | 24 +- .../{TokenListItem.js => TokenListItem.tsx} | 15 +- .../Settings/components/UserListItem.js | 78 - .../Settings/components/UserListItem.tsx | 52 + ...erStatusFilter.js => UserStatusFilter.tsx} | 12 +- app/scenes/{Templates.js => Templates.tsx} | 29 +- app/scenes/{Trash.js => Trash.tsx} | 14 +- app/scenes/{UserDelete.js => UserDelete.tsx} | 31 +- .../{UserProfile.js => UserProfile.tsx} | 39 +- .../{ApiKeysStore.js => ApiKeysStore.ts} | 7 +- app/stores/{AuthStore.js => AuthStore.ts} | 137 +- app/stores/{BaseStore.js => BaseStore.ts} | 139 +- ....js => CollectionGroupMembershipsStore.ts} | 33 +- ...ollectionsStore.js => CollectionsStore.ts} | 83 +- .../{DialogsStore.js => DialogsStore.ts} | 40 +- ...senceStore.js => DocumentPresenceStore.ts} | 26 +- .../{DocumentsStore.js => DocumentsStore.ts} | 276 +- app/stores/{EventsStore.js => EventsStore.ts} | 7 +- ...rationsStore.js => FileOperationsStore.ts} | 7 +- ...shipsStore.js => GroupMembershipsStore.ts} | 26 +- app/stores/{GroupsStore.js => GroupsStore.ts} | 23 +- ...egrationsStore.js => IntegrationsStore.ts} | 14 +- ...embershipsStore.js => MembershipsStore.ts} | 31 +- app/stores/NotificationSettingsStore.js | 17 - app/stores/NotificationSettingsStore.ts | 20 + .../{PoliciesStore.js => PoliciesStore.ts} | 3 +- app/stores/RevisionsStore.js | 87 - app/stores/RevisionsStore.ts | 66 + app/stores/{RootStore.js => RootStore.ts} | 1 - app/stores/{SharesStore.js => SharesStore.ts} | 41 +- app/stores/ToastsStore.test.js | 28 - app/stores/ToastsStore.test.ts | 25 + app/stores/{ToastsStore.js => ToastsStore.ts} | 9 +- app/stores/{UiStore.js => UiStore.ts} | 88 +- app/stores/{UsersStore.js => UsersStore.ts} | 93 +- app/stores/{ViewsStore.js => ViewsStore.ts} | 7 +- app/stores/{index.js => index.ts} | 3 +- app/styles/{animations.js => animations.ts} | 1 - app/styles/{globals.js => globals.ts} | 1 - app/test/setup.js | 14 - app/test/setup.ts | 16 + app/test/{support.js => support.ts} | 1 - app/types.ts | 167 + app/types/index.js | 163 - app/typings/index.d.ts | 63 + app/typings/styled-components.d.ts | 182 + app/utils/{ApiClient.js => ApiClient.ts} | 54 +- .../__mocks__/{ApiClient.js => ApiClient.ts} | 6 +- .../{compressImage.js => compressImage.ts} | 12 +- app/utils/{dates.js => dates.ts} | 18 +- app/utils/{developer.js => developer.ts} | 3 +- app/utils/{domains.js => domains.ts} | 6 +- app/utils/{download.js => download.ts} | 74 +- app/utils/{emoji.js => emoji.ts} | 2 - app/utils/{errors.js => errors.ts} | 8 +- app/utils/getDataTransferFiles.js | 22 - app/utils/getDataTransferFiles.ts | 29 + app/utils/{history.js => history.ts} | 1 - app/utils/{i18n.js => i18n.ts} | 3 +- app/utils/{isTextInput.js => isTextInput.ts} | 4 +- app/utils/{keyboard.js => keyboard.ts} | 3 +- app/utils/{language.js => language.ts} | 7 +- app/utils/{motion.js => motion.ts} | 2 +- .../{pageVisibility.js => pageVisibility.ts} | 2 - .../{routeHelpers.js => routeHelpers.ts} | 25 +- app/utils/{sentry.js => sentry.ts} | 7 +- app/utils/{uploadFile.js => uploadFile.ts} | 31 +- app/utils/{urls.test.js => urls.test.ts} | 1 - app/utils/{urls.js => urls.ts} | 4 +- docs/ARCHITECTURE.md | 4 +- flow-typed/globals.js | 16 - flow-typed/npm/@sentry/node_vx.x.x.js | 309 - flow-typed/npm/@tippy.js/react_vx.x.x.js | 59 - .../npm/@tommoor/remove-markdown_vx.x.x.js | 38 - flow-typed/npm/autotrack_vx.x.x.js | 434 - flow-typed/npm/aws-sdk_vx.x.x.js | 2682 ---- .../boundless-arrow-key-navigation_vx.x.x.js | 58 - flow-typed/npm/bull_vx.x.x.js | 132 - flow-typed/npm/cancan_vx.x.x.js | 33 - flow-typed/npm/classnames_v2.x.x.js | 18 - flow-typed/npm/copy-to-clipboard_v3.x.x.js | 13 - flow-typed/npm/core-js_vx.x.x.js | 12113 ---------------- flow-typed/npm/debug_v2.x.x.js | 30 - flow-typed/npm/debug_vx.x.x.js | 63 - flow-typed/npm/diff_vx.x.x.js | 172 - flow-typed/npm/dotenv_v4.x.x.js | 19 - flow-typed/npm/emoji-name-map_vx.x.x.js | 32 - flow-typed/npm/emoji-regex_vx.x.x.js | 55 - flow-typed/npm/enzyme-to-json_vx.x.x.js | 74 - flow-typed/npm/enzyme_v2.3.x.js | 110 - flow-typed/npm/es6-error_v4.x.x.js | 8 - flow-typed/npm/exports-loader_vx.x.x.js | 33 - flow-typed/npm/fbemitter_vx.x.x.js | 59 - flow-typed/npm/fetch-test-server_vx.x.x.js | 38 - flow-typed/npm/file-loader_vx.x.x.js | 42 - flow-typed/npm/flow-bin_v0.x.x.js | 6 - flow-typed/npm/flow-typed_vx.x.x.js | 186 - flow-typed/npm/fs-extra_vx.x.x.js | 288 - flow-typed/npm/highlight.js_vx.x.x.js | 1124 -- flow-typed/npm/history_vx.x.x.js | 172 - flow-typed/npm/html-webpack-plugin_vx.x.x.js | 59 - flow-typed/npm/http-errors_v1.x.x.js | 60 - flow-typed/npm/imports-loader_vx.x.x.js | 33 - flow-typed/npm/invariant_v2.x.x.js | 6 - flow-typed/npm/ioredis_vx.x.x.js | 270 - flow-typed/npm/isomorphic-fetch_v2.x.x.js | 9 - flow-typed/npm/jest-cli_vx.x.x.js | 104 - flow-typed/npm/jest_v22.x.x.js | 988 -- flow-typed/npm/js-cookie_v2.x.x.js | 0 flow-typed/npm/js-search_vx.x.x.js | 215 - flow-typed/npm/js-tree_vx.x.x.js | 38 - flow-typed/npm/json-loader_vx.x.x.js | 33 - flow-typed/npm/jsonwebtoken_v8.3.x.js | 164 - flow-typed/npm/jszip_vx.x.x.js | 304 - flow-typed/npm/koa-bodyparser_v4.x.x.js | 29 - flow-typed/npm/koa-compress_vx.x.x.js | 33 - flow-typed/npm/koa-connect_vx.x.x.js | 66 - flow-typed/npm/koa-convert_vx.x.x.js | 38 - flow-typed/npm/koa-helmet_vx.x.x.js | 39 - flow-typed/npm/koa-jwt_vx.x.x.js | 77 - flow-typed/npm/koa-logger_vx.x.x.js | 33 - flow-typed/npm/koa-mount_vx.x.x.js | 33 - flow-typed/npm/koa-onerror_vx.x.x.js | 33 - flow-typed/npm/koa-router_vx.x.x.js | 39 - flow-typed/npm/koa-sslify_vx.x.x.js | 52 - flow-typed/npm/koa-static_v4.x.x.js | 34 - .../npm/koa-webpack-dev-middleware_vx.x.x.js | 35 - .../npm/koa-webpack-hot-middleware_vx.x.x.js | 33 - flow-typed/npm/koa_v2.0.x.js | 316 - flow-typed/npm/lib0_vx.x.x.js | 377 - flow-typed/npm/lib0_vx.x.x.js~4256e7ec (flow) | 377 - flow-typed/npm/lodash.orderby_vx.x.x.js | 33 - flow-typed/npm/lodash_v4.x.x.js | 6113 -------- flow-typed/npm/marked-sanitized_vx.x.x.js | 39 - flow-typed/npm/mobx-react-devtools_vx.x.x.js | 38 - flow-typed/npm/mobx-react_vx.x.x.js | 108 - flow-typed/npm/natural-sort_vx.x.x.js | 32 - flow-typed/npm/node-dev_vx.x.x.js | 88 - flow-typed/npm/node-sass_vx.x.x.js | 249 - flow-typed/npm/nodemailer_vx.x.x.js | 306 - flow-typed/npm/nodemon_vx.x.x.js | 249 - flow-typed/npm/normalizr_v2.x.x.js | 26 - flow-typed/npm/outline-icons_vx.x.x.js | 602 - flow-typed/npm/oy-vey_vx.x.x.js | 521 - flow-typed/npm/parse-domain_vx.x.x.js | 151 - flow-typed/npm/pg-hstore_vx.x.x.js | 59 - flow-typed/npm/pg_v6.x.x.js | 302 - flow-typed/npm/polished_vx.x.x.js | 1852 --- flow-typed/npm/prettier_v1.x.x.js | 228 - flow-typed/npm/pui-react-tooltip_vx.x.x.js | 32 - flow-typed/npm/query-string_vx.x.x.js | 33 - flow-typed/npm/raf_vx.x.x.js | 52 - flow-typed/npm/randomstring_v1.x.x.js | 13 - flow-typed/npm/raw-loader_vx.x.x.js | 33 - .../npm/react-addons-test-utils_v15.x.x.js | 28 - flow-typed/npm/react-avatar-editor_vx.x.x.js | 73 - flow-typed/npm/react-color_v2.x.x.js | 242 - flow-typed/npm/react-helmet_v5.x.x.js | 60 - flow-typed/npm/react-i18next_vx.x.x.js | 109 - .../npm/react-medium-image-zoom_vx.x.x.js | 94 - flow-typed/npm/react-portal_vx.x.x.js | 115 - flow-typed/npm/react-router-dom_v5.x.x.js | 181 - flow-typed/npm/react-test-renderer_v16.x.x.js | 75 - flow-typed/npm/react-waypoint_vx.x.x.js | 45 - flow-typed/npm/redis-lock_vx.x.x.js | 38 - flow-typed/npm/redis_v2.x.x.js | 354 - flow-typed/npm/rich-markdown-editor_vx.x.x.js | 1266 -- flow-typed/npm/rimraf_v2.x.x.js | 20 - flow-typed/npm/sass-loader_vx.x.x.js | 33 - flow-typed/npm/semver_vx.x.x.js | 349 - flow-typed/npm/sequelize-cli_vx.x.x.js | 796 - flow-typed/npm/sequelize-encrypted_vx.x.x.js | 41 - flow-typed/npm/sequelize_vx.x.x.js | 706 - flow-typed/npm/slate-md-serializer_vx.x.x.js | 53 - flow-typed/npm/slate_vx.x.x.js | 53 - flow-typed/npm/slug_v0.9.x.js | 26 - flow-typed/npm/slug_vx.x.x.js | 46 - flow-typed/npm/socket.io-redis_vx.x.x.js | 33 - flow-typed/npm/socket.io_vx.x.x.js | 63 - flow-typed/npm/socketio-auth_vx.x.x.js | 45 - flow-typed/npm/string-hash_vx.x.x.js | 38 - .../npm/string-replace-to-array_vx.x.x.js | 39 - .../styled-components-breakpoint_vx.x.x.js | 32 - flow-typed/npm/styled-components_vx.x.x.js | 143 - flow-typed/npm/styled-normalize_vx.x.x.js | 35 - flow-typed/npm/tiny-cookie_vx.x.x.js | 100 - flow-typed/npm/tmp_vx.x.x.js | 32 - flow-typed/npm/url-loader_vx.x.x.js | 33 - flow-typed/npm/uuid_v2.x.x.js | 17 - flow-typed/npm/validator_vx.x.x.js | 479 - flow-typed/npm/y-indexeddb_vx.x.x.js | 39 - flow-typed/npm/y-prosemirror_vx.x.x.js | 67 - flow-typed/npm/y-protocols_vx.x.x.js | 67 - flow-typed/npm/yjs_vx.x.x.js | 430 - i18next-parser.config.js | 1 - package.json | 85 +- server/.babelrc | 3 +- server/.eslintrc | 9 + server/.jestconfig.json | 6 +- server/__mocks__/events.js | 4 - server/__mocks__/events.ts | 5 + ...ailer.test.js.snap => mailer.test.ts.snap} | 0 .../{authentication.js => authentication.ts} | 24 +- server/collaboration/logger.js | 22 - server/collaboration/logger.ts | 22 + .../{persistence.js => persistence.ts} | 35 +- server/collaboration/tracing.js | 66 - server/collaboration/tracing.ts | 60 + .../{markdownToYDoc.js => markdownToYDoc.ts} | 9 +- ...ner.test.js => accountProvisioner.test.ts} | 41 +- ...ntProvisioner.js => accountProvisioner.ts} | 83 +- ...achmentCreator.js => attachmentCreator.ts} | 26 +- ...ctionExporter.js => collectionExporter.ts} | 20 +- ...ter.test.js => collectionImporter.test.ts} | 17 +- ...ctionImporter.js => collectionImporter.ts} | 66 +- ...{documentCreator.js => documentCreator.ts} | 58 +- ...orter.test.js => documentImporter.test.ts} | 33 +- ...ocumentImporter.js => documentImporter.ts} | 56 +- server/commands/documentMover.js | 180 - ...entMover.test.js => documentMover.test.ts} | 39 +- server/commands/documentMover.ts | 222 + ...st.js => documentPermanentDeleter.test.ts} | 62 +- ...Deleter.js => documentPermanentDeleter.ts} | 15 +- ...{documentUpdater.js => documentUpdater.ts} | 12 +- server/commands/fileOperationDeleter.js | 31 - ...r.test.js => fileOperationDeleter.test.ts} | 16 +- server/commands/fileOperationDeleter.ts | 34 + ...reator.test.js => revisionCreator.test.ts} | 16 +- ...{revisionCreator.js => revisionCreator.ts} | 21 +- ...eamCreator.test.js => teamCreator.test.ts} | 23 +- .../{teamCreator.js => teamCreator.ts} | 47 +- ...r.test.js => teamPermanentDeleter.test.ts} | 60 +- ...nentDeleter.js => teamPermanentDeleter.ts} | 102 +- ...serCreator.test.js => userCreator.test.ts} | 40 +- .../{userCreator.js => userCreator.ts} | 76 +- ...estroyer.test.js => userDestroyer.test.ts} | 26 +- .../{userDestroyer.js => userDestroyer.ts} | 35 +- server/commands/userInviter.test.js | 63 - server/commands/userInviter.test.ts | 93 + .../{userInviter.js => userInviter.ts} | 38 +- ...uspender.test.js => userSuspender.test.ts} | 28 +- .../{userSuspender.js => userSuspender.ts} | 33 +- ...ail.js => CollectionNotificationEmail.tsx} | 13 +- ...Email.js => DocumentNotificationEmail.tsx} | 18 +- ...FailureEmail.js => ExportFailureEmail.tsx} | 1 - ...SuccessEmail.js => ExportSuccessEmail.tsx} | 5 +- .../{InviteEmail.js => InviteEmail.tsx} | 11 +- .../{SigninEmail.js => SigninEmail.tsx} | 5 +- .../{WelcomeEmail.js => WelcomeEmail.tsx} | 3 +- .../emails/components/{Body.js => Body.tsx} | 4 +- .../components/{Button.js => Button.tsx} | 7 +- .../{EmailLayout.js => EmailLayout.tsx} | 5 +- .../{EmptySpace.js => EmptySpace.tsx} | 6 +- .../components/{Footer.js => Footer.tsx} | 11 +- .../components/{Header.js => Header.tsx} | 1 - .../components/{Heading.js => Heading.tsx} | 4 +- server/emails/{index.js => index.ts} | 13 +- server/env.js | 4 - server/env.ts | 6 + server/errors.js | 117 - server/errors.ts | 146 + server/{index.js => index.ts} | 21 +- server/logging/{logger.js => logger.ts} | 23 +- server/logging/{metrics.js => metrics.ts} | 10 +- server/logging/{sentry.js => sentry.ts} | 18 +- server/{mailer.test.js => mailer.test.ts} | 8 +- server/{mailer.js => mailer.tsx} | 66 +- .../{apexRedirect.js => apexRedirect.ts} | 5 +- ...ication.test.js => authentication.test.ts} | 47 +- .../{authentication.js => authentication.ts} | 44 +- .../{errorHandling.js => errorHandling.ts} | 8 +- .../{methodOverride.js => methodOverride.ts} | 8 +- .../middlewares/{passport.js => passport.ts} | 20 +- server/middlewares/validation.js | 78 - server/migrations/20160619080644-initial.js | 98 +- .../20160622043741-add-parent-document.js | 5 +- .../migrations/20160626063409-add-indexes.js | 38 +- .../20160626175224-add-revisions.js | 46 +- .../migrations/20160711071958-search-index.js | 3 - .../20160726061511-atlas-creator.js | 5 +- ...160812145029-document-atlas-soft-delete.js | 10 +- .../20160814083127-paranoia-indeces.js | 78 +- ...20160814095336-add-document-createdById.js | 9 +- ...0814111419-add-document-collaboratorIds.js | 4 +- .../20160815142720-app-collection-urlId.js | 5 +- .../20160816082738-add-revision-index.js | 5 +- .../migrations/20160824061730-add-apikeys.js | 21 +- .../20160824062457-add-apikey-indeces.js | 9 +- .../20160911230444-user-optional-slack-id.js | 9 +- .../20160911232911-user-unique-fields.js | 10 +- .../20160911234928-user-password.js | 5 +- ...-collection-documentStructure-migration.js | 9 +- server/migrations/20170604052346-add-views.js | 68 +- server/migrations/20170604052347-add-stars.js | 56 +- .../20170712055148-non-unique-email.js | 9 +- .../20170712072234-uniq-slack-id.js | 5 +- server/migrations/20170729215619-emoji.js | 5 +- .../20170827182423-improve-references.js | 31 +- .../20170904202454-allow-null-username.js | 5 +- server/migrations/20171010042938-add-event.js | 11 +- ...012353-remove-collection-navigationtree.js | 5 +- .../20171017055026-remove-document-html.js | 17 +- .../20171019071915-user-avatar-url.js | 5 +- .../20171023064220-collection-color.js | 5 +- .../20171218043717-add-authentications.js | 9 +- .../migrations/20171225143838-set-admins.js | 16 +- .../migrations/20180115021837-add-drafts.js | 30 +- .../20180212033504-add-integrations.js | 13 +- .../20180225203847-document-pinning.js | 9 +- .../20180303193036-suspended-users.js | 15 +- .../20180324214403-serializer-upgrade.js | 23 +- .../20180513041057-add-share-links.js | 11 +- .../migrations/20180528233909-google-auth.js | 28 +- .../20180528233910-rename-serviceid.js | 20 +- .../20180604182823-user-tracking.js | 28 +- .../20180604191743-revoke-share-links.js | 16 +- .../20180707220121-more-soft-delete.js | 16 +- .../20180707231201-remove-passwords.js | 8 +- .../20180708231200-serviceid-null.js | 8 +- server/migrations/20180808061353-cleanup.js | 16 +- .../20180819054252-disable-sharing.js | 10 +- .../20181031015046-add-subdomain-to-team.js | 14 +- .../20181124000438-add-notifications.js | 43 +- .../20181215192422-document-embeds.js | 10 +- .../20181227001547-collection-permissions.js | 33 +- .../migrations/20190404035736-add-archive.js | 10 +- .../20190423051708-add-search-indexes.js | 13 +- server/migrations/20190606035733-events.js | 37 +- .../migrations/20190704070630-welcome-docs.js | 10 +- server/migrations/20190706213213-backlinks.js | 15 +- .../migrations/20190811231511-maintainers.js | 32 +- .../20191118023010-cascade-delete.js | 28 +- .../20191119023010-cascade-backlinks.js | 31 +- ...20191119023011-cascade-parent-documents.js | 31 +- .../20191119023012-cascade-shares.js | 28 +- .../20191119023013-cascade-backlinks2.js | 28 +- .../migrations/20191121035144-guest-invite.js | 18 +- .../20191211044318-create-groups.js | 24 +- .../20191211044319-create-group-users.js | 24 +- .../20191228031525-edit-presence.js | 9 +- .../migrations/20200104233831-attachments.js | 13 +- ...20200122083721-create-collection-groups.js | 33 +- .../20200316040755-document-editor-version.js | 15 +- .../20200328175012-cascade-delete.js | 31 +- .../20200330053639-document-version.js | 15 +- .../migrations/20200519032353-text-backup.js | 15 +- .../20200522054958-collection-icon.js | 11 +- .../20200723055414-add-published-to-shares.js | 14 +- .../20200727051157-add-templates.js | 19 +- .../20200812170227-remove-collection-type.js | 13 +- .../20200915010511-create-search-queries.js | 1 + .../20200926204620-add-missing-indexes.js | 7 +- ...0201028043021-reverse-document-id-index.js | 5 +- .../20201103050534-custom-domains.js | 13 +- server/migrations/20201106122752-i18n.js | 9 +- .../20201206210619-update-attachment-cols.js | 41 +- .../20201211080408-attachment-no-cascade.js | 43 +- .../20201230031607-collection-sort.js | 13 +- ...0110143902-collection-rename-creator-id.js | 1 - ...210208062816-disable-collection-sharing.js | 10 +- .../20210218111237-add-collection-index.js | 1 - ...20210226232041-authentication-providers.js | 25 +- server/migrations/20210310051804-passport.js | 9 +- server/migrations/20210314173941-isViewer.js | 7 +- .../20210327005406-read-only-collections.js | 11 +- .../20210418053152-share-last-viewed.js | 5 +- .../20210426055334-nested-document-sharing.js | 5 +- .../20210430024222-marketing-tracking.js | 7 +- ...20210716064654-introduce-previousTitles.js | 11 +- ...10716071454-search-index-previousTitles.js | 6 +- .../20210716162923-events-indexes.js | 5 +- .../20210730042450-remove-unused-indexes.js | 8 +- .../20210730044247-remove-backup-column.js | 15 +- .../20210730044248-create-realtime.js | 1 - .../20210730210120-add-fileOperations.js | 39 +- ...0210915051740-collaborative-collections.js | 1 - .../20210921031555-missing-cascades.js | 100 +- .../20210923031555-missing-cascades.js | 52 +- .../20211003021903-missing-cascades.js | 30 +- .../20211015170955-add-defaultUserRole.js | 5 +- .../20211107021900-missing-cascades.js | 29 +- server/models/{ApiKey.js => ApiKey.ts} | 8 +- .../models/{Attachment.js => Attachment.ts} | 13 +- ...nProvider.js => AuthenticationProvider.ts} | 16 +- server/models/{Backlink.js => Backlink.ts} | 2 +- ...{Collection.test.js => Collection.test.ts} | 162 +- .../models/{Collection.js => Collection.ts} | 134 +- ...{CollectionGroup.js => CollectionGroup.ts} | 2 +- .../{CollectionUser.js => CollectionUser.ts} | 2 +- .../{Document.test.js => Document.test.ts} | 123 +- server/models/{Document.js => Document.ts} | 261 +- server/models/{Event.js => Event.ts} | 8 +- .../{FileOperation.js => FileOperation.ts} | 6 +- .../models/{Group.test.js => Group.test.ts} | 50 +- server/models/{Group.js => Group.ts} | 27 +- server/models/{GroupUser.js => GroupUser.ts} | 8 +- .../models/{Integration.js => Integration.ts} | 2 +- ...cation.js => IntegrationAuthentication.ts} | 2 +- .../{Notification.js => Notification.ts} | 2 +- ...ationSetting.js => NotificationSetting.ts} | 3 +- .../{Revision.test.js => Revision.test.ts} | 12 +- server/models/{Revision.js => Revision.ts} | 28 +- .../models/{SearchQuery.js => SearchQuery.ts} | 5 +- server/models/{Share.js => Share.ts} | 26 +- server/models/{Star.js => Star.ts} | 2 +- server/models/{Team.test.js => Team.test.ts} | 36 +- server/models/{Team.js => Team.ts} | 84 +- server/models/{User.test.js => User.test.ts} | 35 +- server/models/{User.js => User.ts} | 169 +- ...uthentication.js => UserAuthentication.ts} | 2 +- server/models/{View.js => View.ts} | 19 +- server/models/{index.js => index.ts} | 1 - server/policies/{apiKey.js => apiKey.ts} | 3 +- .../policies/{attachment.js => attachment.ts} | 3 +- ...nProvider.js => authenticationProvider.ts} | 11 +- ...{collection.test.js => collection.test.ts} | 43 +- .../policies/{collection.js => collection.ts} | 18 +- .../{document.test.js => document.test.ts} | 20 +- server/policies/{document.js => document.ts} | 21 +- server/policies/{group.js => group.ts} | 9 +- .../policies/{index.test.js => index.test.ts} | 11 +- server/policies/{index.js => index.ts} | 23 +- .../{integration.js => integration.ts} | 9 +- ...ationSetting.js => notificationSetting.ts} | 3 +- server/policies/{policy.js => policy.ts} | 2 +- server/policies/{share.js => share.ts} | 6 +- .../policies/{team.test.js => team.test.ts} | 17 +- server/policies/{team.js => team.ts} | 3 +- server/policies/{user.js => user.ts} | 23 +- .../{user.test.js.snap => user.test.ts.snap} | 0 server/presenters/apiKey.js | 11 - server/presenters/apiKey.ts | 11 + ...nProvider.js => authenticationProvider.ts} | 4 +- .../{collection.js => collection.ts} | 21 +- ...ership.js => collectionGroupMembership.ts} | 12 +- server/presenters/document.js | 81 - server/presenters/document.ts | 106 + server/presenters/{env.js => env.ts} | 4 +- server/presenters/event.js | 24 - server/presenters/event.ts | 33 + .../{fileOperation.js => fileOperation.ts} | 4 +- server/presenters/{group.js => group.ts} | 4 +- server/presenters/groupMembership.js | 18 - server/presenters/groupMembership.ts | 19 + server/presenters/{index.js => index.ts} | 1 - .../{integration.js => integration.ts} | 4 +- .../{membership.js => membership.ts} | 12 +- server/presenters/notificationSetting.js | 9 - server/presenters/notificationSetting.ts | 9 + server/presenters/policy.js | 13 - server/presenters/policy.ts | 20 + .../presenters/{revision.js => revision.ts} | 5 +- server/presenters/{share.js => share.ts} | 8 +- server/presenters/slackAttachment.js | 34 - server/presenters/slackAttachment.ts | 39 + server/presenters/{team.js => team.ts} | 4 +- server/presenters/user.js | 39 - .../presenters/{user.test.js => user.test.ts} | 4 - server/presenters/user.ts | 53 + server/presenters/{view.js => view.ts} | 4 +- server/queues/{index.js => index.ts} | 6 +- .../{backlinks.test.js => backlinks.test.ts} | 84 +- .../processors/{backlinks.js => backlinks.ts} | 41 +- .../processors/{debouncer.js => debouncer.ts} | 17 +- server/queues/processors/emails.js | 14 - server/queues/processors/emails.ts | 12 + .../processors/{exports.js => exports.ts} | 38 +- .../processors/{imports.js => imports.ts} | 14 +- ...ications.test.js => notifications.test.ts} | 46 +- .../{notifications.js => notifications.ts} | 20 +- .../{revisions.test.js => revisions.test.ts} | 38 +- .../processors/{revisions.js => revisions.ts} | 16 +- .../queues/processors/{slack.js => slack.ts} | 17 +- .../{websockets.js => websockets.ts} | 63 +- server/{redis.js => redis.ts} | 7 +- ....test.js.snap => collections.test.ts.snap} | 0 ...ts.test.js.snap => documents.test.ts.snap} | 0 ...vents.test.js.snap => events.test.ts.snap} | 0 ...roups.test.js.snap => groups.test.ts.snap} | 0 ...hares.test.js.snap => shares.test.ts.snap} | 0 ...{users.test.js.snap => users.test.ts.snap} | 0 ...{views.test.js.snap => views.test.ts.snap} | 0 server/routes/api/{apiKeys.js => apiKeys.ts} | 32 +- ...ttachments.test.js => attachments.test.ts} | 90 +- .../api/{attachments.js => attachments.ts} | 50 +- .../routes/api/{auth.test.js => auth.test.ts} | 62 +- server/routes/api/{auth.js => auth.ts} | 33 +- ...est.js => authenticationProviders.test.ts} | 46 +- ...roviders.js => authenticationProviders.ts} | 34 +- ...ollections.test.js => collections.test.ts} | 526 +- .../api/{collections.js => collections.ts} | 233 +- .../{documents.test.js => documents.test.ts} | 831 +- .../routes/api/{documents.js => documents.ts} | 712 +- .../api/{events.test.js => events.test.ts} | 64 +- server/routes/api/{events.js => events.ts} | 38 +- ...rations.test.js => fileOperations.test.ts} | 116 +- .../{fileOperations.js => fileOperations.ts} | 54 +- .../api/{groups.test.js => groups.test.ts} | 428 +- server/routes/api/{groups.js => groups.ts} | 97 +- .../api/{hooks.test.js => hooks.test.ts} | 66 +- server/routes/api/{hooks.js => hooks.ts} | 61 +- .../api/{index.test.js => index.test.ts} | 10 +- server/routes/api/{index.js => index.ts} | 17 +- .../api/{integrations.js => integrations.ts} | 27 +- .../{apiWrapper.js => apiWrapper.ts} | 9 +- .../api/middlewares/{editor.js => editor.ts} | 14 +- ...{pagination.test.js => pagination.test.ts} | 40 +- .../{pagination.js => pagination.ts} | 36 +- ...ionSettings.js => notificationSettings.ts} | 24 +- .../{revisions.test.js => revisions.test.ts} | 26 +- .../routes/api/{revisions.js => revisions.ts} | 39 +- .../api/{shares.test.js => shares.test.ts} | 264 +- server/routes/api/{shares.js => shares.ts} | 78 +- .../routes/api/{team.test.js => team.test.ts} | 38 +- server/routes/api/{team.js => team.ts} | 13 +- .../api/{users.test.js => users.test.ts} | 261 +- server/routes/api/{users.js => users.ts} | 171 +- .../api/{utils.test.js => utils.test.ts} | 59 +- server/routes/api/{utils.js => utils.ts} | 22 +- .../api/{views.test.js => views.test.ts} | 73 +- server/routes/api/{views.js => views.ts} | 36 +- .../auth/{index.test.js => index.test.ts} | 24 +- server/routes/auth/{index.js => index.ts} | 23 +- .../auth/providers/{azure.js => azure.ts} | 34 +- .../{email.test.js => email.test.ts} | 132 +- .../auth/providers/{email.js => email.ts} | 58 +- .../auth/providers/{google.js => google.ts} | 22 +- .../auth/providers/{index.js => index.ts} | 10 +- .../auth/providers/{oidc.js => oidc.ts} | 47 +- server/routes/auth/providers/slack.js | 203 - server/routes/auth/providers/slack.ts | 211 + .../routes/{index.test.js => index.test.ts} | 34 +- server/routes/{index.js => index.ts} | 34 +- ...0226232041-migrate-authentication.test.ts} | 20 +- ... 20210226232041-migrate-authentication.ts} | 18 +- ...20210716000000-backfill-revisions.test.ts} | 17 +- ...s => 20210716000000-backfill-revisions.ts} | 10 +- server/scripts/bootstrap.js | 6 - server/scripts/bootstrap.ts | 11 + server/{sequelize.js => sequelize.ts} | 5 +- server/services/{admin.js => admin.ts} | 5 +- .../{collaboration.js => collaboration.ts} | 15 +- server/services/{index.js => index.ts} | 9 +- server/services/{web.js => web.ts} | 39 +- .../services/{websockets.js => websockets.ts} | 50 +- server/services/{worker.js => worker.ts} | 15 +- server/test/{factories.js => factories.ts} | 73 +- server/test/{setup.js => setup.ts} | 2 - server/test/{support.js => support.ts} | 9 +- server/{tracing.js => tracing.ts} | 5 +- server/types.js | 241 - server/types.ts | 253 + server/typings/cancan.d.ts | 35 + server/typings/fetch-with-proxy.d.ts | 3 + server/typings/koa-onerror.d.ts | 1 + server/utils/__mocks__/{s3.js => s3.ts} | 2 - server/utils/{args.js => args.ts} | 2 - .../{authentication.js => authentication.ts} | 29 +- .../{avatars.test.js => avatars.test.ts} | 5 - server/utils/{avatars.js => avatars.ts} | 10 +- ...ctionIndexing.js => collectionIndexing.ts} | 19 +- server/utils/{color.js => color.ts} | 3 +- ...Buffer.test.js => dataURItoBuffer.test.ts} | 4 +- ...{dataURItoBuffer.js => dataURItoBuffer.ts} | 4 - server/utils/{domains.js => domains.ts} | 4 +- server/utils/{fs.test.js => fs.test.ts} | 2 - server/utils/{fs.js => fs.ts} | 7 +- server/utils/jwt.js | 99 - server/utils/jwt.ts | 114 + server/utils/{opensearch.js => opensearch.ts} | 1 - ...Ids.test.js => parseAttachmentIds.test.ts} | 22 +- ...AttachmentIds.js => parseAttachmentIds.ts} | 1 - ...ntIds.test.js => parseDocumentIds.test.ts} | 8 - ...arseDocumentIds.js => parseDocumentIds.ts} | 9 +- ...arseImages.test.js => parseImages.test.ts} | 5 - .../utils/{parseImages.js => parseImages.ts} | 5 +- server/utils/{passport.js => passport.ts} | 25 +- .../{prefetchTags.js => prefetchTags.tsx} | 6 +- server/utils/{queue.js => queue.ts} | 14 +- ...exCollision.js => removeIndexCollision.ts} | 13 +- server/utils/{robots.js => robots.ts} | 7 +- server/utils/{s3.js => s3.ts} | 49 +- server/utils/{slack.js => slack.ts} | 22 +- server/utils/{slugify.js => slugify.ts} | 1 - server/utils/{startup.js => startup.ts} | 17 +- server/utils/{updates.js => updates.ts} | 9 +- server/utils/{zip.js => zip.ts} | 48 +- server/validation.ts | 91 + shared/{constants.js => constants.ts} | 4 +- .../{Abstract.test.js => Abstract.test.ts} | 4 +- shared/embeds/{Abstract.js => Abstract.tsx} | 15 +- .../{Airtable.test.js => Airtable.test.ts} | 2 +- shared/embeds/{Airtable.js => Airtable.tsx} | 16 +- .../{Bilibili.test.js => Bilibili.test.ts} | 2 +- shared/embeds/{Bilibili.js => Bilibili.tsx} | 16 +- .../embeds/{Cawemo.test.js => Cawemo.test.ts} | 2 +- shared/embeds/{Cawemo.js => Cawemo.tsx} | 16 +- .../{ClickUp.test.js => ClickUp.test.ts} | 2 +- shared/embeds/{ClickUp.js => ClickUp.tsx} | 15 +- .../{Codepen.test.js => Codepen.test.ts} | 2 +- shared/embeds/{Codepen.js => Codepen.tsx} | 16 +- shared/embeds/{Descript.js => Descript.tsx} | 15 +- .../{Diagrams.test.js => Diagrams.test.ts} | 1 - shared/embeds/{Diagrams.js => Diagrams.tsx} | 15 +- .../embeds/{Figma.test.js => Figma.test.ts} | 2 +- shared/embeds/{Figma.js => Figma.tsx} | 15 +- .../embeds/{Framer.test.js => Framer.test.ts} | 2 +- shared/embeds/{Framer.js => Framer.tsx} | 15 +- shared/embeds/{Gist.test.js => Gist.test.ts} | 4 +- shared/embeds/{Gist.js => Gist.tsx} | 24 +- ...alendar.test.js => GoogleCalendar.test.ts} | 2 +- .../{GoogleCalendar.js => GoogleCalendar.tsx} | 15 +- ...tudio.test.js => GoogleDataStudio.test.ts} | 2 +- ...ogleDataStudio.js => GoogleDataStudio.tsx} | 15 +- ...{GoogleDocs.test.js => GoogleDocs.test.ts} | 2 +- .../embeds/{GoogleDocs.js => GoogleDocs.tsx} | 15 +- ...rawings.test.js => GoogleDrawings.test.ts} | 2 +- .../{GoogleDrawings.js => GoogleDrawings.tsx} | 15 +- ...oogleDrive.test.js => GoogleDrive.test.ts} | 1 - .../{GoogleDrive.js => GoogleDrive.tsx} | 15 +- ...gleSheets.test.js => GoogleSheets.test.ts} | 2 +- .../{GoogleSheets.js => GoogleSheets.tsx} | 15 +- ...gleSlides.test.js => GoogleSlides.test.ts} | 2 +- .../{GoogleSlides.js => GoogleSlides.tsx} | 15 +- .../{InVision.test.js => InVision.test.ts} | 2 +- shared/embeds/{InVision.js => InVision.tsx} | 20 +- shared/embeds/{Loom.test.js => Loom.test.ts} | 2 +- shared/embeds/{Loom.js => Loom.tsx} | 16 +- ...{Lucidchart.test.js => Lucidchart.test.ts} | 6 +- .../embeds/{Lucidchart.js => Lucidchart.tsx} | 16 +- .../embeds/{Marvel.test.js => Marvel.test.ts} | 2 +- shared/embeds/{Marvel.js => Marvel.tsx} | 15 +- ...indmeister.test.js => Mindmeister.test.ts} | 1 - .../{Mindmeister.js => Mindmeister.tsx} | 16 +- shared/embeds/{Miro.test.js => Miro.test.ts} | 3 +- shared/embeds/{Miro.js => Miro.tsx} | 16 +- ...nalytics.test.js => ModeAnalytics.test.ts} | 2 +- .../{ModeAnalytics.js => ModeAnalytics.tsx} | 16 +- shared/embeds/{Pitch.js => Pitch.tsx} | 16 +- .../embeds/{Prezi.test.js => Prezi.test.ts} | 2 +- shared/embeds/{Prezi.js => Prezi.tsx} | 16 +- .../{Spotify.test.js => Spotify.test.ts} | 2 +- shared/embeds/{Spotify.js => Spotify.tsx} | 17 +- shared/embeds/{Trello.js => Trello.tsx} | 16 +- .../{Typeform.test.js => Typeform.test.ts} | 2 +- shared/embeds/{Typeform.js => Typeform.tsx} | 15 +- .../embeds/{Vimeo.test.js => Vimeo.test.ts} | 2 +- shared/embeds/{Vimeo.js => Vimeo.tsx} | 16 +- .../{YouTube.test.js => YouTube.test.ts} | 2 +- shared/embeds/{YouTube.js => YouTube.tsx} | 18 +- .../embeds/components/{Frame.js => Frame.tsx} | 37 +- .../embeds/components/{Image.js => Image.tsx} | 15 +- shared/embeds/{index.js => index.tsx} | 37 +- shared/i18n/{index.test.js => index.test.ts} | 4 - shared/i18n/{index.js => index.ts} | 77 +- shared/{random.js => random.ts} | 1 - shared/{theme.js => theme.ts} | 62 +- shared/types.js | 2 - shared/types.ts | 20 + shared/utils/{color.js => color.ts} | 2 - shared/utils/{date.js => date.ts} | 11 +- .../{domains.test.js => domains.test.ts} | 11 +- shared/utils/{domains.js => domains.ts} | 14 +- shared/utils/{getTasks.js => getTasks.ts} | 10 +- ...{indexCharacters.js => indexCharacters.ts} | 2 - shared/utils/naturalSort.test.js | 61 - shared/utils/naturalSort.test.ts | 140 + .../utils/{naturalSort.js => naturalSort.ts} | 20 +- ...Slug.test.js => parseDocumentSlug.test.ts} | 1 - ...seDocumentSlug.js => parseDocumentSlug.ts} | 3 +- ...{parseTitle.test.js => parseTitle.test.ts} | 5 - shared/utils/{parseTitle.js => parseTitle.ts} | 8 +- .../{routeHelpers.js => routeHelpers.ts} | 9 +- shared/utils/slugify.js | 8 - shared/utils/slugify.ts | 10 + shared/utils/{unescape.js => unescape.ts} | 2 - shared/utils/{urls.js => urls.ts} | 1 - shared/utils/{zip.js => zip.ts} | 30 +- tsconfig.json | 35 + webpack.config.js | 7 +- yarn.lock | 3282 +++-- 1017 files changed, 17410 insertions(+), 54942 deletions(-) delete mode 100644 .flowconfig create mode 100644 app/.eslintrc rename app/actions/definitions/{collections.js => collections.tsx} (83%) rename app/actions/definitions/{debug.js => debug.tsx} (79%) rename app/actions/definitions/{documents.js => documents.tsx} (88%) rename app/actions/definitions/{navigation.js => navigation.tsx} (92%) rename app/actions/definitions/{settings.js => settings.tsx} (79%) rename app/actions/definitions/{users.js => users.tsx} (77%) rename app/actions/{index.js => index.ts} (76%) rename app/actions/{root.js => root.ts} (98%) rename app/actions/{sections.js => sections.ts} (89%) rename app/components/{Actions.js => Actions.ts} (95%) rename app/components/{Analytics.js => Analytics.ts} (78%) rename app/components/{Arrow.js => Arrow.tsx} (98%) rename app/components/AuthLogo/{GoogleLogo.js => GoogleLogo.tsx} (93%) rename app/components/AuthLogo/{MicrosoftLogo.js => MicrosoftLogo.tsx} (94%) rename app/components/AuthLogo/{SlackLogo.js => SlackLogo.tsx} (98%) rename app/components/AuthLogo/{index.js => index.tsx} (91%) rename app/components/{Authenticated.js => Authenticated.tsx} (84%) rename app/components/Avatar/{Avatar.js => Avatar.tsx} (82%) rename app/components/Avatar/{AvatarWithPresence.js => AvatarWithPresence.tsx} (75%) rename app/components/Avatar/{index.js => index.ts} (94%) rename app/components/{Badge.js => Badge.ts} (89%) rename app/components/{Branding.js => Branding.tsx} (93%) rename app/components/{Breadcrumb.js => Breadcrumb.tsx} (73%) rename app/components/{Bubble.js => Bubble.tsx} (88%) rename app/components/{Button.js => Button.tsx} (64%) rename app/components/{ButtonLarge.js => ButtonLarge.ts} (95%) rename app/components/{ButtonLink.js => ButtonLink.tsx} (81%) rename app/components/{CenteredContent.js => CenteredContent.tsx} (73%) rename app/components/{Checkbox.js => Checkbox.tsx} (68%) rename app/components/{CircularProgressBar.js => CircularProgressBar.tsx} (87%) rename app/components/{ClickablePadding.js => ClickablePadding.ts} (78%) rename app/components/{Collaborators.js => Collaborators.tsx} (82%) rename app/components/{CollectionDescription.js => CollectionDescription.tsx} (82%) rename app/components/{CollectionIcon.js => CollectionIcon.tsx} (83%) rename app/components/{CommandBar.js => CommandBar.tsx} (82%) rename app/components/{CommandBarItem.js => CommandBarItem.tsx} (63%) rename app/components/{CommandBarResults.js => CommandBarResults.tsx} (71%) rename app/components/{ConnectionStatus.js => ConnectionStatus.tsx} (87%) rename app/components/{ContentEditable.js => ContentEditable.tsx} (66%) rename app/components/ContextMenu/{Header.js => Header.ts} (96%) rename app/components/ContextMenu/{MenuItem.js => MenuItem.tsx} (87%) rename app/components/ContextMenu/{OverflowMenuButton.js => OverflowMenuButton.tsx} (70%) rename app/components/ContextMenu/{Separator.js => Separator.tsx} (84%) delete mode 100644 app/components/ContextMenu/Template.js create mode 100644 app/components/ContextMenu/Template.tsx rename app/components/ContextMenu/{index.js => index.tsx} (64%) rename app/components/{CopyToClipboard.js => CopyToClipboard.ts} (73%) rename app/components/{DelayedMount.js => DelayedMount.ts} (88%) rename app/components/{Dialogs.js => Dialogs.tsx} (84%) rename app/components/{Divider.js => Divider.ts} (95%) rename app/components/{DocumentBreadcrumb.js => DocumentBreadcrumb.tsx} (62%) rename app/components/{DocumentHistory.js => DocumentHistory.tsx} (72%) rename app/components/{DocumentList.js => DocumentList.tsx} (63%) rename app/components/{DocumentListItem.js => DocumentListItem.tsx} (81%) rename app/components/{DocumentMeta.js => DocumentMeta.tsx} (83%) rename app/components/{DocumentMetaWithViews.js => DocumentMetaWithViews.tsx} (80%) rename app/components/{DocumentTasks.js => DocumentTasks.tsx} (66%) rename app/components/{DocumentViews.js => DocumentViews.tsx} (78%) rename app/components/{Editor.js => Editor.tsx} (69%) rename app/components/{Empty.js => Empty.ts} (93%) rename app/components/{ErrorBoundary.js => ErrorBoundary.tsx} (76%) rename app/components/{EventBoundary.js => EventBoundary.tsx} (69%) rename app/components/{EventListItem.js => EventListItem.tsx} (86%) rename app/components/{Facepile.js => Facepile.tsx} (78%) rename app/components/{Fade.js => Fade.ts} (57%) rename app/components/{FilterOptions.js => FilterOptions.tsx} (66%) rename app/components/{Flex.js => Flex.tsx} (56%) rename app/components/{FullscreenLoading.js => FullscreenLoading.tsx} (76%) rename app/components/{GithubLogo.js => GithubLogo.tsx} (94%) rename app/components/{GroupListItem.js => GroupListItem.tsx} (66%) rename app/components/{Guide.js => Guide.tsx} (88%) rename app/components/{Header.js => Header.tsx} (90%) rename app/components/{Heading.js => Heading.ts} (85%) rename app/components/{HelpText.js => HelpText.ts} (80%) rename app/components/{Highlight.js => Highlight.tsx} (75%) rename app/components/{HoverPreview.js => HoverPreview.tsx} (84%) rename app/components/{HoverPreviewDocument.js => HoverPreviewDocument.tsx} (67%) rename app/components/{IconPicker.js => IconPicker.tsx} (90%) rename app/components/{Input.js => Input.tsx} (67%) rename app/components/{InputLarge.js => InputLarge.ts} (96%) rename app/components/{InputRich.js => InputRich.tsx} (72%) rename app/components/{InputSearch.js => InputSearch.tsx} (77%) rename app/components/{InputSearchPage.js => InputSearchPage.tsx} (74%) rename app/components/{InputSelect.js => InputSelect.tsx} (78%) rename app/components/{InputSelectPermission.js => InputSelectPermission.tsx} (57%) delete mode 100644 app/components/InputSelectRole.js create mode 100644 app/components/InputSelectRole.tsx rename app/components/{Key.js => Key.ts} (98%) rename app/components/{Labeled.js => Labeled.tsx} (78%) rename app/components/{LanguagePrompt.js => LanguagePrompt.tsx} (85%) rename app/components/{Layout.js => Layout.tsx} (66%) rename app/components/List/{Item.js => Item.tsx} (65%) rename app/components/List/{List.js => List.ts} (93%) rename app/components/List/{Placeholder.js => Placeholder.tsx} (76%) rename app/components/List/{index.js => index.ts} (84%) delete mode 100644 app/components/LoadingIndicator/LoadingIndicator.js create mode 100644 app/components/LoadingIndicator/LoadingIndicator.ts rename app/components/LoadingIndicator/{LoadingIndicatorBar.js => LoadingIndicatorBar.tsx} (98%) rename app/components/LoadingIndicator/{index.js => index.ts} (95%) rename app/components/{LocaleTime.js => LocaleTime.tsx} (76%) rename app/components/{MenuIconWrapper.js => MenuIconWrapper.ts} (95%) rename app/components/{Modal.js => Modal.tsx} (83%) delete mode 100644 app/components/NavLink.js create mode 100644 app/components/NavLink.tsx rename app/components/{Notice.js => Notice.ts} (96%) rename app/components/{NoticeAlert.js => NoticeAlert.tsx} (78%) rename app/components/{NoticeTip.js => NoticeTip.ts} (97%) delete mode 100644 app/components/NudeButton.js create mode 100644 app/components/NudeButton.tsx rename app/components/{OutlineLogo.js => OutlineLogo.tsx} (96%) rename app/components/{PageTheme.js => PageTheme.ts} (94%) rename app/components/{PageTitle.js => PageTitle.tsx} (82%) rename app/components/{PaginatedDocumentList.js => PaginatedDocumentList.tsx} (50%) rename app/components/{PaginatedEventList.js => PaginatedEventList.tsx} (69%) rename app/components/{PaginatedList.test.js => PaginatedList.test.tsx} (74%) rename app/components/{PaginatedList.js => PaginatedList.tsx} (78%) rename app/components/{PathToDocument.js => PathToDocument.tsx} (70%) rename app/components/{PlaceholderDocument.js => PlaceholderDocument.tsx} (79%) rename app/components/{PlaceholderText.js => PlaceholderText.tsx} (68%) rename app/components/{Popover.js => Popover.tsx} (79%) rename app/components/{ProfiledRoute.js => ProfiledRoute.ts} (58%) rename app/components/{RegisterKeyDown.js => RegisterKeyDown.ts} (71%) rename app/components/{Scene.js => Scene.tsx} (67%) rename app/components/{ScrollToTop.js => ScrollToTop.ts} (88%) rename app/components/{Scrollable.js => Scrollable.tsx} (83%) rename app/components/Sidebar/{Main.js => Main.tsx} (86%) rename app/components/Sidebar/{Settings.js => Settings.tsx} (93%) rename app/components/Sidebar/{Sidebar.js => Sidebar.tsx} (81%) rename app/components/Sidebar/components/{ArchiveLink.js => ArchiveLink.tsx} (65%) rename app/components/Sidebar/components/{CollectionLink.js => CollectionLink.tsx} (79%) rename app/components/Sidebar/components/{Collections.js => Collections.tsx} (83%) rename app/components/Sidebar/components/{Disclosure.js => Disclosure.ts} (97%) rename app/components/Sidebar/components/{DocumentLink.js => DocumentLink.tsx} (78%) rename app/components/Sidebar/components/{DropCursor.js => DropCursor.tsx} (72%) rename app/components/Sidebar/components/{DropToImport.js => DropToImport.tsx} (66%) rename app/components/Sidebar/components/{EditableTitle.js => EditableTitle.tsx} (93%) rename app/components/Sidebar/components/{Header.js => Header.ts} (86%) rename app/components/Sidebar/components/{NavLink.js => NavLink.tsx} (68%) rename app/components/Sidebar/components/{PlaceholderCollections.js => PlaceholderCollections.tsx} (85%) rename app/components/Sidebar/components/{ResizeBorder.js => ResizeBorder.ts} (95%) rename app/components/Sidebar/components/{Section.js => Section.ts} (86%) rename app/components/Sidebar/components/{SidebarAction.js => SidebarAction.tsx} (76%) rename app/components/Sidebar/components/{SidebarLink.js => SidebarLink.tsx} (75%) rename app/components/Sidebar/components/{Starred.js => Starred.tsx} (87%) rename app/components/Sidebar/components/{StarredLink.js => StarredLink.tsx} (76%) rename app/components/Sidebar/components/{TeamButton.js => TeamButton.tsx} (80%) rename app/components/Sidebar/components/{Toggle.js => Toggle.tsx} (83%) rename app/components/Sidebar/components/{TrashLink.js => TrashLink.tsx} (72%) rename app/components/Sidebar/components/{Version.js => Version.tsx} (96%) rename app/components/Sidebar/{index.js => index.ts} (85%) rename app/components/{SkipNavContent.js => SkipNavContent.tsx} (93%) rename app/components/{SkipNavLink.js => SkipNavLink.tsx} (92%) rename app/components/{SlackIcon.js => SlackIcon.tsx} (98%) rename app/components/{SocketProvider.js => SocketProvider.tsx} (81%) rename app/components/{Star.js => Star.tsx} (89%) rename app/components/{Subheading.js => Subheading.tsx} (90%) rename app/components/{Switch.js => Switch.tsx} (79%) rename app/components/{Tab.js => Tab.tsx} (85%) rename app/components/{Table.js => Table.tsx} (67%) rename app/components/{Tabs.js => Tabs.tsx} (91%) rename app/components/{TeamLogo.js => TeamLogo.ts} (83%) rename app/components/{Theme.js => Theme.tsx} (51%) rename app/components/{Time.js => Time.tsx} (69%) rename app/components/{Toast.js => Toast.tsx} (73%) rename app/components/{Toasts.js => Toasts.tsx} (77%) delete mode 100644 app/components/Tooltip.js create mode 100644 app/components/Tooltip.tsx rename app/components/{ZapierIcon.js => ZapierIcon.tsx} (98%) create mode 100644 app/components/withStores.tsx delete mode 100644 app/env.js create mode 100644 app/env.ts rename app/hooks/{useBoolean.js => useBoolean.ts} (79%) rename app/hooks/{useCommandBarActions.js => useCommandBarActions.ts} (85%) rename app/hooks/{useCurrentTeam.js => useCurrentTeam.ts} (95%) rename app/hooks/{useCurrentToken.js => useCurrentToken.ts} (96%) rename app/hooks/{useCurrentUser.js => useCurrentUser.ts} (95%) rename app/hooks/{useDebouncedCallback.js => useDebouncedCallback.ts} (75%) rename app/hooks/{useIdle.js => useIdle.ts} (94%) rename app/hooks/{useImportDocument.js => useImportDocument.ts} (86%) rename app/hooks/{useIsMounted.js => useIsMounted.ts} (97%) rename app/hooks/{useKeyDown.js => useKeyDown.ts} (78%) rename app/hooks/{useMediaQuery.js => useMediaQuery.ts} (95%) rename app/hooks/{useMenuHeight.js => useMenuHeight.ts} (68%) rename app/hooks/{useMobile.js => useMobile.ts} (76%) rename app/hooks/{usePageVisibility.js => usePageVisibility.ts} (98%) rename app/hooks/{usePrevious.js => usePrevious.ts} (81%) rename app/hooks/{useQuery.js => useQuery.ts} (93%) rename app/hooks/{useSessions.js => useSessions.ts} (83%) delete mode 100644 app/hooks/useStores.js create mode 100644 app/hooks/useStores.ts rename app/hooks/{useToasts.js => useToasts.ts} (57%) rename app/hooks/{useUnmount.js => useUnmount.ts} (76%) rename app/hooks/{useUserLocale.js => useUserLocale.ts} (95%) rename app/hooks/{useWindowScrollPosition.js => useWindowScrollPosition.ts} (62%) rename app/hooks/{useWindowSize.js => useWindowSize.ts} (77%) rename app/{index.js => index.tsx} (79%) rename app/menus/{AccountMenu.js => AccountMenu.tsx} (63%) rename app/menus/{BreadcrumbMenu.js => BreadcrumbMenu.tsx} (65%) rename app/menus/{CollectionGroupMemberMenu.js => CollectionGroupMemberMenu.tsx} (69%) rename app/menus/{CollectionMenu.js => CollectionMenu.tsx} (79%) rename app/menus/{CollectionSortMenu.js => CollectionSortMenu.tsx} (79%) rename app/menus/{DocumentMenu.js => DocumentMenu.tsx} (77%) rename app/menus/{FileOperationMenu.js => FileOperationMenu.tsx} (67%) rename app/menus/{GroupMemberMenu.js => GroupMemberMenu.tsx} (67%) rename app/menus/{GroupMenu.js => GroupMenu.tsx} (74%) rename app/menus/{MemberMenu.js => MemberMenu.tsx} (65%) rename app/menus/{NewChildDocumentMenu.js => NewChildDocumentMenu.tsx} (67%) rename app/menus/{NewDocumentMenu.js => NewDocumentMenu.tsx} (66%) rename app/menus/{NewTemplateMenu.js => NewTemplateMenu.tsx} (65%) rename app/menus/{RevisionMenu.js => RevisionMenu.tsx} (64%) rename app/menus/{ShareMenu.js => ShareMenu.tsx} (67%) rename app/menus/{TableOfContentsMenu.js => TableOfContentsMenu.tsx} (79%) rename app/menus/{TemplatesMenu.js => TemplatesMenu.tsx} (73%) rename app/menus/{UserMenu.js => UserMenu.tsx} (80%) delete mode 100644 app/menus/separator.js create mode 100644 app/menus/separator.ts rename app/models/{ApiKey.js => ApiKey.ts} (94%) rename app/models/{BaseModel.js => BaseModel.ts} (75%) delete mode 100644 app/models/Collection.js rename app/models/{Collection.test.js => Collection.test.ts} (73%) create mode 100644 app/models/Collection.ts rename app/models/{CollectionGroupMembership.js => CollectionGroupMembership.ts} (97%) rename app/models/{Document.js => Document.ts} (70%) rename app/models/{Event.js => Event.ts} (52%) rename app/models/{FileOperation.js => FileOperation.ts} (90%) rename app/models/{Group.js => Group.ts} (96%) rename app/models/{GroupMembership.js => GroupMembership.ts} (94%) rename app/models/{Integration.js => Integration.ts} (59%) rename app/models/{Membership.js => Membership.ts} (97%) rename app/models/{NotificationSetting.js => NotificationSetting.ts} (94%) rename app/models/{Policy.js => Policy.ts} (66%) rename app/models/{Revision.js => Revision.ts} (96%) rename app/models/{Share.js => Share.ts} (86%) rename app/models/{Team.js => Team.ts} (81%) rename app/models/{User.js => User.ts} (92%) rename app/models/{View.js => View.ts} (97%) rename app/multiplayer/{MultiplayerExtension.js => MultiplayerExtension.ts} (96%) rename app/routes/{authenticated.js => authenticated.tsx} (64%) delete mode 100644 app/routes/index.js create mode 100644 app/routes/index.tsx rename app/routes/{settings.js => settings.tsx} (63%) rename app/scenes/{APITokenNew.js => APITokenNew.tsx} (70%) rename app/scenes/{Archive.js => Archive.tsx} (72%) rename app/scenes/{Collection.js => Collection.tsx} (80%) rename app/scenes/{CollectionDelete.js => CollectionDelete.tsx} (66%) rename app/scenes/{CollectionEdit.js => CollectionEdit.tsx} (73%) rename app/scenes/{CollectionExport.js => CollectionExport.tsx} (69%) rename app/scenes/{CollectionNew.js => CollectionNew.tsx} (69%) rename app/scenes/CollectionPermissions/{AddGroupsToCollection.js => AddGroupsToCollection.tsx} (65%) rename app/scenes/CollectionPermissions/{AddPeopleToCollection.js => AddPeopleToCollection.tsx} (64%) rename app/scenes/CollectionPermissions/components/{CollectionGroupMemberListItem.js => CollectionGroupMemberListItem.tsx} (62%) rename app/scenes/CollectionPermissions/components/{MemberListItem.js => MemberListItem.tsx} (67%) rename app/scenes/CollectionPermissions/components/{UserListItem.js => UserListItem.tsx} (76%) rename app/scenes/CollectionPermissions/{index.js => index.tsx} (80%) rename app/scenes/Document/{Shared.js => Shared.tsx} (59%) rename app/scenes/Document/components/{Container.js => Container.ts} (73%) rename app/scenes/Document/components/{Contents.js => Contents.tsx} (85%) rename app/scenes/Document/components/{DataLoader.js => DataLoader.tsx} (77%) rename app/scenes/Document/components/{Document.js => Document.tsx} (80%) rename app/scenes/Document/components/{EditableTitle.js => EditableTitle.tsx} (74%) rename app/scenes/Document/components/{Editor.js => Editor.tsx} (70%) rename app/scenes/Document/components/{Header.js => Header.tsx} (79%) rename app/scenes/Document/components/{HideSidebar.js => HideSidebar.ts} (78%) rename app/scenes/Document/components/{KeyboardShortcutsButton.js => KeyboardShortcutsButton.tsx} (82%) rename app/scenes/Document/components/{Loading.js => Loading.tsx} (61%) rename app/scenes/Document/components/{MarkAsViewed.js => MarkAsViewed.ts} (77%) rename app/scenes/Document/components/{MultiplayerEditor.js => MultiplayerEditor.tsx} (74%) rename app/scenes/Document/components/{PublicBreadcrumb.js => PublicBreadcrumb.tsx} (58%) rename app/scenes/Document/components/{PublicReferences.js => PublicReferences.tsx} (81%) rename app/scenes/Document/components/{ReferenceListItem.js => ReferenceListItem.tsx} (79%) delete mode 100644 app/scenes/Document/components/References.js create mode 100644 app/scenes/Document/components/References.tsx rename app/scenes/Document/components/{ShareButton.js => ShareButton.tsx} (86%) rename app/scenes/Document/components/{SharePopover.js => SharePopover.tsx} (77%) rename app/scenes/Document/components/{SocketPresence.js => SocketPresence.ts} (78%) rename app/scenes/Document/{index.js => index.tsx} (70%) rename app/scenes/{DocumentDelete.js => DocumentDelete.tsx} (73%) rename app/scenes/{DocumentMove.js => DocumentMove.tsx} (79%) rename app/scenes/{DocumentNew.js => DocumentNew.tsx} (70%) rename app/scenes/{DocumentPermanentDelete.js => DocumentPermanentDelete.tsx} (62%) rename app/scenes/{DocumentReparent.js => DocumentReparent.tsx} (65%) rename app/scenes/{DocumentTemplatize.js => DocumentTemplatize.tsx} (63%) rename app/scenes/{Drafts.js => Drafts.tsx} (58%) rename app/scenes/{Error404.js => Error404.tsx} (77%) rename app/scenes/{ErrorOffline.js => ErrorOffline.tsx} (71%) rename app/scenes/{ErrorSuspended.js => ErrorSuspended.tsx} (57%) rename app/scenes/{GroupDelete.js => GroupDelete.tsx} (62%) rename app/scenes/{GroupEdit.js => GroupEdit.tsx} (64%) rename app/scenes/GroupMembers/{AddPeopleToGroup.js => AddPeopleToGroup.tsx} (63%) rename app/scenes/GroupMembers/{GroupMembers.js => GroupMembers.tsx} (64%) rename app/scenes/GroupMembers/components/{GroupMemberListItem.js => GroupMemberListItem.tsx} (66%) rename app/scenes/GroupMembers/components/{UserListItem.js => UserListItem.tsx} (73%) rename app/scenes/GroupMembers/{index.js => index.ts} (88%) rename app/scenes/{GroupNew.js => GroupNew.tsx} (67%) rename app/scenes/{Home.js => Home.tsx} (71%) rename app/scenes/{Invite.js => Invite.tsx} (77%) rename app/scenes/{KeyboardShortcuts.js => KeyboardShortcuts.tsx} (93%) rename app/scenes/Login/{Notices.js => Notices.tsx} (95%) rename app/scenes/Login/{Provider.js => Provider.tsx} (72%) rename app/scenes/Login/{index.js => index.tsx} (85%) rename app/scenes/{Logout.js => Logout.tsx} (79%) rename app/scenes/Search/{Search.js => Search.tsx} (77%) rename app/scenes/Search/components/{CollectionFilter.js => CollectionFilter.tsx} (81%) delete mode 100644 app/scenes/Search/components/DateFilter.js create mode 100644 app/scenes/Search/components/DateFilter.tsx rename app/scenes/Search/components/{SearchInput.js => SearchInput.tsx} (87%) rename app/scenes/Search/components/{StatusFilter.js => StatusFilter.tsx} (79%) rename app/scenes/Search/components/{UserFilter.js => UserFilter.tsx} (77%) rename app/scenes/Search/{index.js => index.ts} (85%) rename app/scenes/Settings/{Details.js => Details.tsx} (80%) rename app/scenes/Settings/{Features.js => Features.tsx} (78%) rename app/scenes/Settings/{Groups.js => Groups.tsx} (73%) rename app/scenes/Settings/{ImportExport.js => ImportExport.tsx} (73%) rename app/scenes/Settings/{Notifications.js => Notifications.tsx} (85%) rename app/scenes/Settings/{People.js => People.tsx} (85%) rename app/scenes/Settings/{Profile.js => Profile.tsx} (82%) rename app/scenes/Settings/{Security.js => Security.tsx} (80%) rename app/scenes/Settings/{Shares.js => Shares.tsx} (77%) rename app/scenes/Settings/{Slack.js => Slack.tsx} (74%) rename app/scenes/Settings/{Tokens.js => Tokens.tsx} (77%) rename app/scenes/Settings/{Zapier.js => Zapier.tsx} (78%) rename app/scenes/Settings/components/{FileOperationListItem.js => FileOperationListItem.tsx} (78%) rename app/scenes/Settings/components/{ImageUpload.js => ImageUpload.tsx} (72%) rename app/scenes/Settings/components/{NotificationListItem.js => NotificationListItem.tsx} (57%) rename app/scenes/Settings/components/{PeopleTable.js => PeopleTable.tsx} (55%) rename app/scenes/Settings/components/{ShareListItem.js => ShareListItem.tsx} (69%) rename app/scenes/Settings/components/{SlackButton.js => SlackButton.tsx} (60%) rename app/scenes/Settings/components/{TokenListItem.js => TokenListItem.tsx} (65%) delete mode 100644 app/scenes/Settings/components/UserListItem.js create mode 100644 app/scenes/Settings/components/UserListItem.tsx rename app/scenes/Settings/components/{UserStatusFilter.js => UserStatusFilter.tsx} (85%) rename app/scenes/{Templates.js => Templates.tsx} (71%) rename app/scenes/{Trash.js => Trash.tsx} (71%) rename app/scenes/{UserDelete.js => UserDelete.tsx} (72%) rename app/scenes/{UserProfile.js => UserProfile.tsx} (77%) rename app/stores/{ApiKeysStore.js => ApiKeysStore.ts} (52%) rename app/stores/{AuthStore.js => AuthStore.ts} (73%) rename app/stores/{BaseStore.js => BaseStore.ts} (57%) rename app/stores/{CollectionGroupMembershipsStore.js => CollectionGroupMembershipsStore.ts} (71%) rename app/stores/{CollectionsStore.js => CollectionsStore.ts} (72%) rename app/stores/{DialogsStore.js => DialogsStore.ts} (63%) rename app/stores/{DocumentPresenceStore.js => DocumentPresenceStore.ts} (81%) rename app/stores/{DocumentsStore.js => DocumentsStore.ts} (74%) rename app/stores/{EventsStore.js => EventsStore.ts} (80%) rename app/stores/{FileOperationsStore.js => FileOperationsStore.ts} (77%) rename app/stores/{GroupMembershipsStore.js => GroupMembershipsStore.ts} (76%) rename app/stores/{GroupsStore.js => GroupsStore.ts} (78%) rename app/stores/{IntegrationsStore.js => IntegrationsStore.ts} (61%) rename app/stores/{MembershipsStore.js => MembershipsStore.ts} (74%) delete mode 100644 app/stores/NotificationSettingsStore.js create mode 100644 app/stores/NotificationSettingsStore.ts rename app/stores/{PoliciesStore.js => PoliciesStore.ts} (88%) delete mode 100644 app/stores/RevisionsStore.js create mode 100644 app/stores/RevisionsStore.ts rename app/stores/{RootStore.js => RootStore.ts} (99%) rename app/stores/{SharesStore.js => SharesStore.ts} (70%) delete mode 100644 app/stores/ToastsStore.test.js create mode 100644 app/stores/ToastsStore.test.ts rename app/stores/{ToastsStore.js => ToastsStore.ts} (90%) rename app/stores/{UiStore.js => UiStore.ts} (71%) rename app/stores/{UsersStore.js => UsersStore.ts} (77%) rename app/stores/{ViewsStore.js => ViewsStore.ts} (85%) rename app/stores/{index.js => index.ts} (52%) rename app/styles/{animations.js => animations.ts} (99%) rename app/styles/{globals.js => globals.ts} (99%) delete mode 100644 app/test/setup.js create mode 100644 app/test/setup.ts rename app/test/{support.js => support.ts} (88%) create mode 100644 app/types.ts delete mode 100644 app/types/index.js create mode 100644 app/typings/index.d.ts create mode 100644 app/typings/styled-components.d.ts rename app/utils/{ApiClient.js => ApiClient.ts} (68%) rename app/utils/__mocks__/{ApiClient.js => ApiClient.ts} (50%) rename app/utils/{compressImage.js => compressImage.ts} (54%) rename app/utils/{dates.js => dates.ts} (81%) rename app/utils/{developer.js => developer.ts} (96%) rename app/utils/{domains.js => domains.ts} (77%) rename app/utils/{download.js => download.ts} (54%) rename app/utils/{emoji.js => emoji.ts} (95%) rename app/utils/{errors.js => errors.ts} (98%) delete mode 100644 app/utils/getDataTransferFiles.js create mode 100644 app/utils/getDataTransferFiles.ts rename app/utils/{history.js => history.ts} (92%) rename app/utils/{i18n.js => i18n.ts} (85%) rename app/utils/{isTextInput.js => isTextInput.ts} (73%) rename app/utils/{keyboard.js => keyboard.ts} (76%) rename app/utils/{language.js => language.ts} (81%) rename app/utils/{motion.js => motion.ts} (87%) rename app/utils/{pageVisibility.js => pageVisibility.ts} (96%) rename app/utils/{routeHelpers.js => routeHelpers.ts} (87%) rename app/utils/{sentry.js => sentry.ts} (84%) rename app/utils/{uploadFile.js => uploadFile.ts} (64%) rename app/utils/{urls.test.js => urls.test.ts} (97%) rename app/utils/{urls.js => urls.ts} (93%) delete mode 100644 flow-typed/globals.js delete mode 100644 flow-typed/npm/@sentry/node_vx.x.x.js delete mode 100644 flow-typed/npm/@tippy.js/react_vx.x.x.js delete mode 100644 flow-typed/npm/@tommoor/remove-markdown_vx.x.x.js delete mode 100644 flow-typed/npm/autotrack_vx.x.x.js delete mode 100644 flow-typed/npm/aws-sdk_vx.x.x.js delete mode 100644 flow-typed/npm/boundless-arrow-key-navigation_vx.x.x.js delete mode 100644 flow-typed/npm/bull_vx.x.x.js delete mode 100644 flow-typed/npm/cancan_vx.x.x.js delete mode 100644 flow-typed/npm/classnames_v2.x.x.js delete mode 100644 flow-typed/npm/copy-to-clipboard_v3.x.x.js delete mode 100644 flow-typed/npm/core-js_vx.x.x.js delete mode 100644 flow-typed/npm/debug_v2.x.x.js delete mode 100644 flow-typed/npm/debug_vx.x.x.js delete mode 100644 flow-typed/npm/diff_vx.x.x.js delete mode 100644 flow-typed/npm/dotenv_v4.x.x.js delete mode 100644 flow-typed/npm/emoji-name-map_vx.x.x.js delete mode 100644 flow-typed/npm/emoji-regex_vx.x.x.js delete mode 100644 flow-typed/npm/enzyme-to-json_vx.x.x.js delete mode 100644 flow-typed/npm/enzyme_v2.3.x.js delete mode 100644 flow-typed/npm/es6-error_v4.x.x.js delete mode 100644 flow-typed/npm/exports-loader_vx.x.x.js delete mode 100644 flow-typed/npm/fbemitter_vx.x.x.js delete mode 100644 flow-typed/npm/fetch-test-server_vx.x.x.js delete mode 100644 flow-typed/npm/file-loader_vx.x.x.js delete mode 100644 flow-typed/npm/flow-bin_v0.x.x.js delete mode 100644 flow-typed/npm/flow-typed_vx.x.x.js delete mode 100644 flow-typed/npm/fs-extra_vx.x.x.js delete mode 100644 flow-typed/npm/highlight.js_vx.x.x.js delete mode 100644 flow-typed/npm/history_vx.x.x.js delete mode 100644 flow-typed/npm/html-webpack-plugin_vx.x.x.js delete mode 100644 flow-typed/npm/http-errors_v1.x.x.js delete mode 100644 flow-typed/npm/imports-loader_vx.x.x.js delete mode 100644 flow-typed/npm/invariant_v2.x.x.js delete mode 100644 flow-typed/npm/ioredis_vx.x.x.js delete mode 100644 flow-typed/npm/isomorphic-fetch_v2.x.x.js delete mode 100644 flow-typed/npm/jest-cli_vx.x.x.js delete mode 100644 flow-typed/npm/jest_v22.x.x.js delete mode 100644 flow-typed/npm/js-cookie_v2.x.x.js delete mode 100644 flow-typed/npm/js-search_vx.x.x.js delete mode 100644 flow-typed/npm/js-tree_vx.x.x.js delete mode 100644 flow-typed/npm/json-loader_vx.x.x.js delete mode 100644 flow-typed/npm/jsonwebtoken_v8.3.x.js delete mode 100644 flow-typed/npm/jszip_vx.x.x.js delete mode 100644 flow-typed/npm/koa-bodyparser_v4.x.x.js delete mode 100644 flow-typed/npm/koa-compress_vx.x.x.js delete mode 100644 flow-typed/npm/koa-connect_vx.x.x.js delete mode 100644 flow-typed/npm/koa-convert_vx.x.x.js delete mode 100644 flow-typed/npm/koa-helmet_vx.x.x.js delete mode 100644 flow-typed/npm/koa-jwt_vx.x.x.js delete mode 100644 flow-typed/npm/koa-logger_vx.x.x.js delete mode 100644 flow-typed/npm/koa-mount_vx.x.x.js delete mode 100644 flow-typed/npm/koa-onerror_vx.x.x.js delete mode 100644 flow-typed/npm/koa-router_vx.x.x.js delete mode 100644 flow-typed/npm/koa-sslify_vx.x.x.js delete mode 100644 flow-typed/npm/koa-static_v4.x.x.js delete mode 100644 flow-typed/npm/koa-webpack-dev-middleware_vx.x.x.js delete mode 100644 flow-typed/npm/koa-webpack-hot-middleware_vx.x.x.js delete mode 100644 flow-typed/npm/koa_v2.0.x.js delete mode 100644 flow-typed/npm/lib0_vx.x.x.js delete mode 100644 flow-typed/npm/lib0_vx.x.x.js~4256e7ec (flow) delete mode 100644 flow-typed/npm/lodash.orderby_vx.x.x.js delete mode 100644 flow-typed/npm/lodash_v4.x.x.js delete mode 100644 flow-typed/npm/marked-sanitized_vx.x.x.js delete mode 100644 flow-typed/npm/mobx-react-devtools_vx.x.x.js delete mode 100644 flow-typed/npm/mobx-react_vx.x.x.js delete mode 100644 flow-typed/npm/natural-sort_vx.x.x.js delete mode 100644 flow-typed/npm/node-dev_vx.x.x.js delete mode 100644 flow-typed/npm/node-sass_vx.x.x.js delete mode 100644 flow-typed/npm/nodemailer_vx.x.x.js delete mode 100644 flow-typed/npm/nodemon_vx.x.x.js delete mode 100644 flow-typed/npm/normalizr_v2.x.x.js delete mode 100644 flow-typed/npm/outline-icons_vx.x.x.js delete mode 100644 flow-typed/npm/oy-vey_vx.x.x.js delete mode 100644 flow-typed/npm/parse-domain_vx.x.x.js delete mode 100644 flow-typed/npm/pg-hstore_vx.x.x.js delete mode 100644 flow-typed/npm/pg_v6.x.x.js delete mode 100644 flow-typed/npm/polished_vx.x.x.js delete mode 100644 flow-typed/npm/prettier_v1.x.x.js delete mode 100644 flow-typed/npm/pui-react-tooltip_vx.x.x.js delete mode 100644 flow-typed/npm/query-string_vx.x.x.js delete mode 100644 flow-typed/npm/raf_vx.x.x.js delete mode 100644 flow-typed/npm/randomstring_v1.x.x.js delete mode 100644 flow-typed/npm/raw-loader_vx.x.x.js delete mode 100644 flow-typed/npm/react-addons-test-utils_v15.x.x.js delete mode 100644 flow-typed/npm/react-avatar-editor_vx.x.x.js delete mode 100644 flow-typed/npm/react-color_v2.x.x.js delete mode 100644 flow-typed/npm/react-helmet_v5.x.x.js delete mode 100644 flow-typed/npm/react-i18next_vx.x.x.js delete mode 100644 flow-typed/npm/react-medium-image-zoom_vx.x.x.js delete mode 100644 flow-typed/npm/react-portal_vx.x.x.js delete mode 100644 flow-typed/npm/react-router-dom_v5.x.x.js delete mode 100644 flow-typed/npm/react-test-renderer_v16.x.x.js delete mode 100644 flow-typed/npm/react-waypoint_vx.x.x.js delete mode 100644 flow-typed/npm/redis-lock_vx.x.x.js delete mode 100644 flow-typed/npm/redis_v2.x.x.js delete mode 100644 flow-typed/npm/rich-markdown-editor_vx.x.x.js delete mode 100644 flow-typed/npm/rimraf_v2.x.x.js delete mode 100644 flow-typed/npm/sass-loader_vx.x.x.js delete mode 100644 flow-typed/npm/semver_vx.x.x.js delete mode 100644 flow-typed/npm/sequelize-cli_vx.x.x.js delete mode 100644 flow-typed/npm/sequelize-encrypted_vx.x.x.js delete mode 100644 flow-typed/npm/sequelize_vx.x.x.js delete mode 100644 flow-typed/npm/slate-md-serializer_vx.x.x.js delete mode 100644 flow-typed/npm/slate_vx.x.x.js delete mode 100644 flow-typed/npm/slug_v0.9.x.js delete mode 100644 flow-typed/npm/slug_vx.x.x.js delete mode 100644 flow-typed/npm/socket.io-redis_vx.x.x.js delete mode 100644 flow-typed/npm/socket.io_vx.x.x.js delete mode 100644 flow-typed/npm/socketio-auth_vx.x.x.js delete mode 100644 flow-typed/npm/string-hash_vx.x.x.js delete mode 100644 flow-typed/npm/string-replace-to-array_vx.x.x.js delete mode 100644 flow-typed/npm/styled-components-breakpoint_vx.x.x.js delete mode 100644 flow-typed/npm/styled-components_vx.x.x.js delete mode 100644 flow-typed/npm/styled-normalize_vx.x.x.js delete mode 100644 flow-typed/npm/tiny-cookie_vx.x.x.js delete mode 100644 flow-typed/npm/tmp_vx.x.x.js delete mode 100644 flow-typed/npm/url-loader_vx.x.x.js delete mode 100644 flow-typed/npm/uuid_v2.x.x.js delete mode 100644 flow-typed/npm/validator_vx.x.x.js delete mode 100644 flow-typed/npm/y-indexeddb_vx.x.x.js delete mode 100644 flow-typed/npm/y-prosemirror_vx.x.x.js delete mode 100644 flow-typed/npm/y-protocols_vx.x.x.js delete mode 100644 flow-typed/npm/yjs_vx.x.x.js create mode 100644 server/.eslintrc delete mode 100644 server/__mocks__/events.js create mode 100644 server/__mocks__/events.ts rename server/__snapshots__/{mailer.test.js.snap => mailer.test.ts.snap} (100%) rename server/collaboration/{authentication.js => authentication.ts} (62%) delete mode 100644 server/collaboration/logger.js create mode 100644 server/collaboration/logger.ts rename server/collaboration/{persistence.js => persistence.ts} (77%) delete mode 100644 server/collaboration/tracing.js create mode 100644 server/collaboration/tracing.ts rename server/collaboration/utils/{markdownToYDoc.js => markdownToYDoc.ts} (69%) rename server/commands/{accountProvisioner.test.js => accountProvisioner.test.ts} (89%) rename server/commands/{accountProvisioner.js => accountProvisioner.ts} (66%) rename server/commands/{attachmentCreator.js => attachmentCreator.ts} (61%) rename server/commands/{collectionExporter.js => collectionExporter.ts} (54%) rename server/commands/{collectionImporter.test.js => collectionImporter.test.ts} (86%) rename server/commands/{collectionImporter.js => collectionImporter.ts} (68%) rename server/commands/{documentCreator.js => documentCreator.ts} (53%) rename server/commands/{documentImporter.test.js => documentImporter.test.ts} (95%) rename server/commands/{documentImporter.js => documentImporter.ts} (75%) delete mode 100644 server/commands/documentMover.js rename server/commands/{documentMover.test.js => documentMover.test.ts} (77%) create mode 100644 server/commands/documentMover.ts rename server/commands/{documentPermanentDeleter.test.js => documentPermanentDeleter.test.ts} (80%) rename server/commands/{documentPermanentDeleter.js => documentPermanentDeleter.ts} (59%) rename server/commands/{documentUpdater.js => documentUpdater.ts} (89%) delete mode 100644 server/commands/fileOperationDeleter.js rename server/commands/{fileOperationDeleter.test.js => fileOperationDeleter.test.ts} (68%) create mode 100644 server/commands/fileOperationDeleter.ts rename server/commands/{revisionCreator.test.js => revisionCreator.test.ts} (72%) rename server/commands/{revisionCreator.js => revisionCreator.ts} (50%) rename server/commands/{teamCreator.test.js => teamCreator.test.ts} (93%) rename server/commands/{teamCreator.js => teamCreator.ts} (72%) rename server/commands/{teamPermanentDeleter.test.js => teamPermanentDeleter.test.ts} (70%) rename server/commands/{teamPermanentDeleter.js => teamPermanentDeleter.ts} (58%) rename server/commands/{userCreator.test.js => userCreator.test.ts} (95%) rename server/commands/{userCreator.js => userCreator.ts} (74%) rename server/commands/{userDestroyer.test.js => userDestroyer.test.ts} (83%) rename server/commands/{userDestroyer.js => userDestroyer.ts} (54%) delete mode 100644 server/commands/userInviter.test.js create mode 100644 server/commands/userInviter.test.ts rename server/commands/{userInviter.js => userInviter.ts} (71%) rename server/commands/{userSuspender.test.js => userSuspender.test.ts} (68%) rename server/commands/{userSuspender.js => userSuspender.ts} (52%) rename server/emails/{CollectionNotificationEmail.js => CollectionNotificationEmail.tsx} (73%) rename server/emails/{DocumentNotificationEmail.js => DocumentNotificationEmail.tsx} (69%) rename server/emails/{ExportFailureEmail.js => ExportFailureEmail.tsx} (99%) rename server/emails/{ExportSuccessEmail.js => ExportSuccessEmail.tsx} (96%) rename server/emails/{InviteEmail.js => InviteEmail.tsx} (91%) rename server/emails/{SigninEmail.js => SigninEmail.tsx} (96%) rename server/emails/{WelcomeEmail.js => WelcomeEmail.tsx} (98%) rename server/emails/components/{Body.js => Body.tsx} (92%) rename server/emails/components/{Button.js => Button.tsx} (85%) rename server/emails/components/{EmailLayout.js => EmailLayout.tsx} (84%) rename server/emails/components/{EmptySpace.js => EmptySpace.tsx} (85%) rename server/emails/components/{Footer.js => Footer.tsx} (89%) rename server/emails/components/{Header.js => Header.tsx} (98%) rename server/emails/components/{Heading.js => Heading.tsx} (86%) rename server/emails/{index.js => index.ts} (68%) delete mode 100644 server/env.js create mode 100644 server/env.ts delete mode 100644 server/errors.js create mode 100644 server/errors.ts rename server/{index.js => index.ts} (91%) rename server/logging/{logger.js => logger.ts} (89%) rename server/logging/{metrics.js => metrics.ts} (78%) rename server/logging/{sentry.js => sentry.ts} (84%) rename server/{mailer.test.js => mailer.test.ts} (54%) rename server/{mailer.js => mailer.tsx} (81%) rename server/middlewares/{apexRedirect.js => apexRedirect.ts} (79%) rename server/middlewares/{authentication.test.js => authentication.test.ts} (58%) rename server/middlewares/{authentication.js => authentication.ts} (69%) rename server/middlewares/{errorHandling.js => errorHandling.ts} (84%) rename server/middlewares/{methodOverride.js => methodOverride.ts} (81%) rename server/middlewares/{passport.js => passport.ts} (71%) delete mode 100644 server/middlewares/validation.js rename server/models/{ApiKey.js => ApiKey.ts} (68%) rename server/models/{Attachment.js => Attachment.ts} (73%) rename server/models/{AuthenticationProvider.js => AuthenticationProvider.ts} (67%) rename server/models/{Backlink.js => Backlink.ts} (85%) rename server/models/{Collection.test.js => Collection.test.ts} (89%) rename server/models/{Collection.js => Collection.ts} (68%) rename server/models/{CollectionGroup.js => CollectionGroup.ts} (89%) rename server/models/{CollectionUser.js => CollectionUser.ts} (88%) rename server/models/{Document.test.js => Document.test.ts} (89%) rename server/models/{Document.js => Document.ts} (74%) rename server/models/{Event.js => Event.ts} (87%) rename server/models/{FileOperation.js => FileOperation.ts} (86%) rename server/models/{Group.test.js => Group.test.ts} (56%) rename server/models/{Group.js => Group.ts} (74%) rename server/models/{GroupUser.js => GroupUser.ts} (78%) rename server/models/{Integration.js => Integration.ts} (89%) rename server/models/{IntegrationAuthentication.js => IntegrationAuthentication.ts} (87%) rename server/models/{Notification.js => Notification.ts} (87%) rename server/models/{NotificationSetting.js => NotificationSetting.ts} (88%) rename server/models/{Revision.test.js => Revision.test.ts} (77%) rename server/models/{Revision.js => Revision.ts} (70%) rename server/models/{SearchQuery.js => SearchQuery.ts} (81%) rename server/models/{Share.js => Share.ts} (71%) rename server/models/{Star.js => Star.ts} (77%) rename server/models/{Team.test.js => Team.test.ts} (73%) rename server/models/{Team.js => Team.ts} (73%) rename server/models/{User.test.js => User.test.ts} (81%) rename server/models/{User.js => User.ts} (70%) rename server/models/{UserAuthentication.js => UserAuthentication.ts} (87%) rename server/models/{View.js => View.ts} (67%) rename server/models/{index.js => index.ts} (99%) rename server/policies/{apiKey.js => apiKey.ts} (86%) rename server/policies/{attachment.js => attachment.ts} (92%) rename server/policies/{authenticationProvider.js => authenticationProvider.ts} (81%) rename server/policies/{collection.test.js => collection.test.ts} (85%) rename server/policies/{collection.js => collection.ts} (94%) rename server/policies/{document.test.js => document.test.ts} (90%) rename server/policies/{document.js => document.ts} (94%) rename server/policies/{group.js => group.ts} (85%) rename server/policies/{index.test.js => index.test.ts} (74%) rename server/policies/{index.js => index.ts} (69%) rename server/policies/{integration.js => integration.ts} (82%) rename server/policies/{notificationSetting.js => notificationSetting.ts} (82%) rename server/policies/{policy.js => policy.ts} (86%) rename server/policies/{share.js => share.ts} (89%) rename server/policies/{team.test.js => team.test.ts} (80%) rename server/policies/{team.js => team.ts} (90%) rename server/policies/{user.js => user.ts} (84%) rename server/presenters/__snapshots__/{user.test.js.snap => user.test.ts.snap} (100%) delete mode 100644 server/presenters/apiKey.js create mode 100644 server/presenters/apiKey.ts rename server/presenters/{authenticationProvider.js => authenticationProvider.ts} (59%) rename server/presenters/{collection.js => collection.ts} (72%) rename server/presenters/{collectionGroupMembership.js => collectionGroupMembership.ts} (50%) delete mode 100644 server/presenters/document.js create mode 100644 server/presenters/document.ts rename server/presenters/{env.js => env.ts} (88%) delete mode 100644 server/presenters/event.js create mode 100644 server/presenters/event.ts rename server/presenters/{fileOperation.js => fileOperation.ts} (64%) rename server/presenters/{group.js => group.ts} (53%) delete mode 100644 server/presenters/groupMembership.js create mode 100644 server/presenters/groupMembership.ts rename server/presenters/{index.js => index.ts} (99%) rename server/presenters/{integration.js => integration.ts} (70%) rename server/presenters/{membership.js => membership.ts} (50%) delete mode 100644 server/presenters/notificationSetting.js create mode 100644 server/presenters/notificationSetting.ts delete mode 100644 server/presenters/policy.js create mode 100644 server/presenters/policy.ts rename server/presenters/{revision.js => revision.ts} (63%) rename server/presenters/{share.js => share.ts} (65%) delete mode 100644 server/presenters/slackAttachment.js create mode 100644 server/presenters/slackAttachment.ts rename server/presenters/{team.js => team.ts} (68%) delete mode 100644 server/presenters/user.js rename server/presenters/{user.test.js => user.test.ts} (86%) create mode 100644 server/presenters/user.ts rename server/presenters/{view.js => view.ts} (60%) rename server/queues/{index.js => index.ts} (81%) rename server/queues/processors/{backlinks.test.js => backlinks.test.ts} (73%) rename server/queues/processors/{backlinks.js => backlinks.ts} (84%) rename server/queues/processors/{debouncer.js => debouncer.ts} (75%) delete mode 100644 server/queues/processors/emails.js create mode 100644 server/queues/processors/emails.ts rename server/queues/processors/{exports.js => exports.ts} (74%) rename server/queues/processors/{imports.js => imports.ts} (75%) rename server/queues/processors/{notifications.test.js => notifications.test.ts} (77%) rename server/queues/processors/{notifications.js => notifications.ts} (94%) rename server/queues/processors/{revisions.test.js => revisions.test.ts} (59%) rename server/queues/processors/{revisions.js => revisions.ts} (77%) rename server/queues/processors/{slack.js => slack.ts} (89%) rename server/queues/processors/{websockets.js => websockets.ts} (97%) rename server/{redis.js => redis.ts} (96%) rename server/routes/api/__snapshots__/{collections.test.js.snap => collections.test.ts.snap} (100%) rename server/routes/api/__snapshots__/{documents.test.js.snap => documents.test.ts.snap} (100%) rename server/routes/api/__snapshots__/{events.test.js.snap => events.test.ts.snap} (100%) rename server/routes/api/__snapshots__/{groups.test.js.snap => groups.test.ts.snap} (100%) rename server/routes/api/__snapshots__/{shares.test.js.snap => shares.test.ts.snap} (100%) rename server/routes/api/__snapshots__/{users.test.js.snap => users.test.ts.snap} (100%) rename server/routes/api/__snapshots__/{views.test.js.snap => views.test.ts.snap} (100%) rename server/routes/api/{apiKeys.js => apiKeys.ts} (77%) rename server/routes/api/{attachments.test.js => attachments.test.ts} (82%) rename server/routes/api/{attachments.js => attachments.ts} (80%) rename server/routes/api/{auth.test.js => auth.test.ts} (85%) rename server/routes/api/{auth.js => auth.ts} (71%) rename server/routes/api/{authenticationProviders.test.js => authenticationProviders.test.ts} (86%) rename server/routes/api/{authenticationProviders.js => authenticationProviders.ts} (70%) rename server/routes/api/{collections.test.js => collections.test.ts} (85%) rename server/routes/api/{collections.js => collections.ts} (80%) rename server/routes/api/{documents.test.js => documents.test.ts} (87%) rename server/routes/api/{documents.js => documents.ts} (66%) rename server/routes/api/{events.test.js => events.test.ts} (88%) rename server/routes/api/{events.js => events.ts} (55%) rename server/routes/api/{fileOperations.test.js => fileOperations.test.ts} (83%) rename server/routes/api/{fileOperations.js => fileOperations.ts} (69%) rename server/routes/api/{groups.test.js => groups.test.ts} (71%) rename server/routes/api/{groups.js => groups.ts} (76%) rename server/routes/api/{hooks.test.js => hooks.test.ts} (89%) rename server/routes/api/{hooks.js => hooks.ts} (85%) rename server/routes/api/{index.test.js => index.test.ts} (68%) rename server/routes/api/{index.js => index.ts} (84%) rename server/routes/api/{integrations.js => integrations.ts} (68%) rename server/routes/api/middlewares/{apiWrapper.js => apiWrapper.ts} (64%) rename server/routes/api/middlewares/{editor.js => editor.ts} (66%) rename server/routes/api/middlewares/{pagination.test.js => pagination.test.ts} (64%) rename server/routes/api/middlewares/{pagination.js => pagination.ts} (52%) rename server/routes/api/{notificationSettings.js => notificationSettings.ts} (78%) rename server/routes/api/{revisions.test.js => revisions.test.ts} (84%) rename server/routes/api/{revisions.js => revisions.ts} (57%) rename server/routes/api/{shares.test.js => shares.test.ts} (84%) rename server/routes/api/{shares.js => shares.ts} (82%) rename server/routes/api/{team.test.js => team.test.ts} (69%) rename server/routes/api/{team.js => team.ts} (87%) rename server/routes/api/{users.test.js => users.test.ts} (79%) rename server/routes/api/{users.js => users.ts} (62%) rename server/routes/api/{utils.test.js => utils.test.ts} (77%) rename server/routes/api/{utils.js => utils.ts} (77%) rename server/routes/api/{views.test.js => views.test.ts} (71%) rename server/routes/api/{views.js => views.ts} (55%) rename server/routes/auth/{index.test.js => index.test.ts} (63%) rename server/routes/auth/{index.js => index.ts} (64%) rename server/routes/auth/providers/{azure.js => azure.ts} (68%) rename server/routes/auth/providers/{email.test.js => email.test.ts} (70%) rename server/routes/auth/providers/{email.js => email.ts} (72%) rename server/routes/auth/providers/{google.js => google.ts} (74%) rename server/routes/auth/providers/{index.js => index.ts} (52%) rename server/routes/auth/providers/{oidc.js => oidc.ts} (75%) delete mode 100644 server/routes/auth/providers/slack.js create mode 100644 server/routes/auth/providers/slack.ts rename server/routes/{index.test.js => index.test.ts} (76%) rename server/routes/{index.js => index.ts} (83%) rename server/scripts/{20210226232041-migrate-authentication.test.js => 20210226232041-migrate-authentication.test.ts} (97%) rename server/scripts/{20210226232041-migrate-authentication.js => 20210226232041-migrate-authentication.ts} (87%) rename server/scripts/{20210716000000-backfill-revisions.test.js => 20210716000000-backfill-revisions.test.ts} (89%) rename server/scripts/{20210716000000-backfill-revisions.js => 20210716000000-backfill-revisions.ts} (81%) delete mode 100644 server/scripts/bootstrap.js create mode 100644 server/scripts/bootstrap.ts rename server/{sequelize.js => sequelize.ts} (72%) rename server/services/{admin.js => admin.ts} (86%) rename server/services/{collaboration.js => collaboration.ts} (60%) rename server/services/{index.js => index.ts} (68%) rename server/services/{web.js => web.ts} (82%) rename server/services/{websockets.js => websockets.ts} (86%) rename server/services/{worker.js => worker.ts} (91%) rename server/test/{factories.js => factories.ts} (77%) rename server/test/{setup.js => setup.ts} (97%) rename server/test/{support.js => support.ts} (96%) rename server/{tracing.js => tracing.ts} (83%) delete mode 100644 server/types.js create mode 100644 server/types.ts create mode 100644 server/typings/cancan.d.ts create mode 100644 server/typings/fetch-with-proxy.d.ts create mode 100644 server/typings/koa-onerror.d.ts rename server/utils/__mocks__/{s3.js => s3.ts} (71%) rename server/utils/{args.js => args.ts} (97%) rename server/utils/{authentication.js => authentication.ts} (81%) rename server/utils/{avatars.test.js => avatars.test.ts} (99%) rename server/utils/{avatars.js => avatars.ts} (93%) rename server/utils/{collectionIndexing.js => collectionIndexing.ts} (60%) rename server/utils/{color.js => color.ts} (90%) rename server/utils/{dataURItoBuffer.test.js => dataURItoBuffer.test.ts} (99%) rename server/utils/{dataURItoBuffer.js => dataURItoBuffer.ts} (97%) rename server/utils/{domains.js => domains.ts} (63%) rename server/utils/{fs.test.js => fs.test.ts} (98%) rename server/utils/{fs.js => fs.ts} (84%) delete mode 100644 server/utils/jwt.js create mode 100644 server/utils/jwt.ts rename server/utils/{opensearch.js => opensearch.ts} (98%) rename server/utils/{parseAttachmentIds.test.js => parseAttachmentIds.test.ts} (92%) rename server/utils/{parseAttachmentIds.js => parseAttachmentIds.ts} (97%) rename server/utils/{parseDocumentIds.test.js => parseDocumentIds.test.ts} (98%) rename server/utils/{parseDocumentIds.js => parseDocumentIds.ts} (63%) rename server/utils/{parseImages.test.js => parseImages.test.ts} (97%) rename server/utils/{parseImages.js => parseImages.ts} (52%) rename server/utils/{passport.js => passport.ts} (57%) rename server/utils/{prefetchTags.js => prefetchTags.tsx} (89%) rename server/utils/{queue.js => queue.ts} (92%) rename server/utils/{removeIndexCollision.js => removeIndexCollision.ts} (89%) rename server/utils/{robots.js => robots.ts} (56%) rename server/utils/{s3.js => s3.ts} (75%) rename server/utils/{slack.js => slack.ts} (68%) rename server/utils/{slugify.js => slugify.ts} (94%) rename server/utils/{startup.js => startup.ts} (94%) rename server/utils/{updates.js => updates.ts} (95%) rename server/utils/{zip.js => zip.ts} (61%) create mode 100644 server/validation.ts rename shared/{constants.js => constants.ts} (92%) rename shared/embeds/{Abstract.test.js => Abstract.test.ts} (96%) rename shared/embeds/{Abstract.js => Abstract.tsx} (70%) rename shared/embeds/{Airtable.test.js => Airtable.test.ts} (91%) rename shared/embeds/{Airtable.js => Airtable.tsx} (68%) rename shared/embeds/{Bilibili.test.js => Bilibili.test.ts} (92%) rename shared/embeds/{Bilibili.js => Bilibili.tsx} (70%) rename shared/embeds/{Cawemo.test.js => Cawemo.test.ts} (90%) rename shared/embeds/{Cawemo.js => Cawemo.tsx} (69%) rename shared/embeds/{ClickUp.test.js => ClickUp.test.ts} (89%) rename shared/embeds/{ClickUp.js => ClickUp.tsx} (63%) rename shared/embeds/{Codepen.test.js => Codepen.test.ts} (90%) rename shared/embeds/{Codepen.js => Codepen.tsx} (65%) rename shared/embeds/{Descript.js => Descript.tsx} (68%) rename shared/embeds/{Diagrams.test.js => Diagrams.test.ts} (88%) rename shared/embeds/{Diagrams.js => Diagrams.tsx} (79%) rename shared/embeds/{Figma.test.js => Figma.test.ts} (90%) rename shared/embeds/{Figma.js => Figma.tsx} (68%) rename shared/embeds/{Framer.test.js => Framer.test.ts} (84%) rename shared/embeds/{Framer.js => Framer.tsx} (63%) rename shared/embeds/{Gist.test.js => Gist.test.ts} (91%) rename shared/embeds/{Gist.js => Gist.tsx} (81%) rename shared/embeds/{GoogleCalendar.test.js => GoogleCalendar.test.ts} (90%) rename shared/embeds/{GoogleCalendar.js => GoogleCalendar.tsx} (65%) rename shared/embeds/{GoogleDataStudio.test.js => GoogleDataStudio.test.ts} (91%) rename shared/embeds/{GoogleDataStudio.js => GoogleDataStudio.tsx} (77%) rename shared/embeds/{GoogleDocs.test.js => GoogleDocs.test.ts} (94%) rename shared/embeds/{GoogleDocs.js => GoogleDocs.tsx} (75%) rename shared/embeds/{GoogleDrawings.test.js => GoogleDrawings.test.ts} (94%) rename shared/embeds/{GoogleDrawings.js => GoogleDrawings.tsx} (76%) rename shared/embeds/{GoogleDrive.test.js => GoogleDrive.test.ts} (93%) rename shared/embeds/{GoogleDrive.js => GoogleDrive.tsx} (74%) rename shared/embeds/{GoogleSheets.test.js => GoogleSheets.test.ts} (92%) rename shared/embeds/{GoogleSheets.js => GoogleSheets.tsx} (75%) rename shared/embeds/{GoogleSlides.test.js => GoogleSlides.test.ts} (94%) rename shared/embeds/{GoogleSlides.js => GoogleSlides.tsx} (76%) rename shared/embeds/{InVision.test.js => InVision.test.ts} (91%) rename shared/embeds/{InVision.js => InVision.tsx} (74%) rename shared/embeds/{Loom.test.js => Loom.test.ts} (93%) rename shared/embeds/{Loom.js => Loom.tsx} (64%) rename shared/embeds/{Lucidchart.test.js => Lucidchart.test.ts} (96%) rename shared/embeds/{Lucidchart.js => Lucidchart.tsx} (76%) rename shared/embeds/{Marvel.test.js => Marvel.test.ts} (87%) rename shared/embeds/{Marvel.js => Marvel.tsx} (63%) rename shared/embeds/{Mindmeister.test.js => Mindmeister.test.ts} (95%) rename shared/embeds/{Mindmeister.js => Mindmeister.tsx} (73%) rename shared/embeds/{Miro.test.js => Miro.test.ts} (91%) rename shared/embeds/{Miro.js => Miro.tsx} (72%) rename shared/embeds/{ModeAnalytics.test.js => ModeAnalytics.test.ts} (90%) rename shared/embeds/{ModeAnalytics.js => ModeAnalytics.tsx} (71%) rename shared/embeds/{Pitch.js => Pitch.tsx} (71%) rename shared/embeds/{Prezi.test.js => Prezi.test.ts} (90%) rename shared/embeds/{Prezi.js => Prezi.tsx} (64%) rename shared/embeds/{Spotify.test.js => Spotify.test.ts} (92%) rename shared/embeds/{Spotify.js => Spotify.tsx} (79%) rename shared/embeds/{Trello.js => Trello.tsx} (67%) rename shared/embeds/{Typeform.test.js => Typeform.test.ts} (89%) rename shared/embeds/{Typeform.js => Typeform.tsx} (65%) rename shared/embeds/{Vimeo.test.js => Vimeo.test.ts} (90%) rename shared/embeds/{Vimeo.js => Vimeo.tsx} (70%) rename shared/embeds/{YouTube.test.js => YouTube.test.ts} (93%) rename shared/embeds/{YouTube.js => YouTube.tsx} (69%) rename shared/embeds/components/{Frame.js => Frame.tsx} (82%) rename shared/embeds/components/{Image.js => Image.tsx} (63%) rename shared/embeds/{index.js => index.tsx} (72%) rename shared/i18n/{index.test.js => index.test.ts} (97%) rename shared/i18n/{index.js => index.ts} (57%) rename shared/{random.js => random.ts} (94%) rename shared/{theme.js => theme.ts} (92%) delete mode 100644 shared/types.js create mode 100644 shared/types.ts rename shared/utils/{color.js => color.ts} (91%) rename shared/utils/{date.js => date.ts} (74%) rename shared/utils/{domains.test.js => domains.test.ts} (93%) rename shared/utils/{domains.js => domains.ts} (95%) rename shared/utils/{getTasks.js => getTasks.ts} (78%) rename shared/utils/{indexCharacters.js => indexCharacters.ts} (91%) delete mode 100644 shared/utils/naturalSort.test.js create mode 100644 shared/utils/naturalSort.test.ts rename shared/utils/{naturalSort.js => naturalSort.ts} (56%) rename shared/utils/{parseDocumentSlug.test.js => parseDocumentSlug.test.ts} (98%) rename shared/utils/{parseDocumentSlug.js => parseDocumentSlug.ts} (96%) rename shared/utils/{parseTitle.test.js => parseTitle.test.ts} (93%) rename shared/utils/{parseTitle.js => parseTitle.ts} (86%) rename shared/utils/{routeHelpers.js => routeHelpers.ts} (82%) delete mode 100644 shared/utils/slugify.js create mode 100644 shared/utils/slugify.ts rename shared/utils/{unescape.js => unescape.ts} (94%) rename shared/utils/{urls.js => urls.ts} (94%) rename shared/utils/{zip.js => zip.ts} (74%) create mode 100644 tsconfig.json diff --git a/.babelrc b/.babelrc index 38bb56bdf5..5a7af638eb 100644 --- a/.babelrc +++ b/.babelrc @@ -1,7 +1,7 @@ { "presets": [ "@babel/preset-react", - "@babel/preset-flow", + "@babel/preset-typescript", [ "@babel/preset-env", { diff --git a/.circleci/config.yml b/.circleci/config.yml index bf7e675460..e847cf3b11 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -41,8 +41,8 @@ jobs: name: lint command: yarn lint - run: - name: flow - command: yarn flow check --max-workers 4 + name: typescript + command: yarn tsc - run: name: test command: yarn test diff --git a/.dockerignore b/.dockerignore index 9a2b306ca5..f2dc90801d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,14 +6,13 @@ __mocks__ .DS_Store .env* .eslint* -.flowconfig .log Makefile Procfile app.json +crowdin.yml build docker-compose.yml fakes3 -flow-typed node_modules -setupJest.js \ No newline at end of file +tsconfig.json diff --git a/.eslintrc b/.eslintrc index 8eeaa95b1d..7e2d5b3542 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,20 +1,34 @@ { - "parser": "babel-eslint", + "parser": "@typescript-eslint/parser", + "parserOptions": { + "sourceType": "module", + "extraFileExtensions": [".json"], + "ecmaFeatures": { + "jsx": true + } + }, "extends": [ - "react-app", - "plugin:import/errors", - "plugin:import/warnings", - "plugin:flowtype/recommended", - "plugin:react-hooks/recommended" + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/recommended", + "plugin:import/typescript", + "plugin:react-hooks/recommended", + "plugin:prettier/recommended" ], "plugins": [ - "prettier", - "flowtype" + "@typescript-eslint", + "eslint-plugin-import", + "eslint-plugin-node", + "eslint-plugin-react", + "eslint-plugin-react-hooks", + "import" ], "rules": { "eqeqeq": 2, - "no-unused-vars": 2, "no-mixed-operators": "off", + "padding-line-between-statements": ["error", { "blankLine": "always", "prev": "*", "next": "export" }], + "lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }], + "import/newline-after-import": 2, "import/order": [ "error", { @@ -23,53 +37,48 @@ }, "pathGroups": [ { - "pattern": "shared/**", + "pattern": "@shared/**", "group": "external", "position": "after" }, { - "pattern": "stores", + "pattern": "@server/**", "group": "external", "position": "after" }, { - "pattern": "stores/**", + "pattern": "~/stores", "group": "external", "position": "after" }, { - "pattern": "models/**", + "pattern": "~/stores/**", "group": "external", "position": "after" }, { - "pattern": "scenes/**", + "pattern": "~/models/**", "group": "external", "position": "after" }, { - "pattern": "components/**", + "pattern": "~/scenes/**", + "group": "external", + "position": "after" + }, + { + "pattern": "~/components/**", + "group": "external", + "position": "after" + }, + { + "pattern": "~/**", "group": "external", "position": "after" } ] } ], - "flowtype/require-valid-file-annotation": [ - 2, - "always", - { - "annotationStyle": "line" - } - ], - "flowtype/space-after-type-colon": [ - 2, - "always" - ], - "flowtype/space-before-type-colon": [ - 2, - "never" - ], "prettier/prettier": [ "error", { @@ -84,21 +93,13 @@ "pragma": "React", "version": "detect" }, - "import/resolver": { - "node": { - "paths": [ - "app", - "." - ] - } + "import/parsers": { + "@typescript-eslint/parser": [".ts", ".tsx"] }, - "flowtype": { - "onlyFilesWithFlowAnnotation": false + "import/resolver": { + "typescript": {} } }, - "env": { - "jest": true - }, "globals": { "EDITOR_VERSION": true } diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 7e630b5656..0000000000 --- a/.flowconfig +++ /dev/null @@ -1,44 +0,0 @@ -[include] -.*/app/.* -.*/server/.* -.*/shared/.* - -[ignore] -.*/node_modules/tiny-cookie/flow/.* -.*/node_modules/styled-components/.* -.*/node_modules/polished/.* -.*/node_modules/mobx/.*.flow -.*/node_modules/react-side-effect/.* -.*/node_modules/fbjs/.* -.*/node_modules/config-chain/.* -.*/node_modules/yjs/.* -.*/node_modules/y-prosemirror/.* -.*/node_modules/y-protocols/.* -.*/node_modules/y-indexeddb/.* -.*/node_modules/lib0/.* -.*/server/scripts/.* -*.test.js - -[libs] - -[options] -emoji=true -sharedmemory.heap_size=3221225472 - -module.system.node.resolve_dirname=node_modules -module.system.node.resolve_dirname=app - -module.name_mapper='^\(.*\)\.md$' -> 'empty/object' -module.name_mapper='^shared\/\(.*\)$' -> '/shared/\1' - -module.file_ext=.js -module.file_ext=.md -module.file_ext=.json - -esproposal.decorators=ignore -esproposal.class_static_fields=enable -esproposal.class_instance_fields=enable -esproposal.optional_chaining=enable - -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue diff --git a/.vscode/settings.json b/.vscode/settings.json index 041e71a9e7..77b6256c8c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { - "javascript.validate.enable": false, - "javascript.format.enable": false, - "typescript.validate.enable": false, - "typescript.format.enable": false, + "javascript.validate.enable": true, + "javascript.format.enable": true, + "typescript.validate.enable": true, + "typescript.format.enable": true, "editor.formatOnSave": true, } \ No newline at end of file diff --git a/README.md b/README.md index 018a15e9b9..8c869ed40d 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,10 @@

- - - + TypeScript + Prettier + Styled Components +

This is the source code that runs [**Outline**](https://www.getoutline.com) and all the associated services. If you want to use Outline then you don't need to run this code, we offer a hosted version of the app at [getoutline.com](https://www.getoutline.com). diff --git a/__mocks__/bull.js b/__mocks__/bull.js index 3837625cc2..02c0a40b43 100644 --- a/__mocks__/bull.js +++ b/__mocks__/bull.js @@ -1,4 +1,3 @@ -/* eslint-disable flowtype/require-valid-file-annotation */ export default class Queue { name; diff --git a/app/.eslintrc b/app/.eslintrc new file mode 100644 index 0000000000..f273da1c95 --- /dev/null +++ b/app/.eslintrc @@ -0,0 +1,9 @@ +{ + "extends": [ + "../.eslintrc" + ], + "env": { + "jest": true, + "browser": true + } +} \ No newline at end of file diff --git a/app/.jestconfig.json b/app/.jestconfig.json index f07d05a0dc..515b464d35 100644 --- a/app/.jestconfig.json +++ b/app/.jestconfig.json @@ -7,14 +7,10 @@ "/shared" ], "moduleNameMapper": { - "^shared/(.*)$": "/shared/$1", + "^~/(.*)$": "/app/$1", + "^@shared/(.*)$": "/shared/$1", "^.*[.](gif|ttf|eot|svg)$": "/__test__/fileMock.js" }, - "moduleFileExtensions": [ - "js", - "jsx", - "json" - ], "moduleDirectories": [ "node_modules" ], @@ -25,6 +21,6 @@ "/__mocks__/window.js" ], "setupFilesAfterEnv": [ - "./app/test/setup.js" + "./app/test/setup.ts" ] } \ No newline at end of file diff --git a/app/actions/definitions/collections.js b/app/actions/definitions/collections.tsx similarity index 83% rename from app/actions/definitions/collections.js rename to app/actions/definitions/collections.tsx index 47331e75fc..ad17a3ba60 100644 --- a/app/actions/definitions/collections.js +++ b/app/actions/definitions/collections.tsx @@ -1,13 +1,12 @@ -// @flow import { CollectionIcon, EditIcon, PlusIcon } from "outline-icons"; import * as React from "react"; -import stores from "stores"; -import CollectionEdit from "scenes/CollectionEdit"; -import CollectionNew from "scenes/CollectionNew"; -import DynamicCollectionIcon from "components/CollectionIcon"; -import { createAction } from "actions"; -import { CollectionSection } from "actions/sections"; -import history from "utils/history"; +import stores from "~/stores"; +import CollectionEdit from "~/scenes/CollectionEdit"; +import CollectionNew from "~/scenes/CollectionNew"; +import DynamicCollectionIcon from "~/components/CollectionIcon"; +import { createAction } from "~/actions"; +import { CollectionSection } from "~/actions/sections"; +import history from "~/utils/history"; export const openCollection = createAction({ name: ({ t }) => t("Open collection"), @@ -16,7 +15,6 @@ export const openCollection = createAction({ icon: , children: ({ stores }) => { const collections = stores.collections.orderedData; - return collections.map((collection) => ({ // Note: using url which includes the slug rather than id here to bust // cache if the collection is renamed @@ -39,7 +37,6 @@ export const createCollection = createAction({ perform: ({ t, event }) => { event?.preventDefault(); event?.stopPropagation(); - stores.dialogs.openModal({ title: t("Create a collection"), content: , @@ -55,6 +52,8 @@ export const editCollection = createAction({ !!activeCollectionId && stores.policies.abilities(activeCollectionId).update, perform: ({ t, activeCollectionId }) => { + if (!activeCollectionId) return; + stores.dialogs.openModal({ title: t("Edit collection"), content: ( diff --git a/app/actions/definitions/debug.js b/app/actions/definitions/debug.tsx similarity index 79% rename from app/actions/definitions/debug.js rename to app/actions/definitions/debug.tsx index 142f2735c4..5f11c56872 100644 --- a/app/actions/definitions/debug.js +++ b/app/actions/definitions/debug.tsx @@ -1,11 +1,10 @@ -// @flow import { ToolsIcon, TrashIcon } from "outline-icons"; import * as React from "react"; -import stores from "stores"; -import { createAction } from "actions"; -import { DebugSection } from "actions/sections"; -import env from "env"; -import { deleteAllDatabases } from "utils/developer"; +import stores from "~/stores"; +import { createAction } from "~/actions"; +import { DebugSection } from "~/actions/sections"; +import env from "~/env"; +import { deleteAllDatabases } from "~/utils/developer"; export const clearIndexedDB = createAction({ name: ({ t }) => t("Delete IndexedDB cache"), diff --git a/app/actions/definitions/documents.js b/app/actions/definitions/documents.tsx similarity index 88% rename from app/actions/definitions/documents.js rename to app/actions/definitions/documents.tsx index f3922d8e85..32c83ab5d5 100644 --- a/app/actions/definitions/documents.js +++ b/app/actions/definitions/documents.tsx @@ -1,4 +1,3 @@ -// @flow import invariant from "invariant"; import { DownloadIcon, @@ -12,12 +11,12 @@ import { ImportIcon, } from "outline-icons"; import * as React from "react"; -import DocumentTemplatize from "scenes/DocumentTemplatize"; -import { createAction } from "actions"; -import { DocumentSection } from "actions/sections"; -import getDataTransferFiles from "utils/getDataTransferFiles"; -import history from "utils/history"; -import { newDocumentPath } from "utils/routeHelpers"; +import DocumentTemplatize from "~/scenes/DocumentTemplatize"; +import { createAction } from "~/actions"; +import { DocumentSection } from "~/actions/sections"; +import getDataTransferFiles from "~/utils/getDataTransferFiles"; +import history from "~/utils/history"; +import { newDocumentPath } from "~/utils/routeHelpers"; export const openDocument = createAction({ name: ({ t }) => t("Open document"), @@ -36,9 +35,7 @@ export const openDocument = createAction({ id: path.url, name: path.title, icon: () => - stores.documents.get(path.id)?.isStarred ? ( - - ) : undefined, + stores.documents.get(path.id)?.isStarred ? : null, section: DocumentSection, perform: () => history.push(path.url), })); @@ -65,13 +62,12 @@ export const starDocument = createAction({ visible: ({ activeDocumentId, stores }) => { if (!activeDocumentId) return false; const document = stores.documents.get(activeDocumentId); - return ( !document?.isStarred && stores.policies.abilities(activeDocumentId).star ); }, perform: ({ activeDocumentId, stores }) => { - if (!activeDocumentId) return false; + if (!activeDocumentId) return; const document = stores.documents.get(activeDocumentId); document?.star(); @@ -86,14 +82,13 @@ export const unstarDocument = createAction({ visible: ({ activeDocumentId, stores }) => { if (!activeDocumentId) return false; const document = stores.documents.get(activeDocumentId); - return ( !!document?.isStarred && stores.policies.abilities(activeDocumentId).unstar ); }, perform: ({ activeDocumentId, stores }) => { - if (!activeDocumentId) return false; + if (!activeDocumentId) return; const document = stores.documents.get(activeDocumentId); document?.unstar(); @@ -109,7 +104,7 @@ export const downloadDocument = createAction({ visible: ({ activeDocumentId, stores }) => !!activeDocumentId && stores.policies.abilities(activeDocumentId).download, perform: ({ activeDocumentId, stores }) => { - if (!activeDocumentId) return false; + if (!activeDocumentId) return; const document = stores.documents.get(activeDocumentId); document?.download(); @@ -125,16 +120,16 @@ export const duplicateDocument = createAction({ visible: ({ activeDocumentId, stores }) => !!activeDocumentId && stores.policies.abilities(activeDocumentId).update, perform: async ({ activeDocumentId, t, stores }) => { - if (!activeDocumentId) return false; + if (!activeDocumentId) return; const document = stores.documents.get(activeDocumentId); invariant(document, "Document must exist"); - const duped = await document.duplicate(); - // when duplicating, go straight to the duplicated document content history.push(duped.url); - stores.toasts.showToast(t("Document duplicated"), { type: "success" }); + stores.toasts.showToast(t("Document duplicated"), { + type: "success", + }); }, }); @@ -150,7 +145,7 @@ export const printDocument = createAction({ }); export const importDocument = createAction({ - name: ({ t, activeDocumentId }) => t("Import document"), + name: ({ t }) => t("Import document"), section: DocumentSection, icon: , keywords: "upload", @@ -158,18 +153,20 @@ export const importDocument = createAction({ if (activeDocumentId) { return !!stores.policies.abilities(activeDocumentId).createChildDocument; } + if (activeCollectionId) { return !!stores.policies.abilities(activeCollectionId).update; } + return false; }, perform: ({ activeCollectionId, activeDocumentId, stores }) => { const { documents, toasts } = stores; - const input = document.createElement("input"); input.type = "file"; input.accept = documents.importFileTypes.join(", "); - input.onchange = async (ev: SyntheticEvent<>) => { + + input.onchange = async (ev: Event) => { const files = getDataTransferFiles(ev); try { @@ -187,10 +184,10 @@ export const importDocument = createAction({ toasts.showToast(err.message, { type: "error", }); - throw err; } }; + input.click(); }, }); @@ -202,9 +199,7 @@ export const createTemplate = createAction({ keywords: "new create template", visible: ({ activeCollectionId, activeDocumentId, stores }) => { if (!activeDocumentId) return false; - const document = stores.documents.get(activeDocumentId); - return ( !!activeCollectionId && stores.policies.abilities(activeCollectionId).update && @@ -212,6 +207,8 @@ export const createTemplate = createAction({ ); }, perform: ({ activeDocumentId, stores, t, event }) => { + if (!activeDocumentId) return; + event?.preventDefault(); event?.stopPropagation(); diff --git a/app/actions/definitions/navigation.js b/app/actions/definitions/navigation.tsx similarity index 92% rename from app/actions/definitions/navigation.js rename to app/actions/definitions/navigation.tsx index db5d38cf89..003865a8f6 100644 --- a/app/actions/definitions/navigation.js +++ b/app/actions/definitions/navigation.tsx @@ -1,4 +1,3 @@ -// @flow import { HomeIcon, SearchIcon, @@ -17,12 +16,12 @@ import { changelogUrl, mailToUrl, githubIssuesUrl, -} from "shared/utils/routeHelpers"; -import stores from "stores"; -import KeyboardShortcuts from "scenes/KeyboardShortcuts"; -import { createAction } from "actions"; -import { NavigationSection } from "actions/sections"; -import history from "utils/history"; +} from "@shared/utils/routeHelpers"; +import stores from "~/stores"; +import KeyboardShortcuts from "~/scenes/KeyboardShortcuts"; +import { createAction } from "~/actions"; +import { NavigationSection } from "~/actions/sections"; +import history from "~/utils/history"; import { settingsPath, homePath, @@ -31,7 +30,7 @@ import { templatesPath, archivePath, trashPath, -} from "utils/routeHelpers"; +} from "~/utils/routeHelpers"; export const navigateToHome = createAction({ name: ({ t }) => t("Home"), diff --git a/app/actions/definitions/settings.js b/app/actions/definitions/settings.tsx similarity index 79% rename from app/actions/definitions/settings.js rename to app/actions/definitions/settings.tsx index c2accae34a..4328728078 100644 --- a/app/actions/definitions/settings.js +++ b/app/actions/definitions/settings.tsx @@ -1,9 +1,9 @@ -// @flow import { SunIcon, MoonIcon, BrowserIcon } from "outline-icons"; import * as React from "react"; -import stores from "stores"; -import { createAction } from "actions"; -import { SettingsSection } from "actions/sections"; +import stores from "~/stores"; +import { Theme } from "~/stores/UiStore"; +import { createAction } from "~/actions"; +import { SettingsSection } from "~/actions/sections"; export const changeToDarkTheme = createAction({ name: ({ t }) => t("Dark"), @@ -12,7 +12,7 @@ export const changeToDarkTheme = createAction({ keywords: "theme dark night", section: SettingsSection, selected: () => stores.ui.theme === "dark", - perform: () => stores.ui.setTheme("dark"), + perform: () => stores.ui.setTheme(Theme.Dark), }); export const changeToLightTheme = createAction({ @@ -22,7 +22,7 @@ export const changeToLightTheme = createAction({ keywords: "theme light day", section: SettingsSection, selected: () => stores.ui.theme === "light", - perform: () => stores.ui.setTheme("light"), + perform: () => stores.ui.setTheme(Theme.Light), }); export const changeToSystemTheme = createAction({ @@ -32,7 +32,7 @@ export const changeToSystemTheme = createAction({ keywords: "theme system default", section: SettingsSection, selected: () => stores.ui.theme === "system", - perform: () => stores.ui.setTheme("system"), + perform: () => stores.ui.setTheme(Theme.System), }); export const changeTheme = createAction({ diff --git a/app/actions/definitions/users.js b/app/actions/definitions/users.tsx similarity index 77% rename from app/actions/definitions/users.js rename to app/actions/definitions/users.tsx index d60f2e66fc..cb10834c25 100644 --- a/app/actions/definitions/users.js +++ b/app/actions/definitions/users.tsx @@ -1,10 +1,9 @@ -// @flow import { PlusIcon } from "outline-icons"; import * as React from "react"; -import stores from "stores"; -import Invite from "scenes/Invite"; -import { createAction } from "actions"; -import { UserSection } from "actions/sections"; +import stores from "~/stores"; +import Invite from "~/scenes/Invite"; +import { createAction } from "~/actions"; +import { UserSection } from "~/actions/sections"; export const inviteUser = createAction({ name: ({ t }) => `${t("Invite people")}…`, diff --git a/app/actions/index.js b/app/actions/index.ts similarity index 76% rename from app/actions/index.js rename to app/actions/index.ts index 0e61d21f3a..622f448dae 100644 --- a/app/actions/index.js +++ b/app/actions/index.ts @@ -1,17 +1,22 @@ -// @flow import { flattenDeep } from "lodash"; import * as React from "react"; +import { $Diff } from "utility-types"; import { v4 as uuidv4 } from "uuid"; -import type { +import { Action, ActionContext, CommandBarAction, - MenuItemClickable, + MenuItemButton, MenuItemWithChildren, -} from "types"; +} from "~/types"; export function createAction( - definition: $Diff + definition: $Diff< + Action, + { + id?: string; + } + > ): Action { return { id: uuidv4(), @@ -22,7 +27,7 @@ export function createAction( export function actionToMenuItem( action: Action, context: ActionContext -): MenuItemClickable | MenuItemWithChildren { +): MenuItemButton | MenuItemWithChildren { function resolve(value: any): T { if (typeof value === "function") { return value(context); @@ -31,18 +36,20 @@ export function actionToMenuItem( return value; } - const resolvedIcon = resolve>(action.icon); + const resolvedIcon = resolve>(action.icon); const resolvedChildren = resolve(action.children); - const visible = action.visible ? action.visible(context) : true; const title = resolve(action.name); const icon = resolvedIcon && action.iconInContextMenu !== false - ? React.cloneElement(resolvedIcon, { color: "currentColor" }) + ? React.cloneElement(resolvedIcon, { + color: "currentColor", + }) : undefined; if (resolvedChildren) { return { + type: "submenu", title, icon, items: resolvedChildren @@ -53,6 +60,7 @@ export function actionToMenuItem( } return { + type: "button", title, icon, visible, @@ -77,12 +85,11 @@ export function actionToKBar( return []; } - const resolvedIcon = resolve>(action.icon); + const resolvedIcon = resolve>(action.icon); const resolvedChildren = resolve(action.children); const resolvedSection = resolve(action.section); const resolvedName = resolve(action.name); const resolvedPlaceholder = resolve(action.placeholder); - const children = resolvedChildren ? flattenDeep(resolvedChildren.map((a) => actionToKBar(a, context))).filter( (a) => !!a @@ -99,19 +106,17 @@ export function actionToKBar( .filter((c) => !!c.keywords) .map((c) => c.keywords) .join(" ")}`, - shortcut: action.shortcut, + shortcut: action.shortcut || [], icon: resolvedIcon - ? React.cloneElement(resolvedIcon, { color: "currentColor" }) + ? React.cloneElement(resolvedIcon, { + color: "currentColor", + }) : undefined, perform: action.perform ? () => action.perform && action.perform(context) : undefined, children: children.length ? children.map((a) => a.id) : undefined, }, - ].concat( - children.map((child) => ({ - ...child, - parent: action.id, - })) - ); + // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. + ].concat(children.map((child) => ({ ...child, parent: action.id }))); } diff --git a/app/actions/root.js b/app/actions/root.ts similarity index 98% rename from app/actions/root.js rename to app/actions/root.ts index 7be0013d14..9894e0d72a 100644 --- a/app/actions/root.js +++ b/app/actions/root.ts @@ -1,4 +1,3 @@ -// @flow import { rootCollectionActions } from "./definitions/collections"; import { rootDebugActions } from "./definitions/debug"; import { rootDocumentActions } from "./definitions/documents"; diff --git a/app/actions/sections.js b/app/actions/sections.ts similarity index 89% rename from app/actions/sections.js rename to app/actions/sections.ts index 97fc3ae73e..e8a6a6320c 100644 --- a/app/actions/sections.js +++ b/app/actions/sections.ts @@ -1,5 +1,4 @@ -// @flow -import { type ActionContext } from "types"; +import { ActionContext } from "~/types"; export const CollectionSection = ({ t }: ActionContext) => t("Collection"); diff --git a/app/components/Actions.js b/app/components/Actions.ts similarity index 95% rename from app/components/Actions.js rename to app/components/Actions.ts index 444ce49688..54b1212dec 100644 --- a/app/components/Actions.js +++ b/app/components/Actions.ts @@ -1,7 +1,6 @@ -// @flow import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; -import Flex from "components/Flex"; +import Flex from "~/components/Flex"; export const Action = styled(Flex)` justify-content: center; diff --git a/app/components/Analytics.js b/app/components/Analytics.ts similarity index 78% rename from app/components/Analytics.js rename to app/components/Analytics.ts index ef9e0f154f..1bf1e5d94c 100644 --- a/app/components/Analytics.js +++ b/app/components/Analytics.ts @@ -1,32 +1,30 @@ -// @flow /* global ga */ import * as React from "react"; -import env from "env"; +import env from "~/env"; type Props = { - children?: React.Node, + children?: React.ReactNode; }; export default class Analytics extends React.Component { componentDidMount() { if (!env.GOOGLE_ANALYTICS_ID) { - return null; + return; } // standard Google Analytics script window.ga = window.ga || - function () { - // $FlowIssue - (ga.q = ga.q || []).push(arguments); + function (...args) { + (ga.q = ga.q || []).push(args); }; - // $FlowIssue ga.l = +new Date(); ga("create", env.GOOGLE_ANALYTICS_ID, "auto"); - ga("set", { dimension1: "true" }); + ga("set", { + dimension1: "true", + }); ga("send", "pageview"); - const script = document.createElement("script"); script.src = "https://www.google-analytics.com/analytics.js"; script.async = true; diff --git a/app/components/Arrow.js b/app/components/Arrow.tsx similarity index 98% rename from app/components/Arrow.js rename to app/components/Arrow.tsx index 2b6ade160a..ba462d5774 100644 --- a/app/components/Arrow.js +++ b/app/components/Arrow.tsx @@ -1,4 +1,3 @@ -// @flow import * as React from "react"; export default function Arrow() { diff --git a/app/components/AuthLogo/GoogleLogo.js b/app/components/AuthLogo/GoogleLogo.tsx similarity index 93% rename from app/components/AuthLogo/GoogleLogo.js rename to app/components/AuthLogo/GoogleLogo.tsx index b4132b7a69..4854512b96 100644 --- a/app/components/AuthLogo/GoogleLogo.js +++ b/app/components/AuthLogo/GoogleLogo.tsx @@ -1,10 +1,9 @@ -// @flow import * as React from "react"; type Props = { - size?: number, - fill?: string, - className?: string, + size?: number; + fill?: string; + className?: string; }; function GoogleLogo({ size = 34, fill = "#FFF", className }: Props) { diff --git a/app/components/AuthLogo/MicrosoftLogo.js b/app/components/AuthLogo/MicrosoftLogo.tsx similarity index 94% rename from app/components/AuthLogo/MicrosoftLogo.js rename to app/components/AuthLogo/MicrosoftLogo.tsx index a73c5b84f4..393b524883 100644 --- a/app/components/AuthLogo/MicrosoftLogo.js +++ b/app/components/AuthLogo/MicrosoftLogo.tsx @@ -1,10 +1,9 @@ -// @flow import * as React from "react"; type Props = { - size?: number, - fill?: string, - className?: string, + size?: number; + fill?: string; + className?: string; }; function MicrosoftLogo({ size = 34, fill = "#FFF", className }: Props) { diff --git a/app/components/AuthLogo/SlackLogo.js b/app/components/AuthLogo/SlackLogo.tsx similarity index 98% rename from app/components/AuthLogo/SlackLogo.js rename to app/components/AuthLogo/SlackLogo.tsx index 69388b9217..1d19f5b8bb 100644 --- a/app/components/AuthLogo/SlackLogo.js +++ b/app/components/AuthLogo/SlackLogo.tsx @@ -1,10 +1,9 @@ -// @flow import * as React from "react"; type Props = { - size?: number, - fill?: string, - className?: string, + size?: number; + fill?: string; + className?: string; }; function SlackLogo({ size = 34, fill = "#FFF", className }: Props) { diff --git a/app/components/AuthLogo/index.js b/app/components/AuthLogo/index.tsx similarity index 91% rename from app/components/AuthLogo/index.js rename to app/components/AuthLogo/index.tsx index d2b444f2a2..669b6591e3 100644 --- a/app/components/AuthLogo/index.js +++ b/app/components/AuthLogo/index.tsx @@ -1,14 +1,13 @@ -// @flow import * as React from "react"; import styled from "styled-components"; import GoogleLogo from "./GoogleLogo"; import MicrosoftLogo from "./MicrosoftLogo"; import SlackLogo from "./SlackLogo"; -type Props = {| - providerName: string, - size?: number, -|}; +type Props = { + providerName: string; + size?: number; +}; function AuthLogo({ providerName, size = 16 }: Props) { switch (providerName) { @@ -18,18 +17,21 @@ function AuthLogo({ providerName, size = 16 }: Props) { ); + case "google": return ( ); + case "azure": return ( ); + default: return null; } diff --git a/app/components/Authenticated.js b/app/components/Authenticated.tsx similarity index 84% rename from app/components/Authenticated.js rename to app/components/Authenticated.tsx index c2d489a501..225791c663 100644 --- a/app/components/Authenticated.js +++ b/app/components/Authenticated.tsx @@ -1,16 +1,15 @@ -// @flow import { observer } from "mobx-react"; import * as React from "react"; import { useTranslation } from "react-i18next"; import { Redirect } from "react-router-dom"; -import { isCustomSubdomain } from "shared/utils/domains"; -import LoadingIndicator from "components/LoadingIndicator"; -import useStores from "../hooks/useStores"; -import { changeLanguage } from "../utils/language"; -import env from "env"; +import { isCustomSubdomain } from "@shared/utils/domains"; +import LoadingIndicator from "~/components/LoadingIndicator"; +import env from "~/env"; +import useStores from "~/hooks/useStores"; +import { changeLanguage } from "~/utils/language"; type Props = { - children: React.Node, + children: JSX.Element; }; const Authenticated = ({ children }: Props) => { diff --git a/app/components/Avatar/Avatar.js b/app/components/Avatar/Avatar.tsx similarity index 82% rename from app/components/Avatar/Avatar.js rename to app/components/Avatar/Avatar.tsx index c8b25dafe4..88601f43ff 100644 --- a/app/components/Avatar/Avatar.js +++ b/app/components/Avatar/Avatar.tsx @@ -1,24 +1,24 @@ -// @flow import { observable } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import styled from "styled-components"; -import User from "models/User"; +import User from "~/models/User"; import placeholder from "./placeholder.png"; -type Props = {| - src: string, - size: number, - icon?: React.Node, - user?: User, - alt?: string, - onClick?: () => void, - className?: string, -|}; +type Props = { + src: string; + size: number; + icon?: React.ReactNode; + user?: User; + alt?: string; + onClick?: () => void; + className?: string; +}; @observer class Avatar extends React.Component { - @observable error: boolean; + @observable + error: boolean; static defaultProps = { size: 24, @@ -30,7 +30,6 @@ class Avatar extends React.Component { render() { const { src, icon, ...rest } = this.props; - return ( ` display: block; width: ${(props) => props.size}px; height: ${(props) => props.size}px; diff --git a/app/components/Avatar/AvatarWithPresence.js b/app/components/Avatar/AvatarWithPresence.tsx similarity index 75% rename from app/components/Avatar/AvatarWithPresence.js rename to app/components/Avatar/AvatarWithPresence.tsx index 831e17d513..6055f5665f 100644 --- a/app/components/Avatar/AvatarWithPresence.js +++ b/app/components/Avatar/AvatarWithPresence.tsx @@ -1,26 +1,25 @@ -// @flow import { observable } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; -import { withTranslation, type TFunction } from "react-i18next"; +import { WithTranslation, withTranslation } from "react-i18next"; import styled from "styled-components"; -import User from "models/User"; -import UserProfile from "scenes/UserProfile"; -import Avatar from "components/Avatar"; -import Tooltip from "components/Tooltip"; +import User from "~/models/User"; +import UserProfile from "~/scenes/UserProfile"; +import Avatar from "~/components/Avatar"; +import Tooltip from "~/components/Tooltip"; -type Props = { - user: User, - isPresent: boolean, - isEditing: boolean, - isCurrentUser: boolean, - profileOnClick: boolean, - t: TFunction, +type Props = WithTranslation & { + user: User; + isPresent: boolean; + isEditing: boolean; + isCurrentUser: boolean; + profileOnClick: boolean; }; @observer class AvatarWithPresence extends React.Component { - @observable isOpen: boolean = false; + @observable + isOpen = false; handleOpenProfile = () => { this.isOpen = true; @@ -32,13 +31,11 @@ class AvatarWithPresence extends React.Component { render() { const { user, isPresent, isEditing, isCurrentUser, t } = this.props; - const action = isPresent ? isEditing ? t("currently editing") : t("currently viewing") : t("previously edited"); - return ( <> ` opacity: ${(props) => (props.isPresent ? 1 : 0.5)}; transition: opacity 250ms ease-in-out; `; -export default withTranslation()(AvatarWithPresence); +export default withTranslation()(AvatarWithPresence); diff --git a/app/components/Avatar/index.js b/app/components/Avatar/index.ts similarity index 94% rename from app/components/Avatar/index.js rename to app/components/Avatar/index.ts index 0106b24db4..4dc0cb18b7 100644 --- a/app/components/Avatar/index.js +++ b/app/components/Avatar/index.ts @@ -1,6 +1,6 @@ -// @flow import Avatar from "./Avatar"; import AvatarWithPresence from "./AvatarWithPresence"; export { AvatarWithPresence }; + export default Avatar; diff --git a/app/components/Badge.js b/app/components/Badge.ts similarity index 89% rename from app/components/Badge.js rename to app/components/Badge.ts index 04d564b84f..bd0c1d11af 100644 --- a/app/components/Badge.js +++ b/app/components/Badge.ts @@ -1,7 +1,6 @@ -// @flow import styled from "styled-components"; -const Badge = styled.span` +const Badge = styled.span<{ yellow?: boolean; primary?: boolean }>` margin-left: 10px; padding: 1px 5px 2px; background-color: ${({ yellow, primary, theme }) => diff --git a/app/components/Branding.js b/app/components/Branding.tsx similarity index 93% rename from app/components/Branding.js rename to app/components/Branding.tsx index 38a90a3406..756130eee7 100644 --- a/app/components/Branding.js +++ b/app/components/Branding.tsx @@ -1,11 +1,10 @@ -// @flow import * as React from "react"; import styled from "styled-components"; +import env from "~/env"; import OutlineLogo from "./OutlineLogo"; -import env from "env"; type Props = { - href?: string, + href?: string; }; function Branding({ href = env.URL }: Props) { diff --git a/app/components/Breadcrumb.js b/app/components/Breadcrumb.tsx similarity index 73% rename from app/components/Breadcrumb.js rename to app/components/Breadcrumb.tsx index 350e20ad95..fb19e89719 100644 --- a/app/components/Breadcrumb.js +++ b/app/components/Breadcrumb.tsx @@ -1,35 +1,36 @@ -// @flow import { GoToIcon } from "outline-icons"; import * as React from "react"; import { Link } from "react-router-dom"; import styled from "styled-components"; -import Flex from "components/Flex"; -import BreadcrumbMenu from "menus/BreadcrumbMenu"; +import Flex from "~/components/Flex"; +import BreadcrumbMenu from "~/menus/BreadcrumbMenu"; +import { MenuInternalLink } from "~/types"; -type MenuItem = {| - icon?: React.Node, - title: React.Node, - to?: string, -|}; +export type Crumb = { + title: React.ReactNode; + icon?: React.ReactNode; + to?: string; +}; -type Props = {| - items: MenuItem[], - max?: number, - children?: React.Node, - highlightFirstItem?: boolean, -|}; +type Props = { + items: Crumb[]; + max?: number; + children?: React.ReactNode; + highlightFirstItem?: boolean; +}; function Breadcrumb({ items, highlightFirstItem, children, max = 2 }: Props) { const totalItems = items.length; - let topLevelItems: MenuItem[] = [...items]; + const topLevelItems: Crumb[] = [...items]; let overflowItems; // chop middle breadcrumbs and present a "..." menu instead if (totalItems > max) { const halfMax = Math.floor(max / 2); overflowItems = topLevelItems.splice(halfMax, totalItems - max); + topLevelItems.splice(halfMax, 0, { - title: , + title: , }); } @@ -42,7 +43,7 @@ function Breadcrumb({ items, highlightFirstItem, children, max = 2 }: Props) { {item.title} @@ -62,7 +63,7 @@ const Slash = styled(GoToIcon)` fill: ${(props) => props.theme.divider}; `; -const Item = styled(Link)` +const Item = styled(Link)<{ $highlight: boolean; $withIcon: boolean }>` display: flex; flex-shrink: 1; min-width: 0; diff --git a/app/components/Bubble.js b/app/components/Bubble.tsx similarity index 88% rename from app/components/Bubble.js rename to app/components/Bubble.tsx index 656ba7b547..6cba8e80b1 100644 --- a/app/components/Bubble.js +++ b/app/components/Bubble.tsx @@ -1,11 +1,10 @@ -// @flow import * as React from "react"; import styled from "styled-components"; -import { bounceIn } from "styles/animations"; +import { bounceIn } from "~/styles/animations"; -type Props = {| - count: number, -|}; +type Props = { + count: number; +}; const Bubble = ({ count }: Props) => { if (!count) { diff --git a/app/components/Button.js b/app/components/Button.tsx similarity index 64% rename from app/components/Button.js rename to app/components/Button.tsx index c29b8ae8c4..e8c1c0d42c 100644 --- a/app/components/Button.js +++ b/app/components/Button.tsx @@ -1,10 +1,15 @@ -// @flow import { ExpandedIcon } from "outline-icons"; import { darken } from "polished"; import * as React from "react"; import styled from "styled-components"; -const RealButton = styled.button` +const RealButton = styled.button<{ + fullwidth?: boolean; + borderOnHover?: boolean; + neutral?: boolean; + danger?: boolean; + iconColor?: string; +}>` display: ${(props) => (props.fullwidth ? "block" : "inline-block")}; width: ${(props) => (props.fullwidth ? "100%" : "auto")}; margin: 0; @@ -50,7 +55,7 @@ const RealButton = styled.button` } ${(props) => - props.$neutral && + props.neutral && ` background: ${props.theme.buttonNeutralBackground}; color: ${props.theme.buttonNeutralText}; @@ -87,7 +92,9 @@ const RealButton = styled.button` fill: ${props.theme.textTertiary}; } } - `} ${(props) => + `} + + ${(props) => props.danger && ` background: ${props.theme.danger}; @@ -99,7 +106,7 @@ const RealButton = styled.button` `}; `; -const Label = styled.span` +const Label = styled.span<{ hasIcon?: boolean }>` overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -107,7 +114,11 @@ const Label = styled.span` ${(props) => props.hasIcon && "padding-left: 4px;"}; `; -export const Inner = styled.span` +export const Inner = styled.span<{ + disclosure?: boolean; + hasIcon?: boolean; + hasText?: boolean; +}>` display: flex; padding: 0 8px; padding-right: ${(props) => (props.disclosure ? 2 : 8)}px; @@ -120,58 +131,41 @@ export const Inner = styled.span` ${(props) => props.hasIcon && !props.hasText && "padding: 0 4px;"}; `; -export type Props = {| - type?: "button" | "submit", - value?: string, - icon?: React.Node, - iconColor?: string, - className?: string, - children?: React.Node, - innerRef?: React.ElementRef, - disclosure?: boolean, - neutral?: boolean, - danger?: boolean, - primary?: boolean, - disabled?: boolean, - fullwidth?: boolean, - autoFocus?: boolean, - style?: Object, - as?: React.ComponentType | string, - to?: string, - onClick?: (event: SyntheticEvent<>) => mixed, - borderOnHover?: boolean, - href?: string, - "data-on"?: string, - "data-event-category"?: string, - "data-event-action"?: string, -|}; +export type Props = { + icon?: React.ReactNode; + iconColor?: string; + children?: React.ReactNode; + disclosure?: boolean; + neutral?: boolean; + danger?: boolean; + primary?: boolean; + fullwidth?: boolean; + as?: T; + to?: string; + borderOnHover?: boolean; + href?: string; + "data-on"?: string; + "data-event-category"?: string; + "data-event-action"?: string; +}; -const Button = React.forwardRef( - ( - { - type = "text", - icon, - children, - value, - disclosure, - neutral, - ...rest - }: Props, - innerRef - ) => { - const hasText = children !== undefined || value !== undefined; - const hasIcon = icon !== undefined; +const Button = ( + props: Props & React.ComponentPropsWithoutRef, + ref: React.Ref +) => { + const { type, icon, children, value, disclosure, neutral, ...rest } = props; + const hasText = children !== undefined || value !== undefined; + const hasIcon = icon !== undefined; - return ( - - - {hasIcon && icon} - {hasText && } - {disclosure && } - - - ); - } -); + return ( + + + {hasIcon && icon} + {hasText && } + {disclosure && } + + + ); +}; -export default Button; +export default React.forwardRef(Button); diff --git a/app/components/ButtonLarge.js b/app/components/ButtonLarge.ts similarity index 95% rename from app/components/ButtonLarge.js rename to app/components/ButtonLarge.ts index f3611bbd8a..24e28947d7 100644 --- a/app/components/ButtonLarge.js +++ b/app/components/ButtonLarge.ts @@ -1,4 +1,3 @@ -// @flow import styled from "styled-components"; import Button, { Inner } from "./Button"; diff --git a/app/components/ButtonLink.js b/app/components/ButtonLink.tsx similarity index 81% rename from app/components/ButtonLink.js rename to app/components/ButtonLink.tsx index b42e1efdca..89302b628c 100644 --- a/app/components/ButtonLink.js +++ b/app/components/ButtonLink.tsx @@ -1,10 +1,9 @@ -// @flow import * as React from "react"; import styled from "styled-components"; type Props = { - onClick: (ev: SyntheticEvent<>) => void, - children: React.Node, + onClick: React.MouseEventHandler; + children: React.ReactNode; }; export default function ButtonLink(props: Props) { diff --git a/app/components/CenteredContent.js b/app/components/CenteredContent.tsx similarity index 73% rename from app/components/CenteredContent.js rename to app/components/CenteredContent.tsx index 3f3685cdd5..5724b8285e 100644 --- a/app/components/CenteredContent.js +++ b/app/components/CenteredContent.tsx @@ -1,20 +1,19 @@ -// @flow import * as React from "react"; import styled from "styled-components"; import breakpoint from "styled-components-breakpoint"; -type Props = {| - children?: React.Node, - withStickyHeader?: boolean, -|}; +type Props = { + children?: React.ReactNode; + withStickyHeader?: boolean; +}; -const Container = styled.div` +const Container = styled.div<{ withStickyHeader?: boolean }>` width: 100%; max-width: 100vw; padding: ${(props) => (props.withStickyHeader ? "4px 12px" : "60px 12px")}; ${breakpoint("tablet")` - padding: ${(props) => (props.withStickyHeader ? "4px 60px" : "60px")}; + padding: ${(props: any) => (props.withStickyHeader ? "4px 60px" : "60px")}; `}; `; diff --git a/app/components/Checkbox.js b/app/components/Checkbox.tsx similarity index 68% rename from app/components/Checkbox.js rename to app/components/Checkbox.tsx index 11e9e7ab80..ecf01d4229 100644 --- a/app/components/Checkbox.js +++ b/app/components/Checkbox.tsx @@ -1,29 +1,27 @@ -// @flow import * as React from "react"; import { VisuallyHidden } from "reakit/VisuallyHidden"; import styled from "styled-components"; -import HelpText from "components/HelpText"; +import HelpText from "~/components/HelpText"; -export type Props = {| - checked?: boolean, - label?: React.Node, - labelHidden?: boolean, - className?: string, - name?: string, - disabled?: boolean, - onChange: (event: SyntheticInputEvent) => mixed, - note?: React.Node, - short?: boolean, - small?: boolean, -|}; +export type Props = { + checked?: boolean; + label?: React.ReactNode; + labelHidden?: boolean; + className?: string; + name?: string; + disabled?: boolean; + onChange: (event: React.ChangeEvent) => unknown; + note?: React.ReactNode; + small?: boolean; +}; -const LabelText = styled.span` +const LabelText = styled.span<{ small?: boolean }>` font-weight: 500; margin-left: ${(props) => (props.small ? "6px" : "10px")}; ${(props) => (props.small ? `color: ${props.theme.textSecondary}` : "")}; `; -const Wrapper = styled.div` +const Wrapper = styled.div<{ small?: boolean }>` padding-bottom: 8px; ${(props) => (props.small ? "font-size: 14px" : "")}; width: 100%; @@ -41,14 +39,13 @@ export default function Checkbox({ note, className, small, - short, ...rest }: Props) { const wrappedLabel = {label}; return ( <> - +