mirror of
https://github.com/flarum/framework.git
synced 2025-02-18 05:52:47 +08:00
feat: export registry (#3842)
* feat: registry first iteration Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * feat: improve webpack auto export loader Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * chore: remove `compat` API Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> * chore: cleanup Signed-off-by: Sami Mazouz <sychocouldy@gmail.com> --------- Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>
This commit is contained in:
parent
cf70865aa6
commit
016503d8c3
|
@ -15,7 +15,7 @@
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
||||||
"flarum/flags/*": ["../../flags/js/dist-typings/*"]
|
"ext:flarum/flags/*": ["../../flags/js/dist-typings/*"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import addFlagsToPosts from './addFlagsToPosts';
|
|
||||||
import addFlagControl from './addFlagControl';
|
|
||||||
import addFlagsDropdown from './addFlagsDropdown';
|
|
||||||
import Flag from './models/Flag';
|
|
||||||
import FlagList from './components/FlagList';
|
|
||||||
import FlagPostModal from './components/FlagPostModal';
|
|
||||||
import FlagsPage from './components/FlagsPage';
|
|
||||||
import FlagsDropdown from './components/FlagsDropdown';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
'flags/addFlagsToPosts': addFlagsToPosts,
|
|
||||||
'flags/addFlagControl': addFlagControl,
|
|
||||||
'flags/addFlagsDropdown': addFlagsDropdown,
|
|
||||||
'flags/models/Flag': Flag,
|
|
||||||
'flags/components/FlagList': FlagList,
|
|
||||||
'flags/components/FlagPostModal': FlagPostModal,
|
|
||||||
'flags/components/FlagsPage': FlagsPage,
|
|
||||||
'flags/components/FlagsDropdown': FlagsDropdown,
|
|
||||||
};
|
|
|
@ -1,5 +1,5 @@
|
||||||
import app from 'flarum/forum/app';
|
import app from 'flarum/forum/app';
|
||||||
import Page from 'flarum/components/Page';
|
import Page from 'flarum/common/components/Page';
|
||||||
|
|
||||||
import FlagList from './FlagList';
|
import FlagList from './FlagList';
|
||||||
|
|
||||||
|
|
10
extensions/flags/js/src/forum/forum.ts
Normal file
10
extensions/flags/js/src/forum/forum.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import './addFlagsToPosts';
|
||||||
|
import './addFlagControl';
|
||||||
|
import './addFlagsDropdown';
|
||||||
|
|
||||||
|
import './models/Flag';
|
||||||
|
|
||||||
|
import './components/FlagList';
|
||||||
|
import './components/FlagPostModal';
|
||||||
|
import './components/FlagsPage';
|
||||||
|
import './components/FlagsDropdown';
|
|
@ -15,8 +15,4 @@ app.initializers.add('flarum-flags', () => {
|
||||||
addFlagsToPosts();
|
addFlagsToPosts();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Expose compat API
|
import './forum';
|
||||||
import flagsCompat from './compat';
|
|
||||||
import { compat } from '@flarum/core/forum';
|
|
||||||
|
|
||||||
Object.assign(compat, flagsCompat);
|
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
// This will output typings to `dist-typings`
|
// This will output typings to `dist-typings`
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
|
||||||
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,7 @@
|
||||||
// This will output typings to `dist-typings`
|
// This will output typings to `dist-typings`
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
|
||||||
// TODO: remove after export registry system implemented
|
|
||||||
// Without this, the old-style `@flarum/core` import is resolved to
|
|
||||||
// source code in flarum/core instead of the dist typings.
|
|
||||||
// This causes an inaccurate "duplicate export" error.
|
|
||||||
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,7 @@
|
||||||
// This will output typings to `dist-typings`
|
// This will output typings to `dist-typings`
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
|
||||||
// TODO: remove after export registry system implemented
|
|
||||||
// Without this, the old-style `@flarum/core` import is resolved to
|
|
||||||
// source code in flarum/core instead of the dist typings.
|
|
||||||
// This causes an inaccurate "duplicate export" error.
|
|
||||||
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import GroupMentionedNotification from './components/GroupMentionedNotification';
|
|
||||||
import MentionsUserPage from './components/MentionsUserPage';
|
|
||||||
import PostMentionedNotification from './components/PostMentionedNotification';
|
|
||||||
import UserMentionedNotification from './components/UserMentionedNotification';
|
|
||||||
import AutocompleteDropdown from './fragments/AutocompleteDropdown';
|
|
||||||
import PostQuoteButton from './fragments/PostQuoteButton';
|
|
||||||
import getCleanDisplayName from './utils/getCleanDisplayName';
|
|
||||||
import getMentionText from './utils/getMentionText';
|
|
||||||
import * as reply from './utils/reply';
|
|
||||||
import selectedText from './utils/selectedText';
|
|
||||||
import * as textFormatter from './utils/textFormatter';
|
|
||||||
import MentionableModel from './mentionables/MentionableModel';
|
|
||||||
import MentionFormat from './mentionables/formats/MentionFormat';
|
|
||||||
import Mentionables from './extenders/Mentionables';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
'mentions/components/MentionsUserPage': MentionsUserPage,
|
|
||||||
'mentions/components/PostMentionedNotification': PostMentionedNotification,
|
|
||||||
'mentions/components/UserMentionedNotification': UserMentionedNotification,
|
|
||||||
'mentions/components/GroupMentionedNotification': GroupMentionedNotification,
|
|
||||||
'mentions/fragments/AutocompleteDropdown': AutocompleteDropdown,
|
|
||||||
'mentions/fragments/PostQuoteButton': PostQuoteButton,
|
|
||||||
'mentions/utils/getCleanDisplayName': getCleanDisplayName,
|
|
||||||
'mentions/utils/getMentionText': getMentionText,
|
|
||||||
'mentions/utils/reply': reply,
|
|
||||||
'mentions/utils/selectedText': selectedText,
|
|
||||||
'mentions/utils/textFormatter': textFormatter,
|
|
||||||
'mentions/mentionables/MentionableModel': MentionableModel,
|
|
||||||
'mentions/mentionables/formats/MentionFormat': MentionFormat,
|
|
||||||
'mentions/extenders/Mentionables': Mentionables,
|
|
||||||
};
|
|
14
extensions/mentions/js/src/forum/forum.js
Normal file
14
extensions/mentions/js/src/forum/forum.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import './components/GroupMentionedNotification';
|
||||||
|
import './components/MentionsUserPage';
|
||||||
|
import './components/PostMentionedNotification';
|
||||||
|
import './components/UserMentionedNotification';
|
||||||
|
import './fragments/AutocompleteDropdown';
|
||||||
|
import './fragments/PostQuoteButton';
|
||||||
|
import './utils/getCleanDisplayName';
|
||||||
|
import './utils/getMentionText';
|
||||||
|
import './utils/reply';
|
||||||
|
import './utils/selectedText';
|
||||||
|
import './utils/textFormatter';
|
||||||
|
import './mentionables/MentionableModel';
|
||||||
|
import './mentionables/formats/MentionFormat';
|
||||||
|
import './extenders/Mentionables';
|
|
@ -15,8 +15,6 @@ import UserMentionedNotification from './components/UserMentionedNotification';
|
||||||
import GroupMentionedNotification from './components/GroupMentionedNotification';
|
import GroupMentionedNotification from './components/GroupMentionedNotification';
|
||||||
import UserPage from 'flarum/forum/components/UserPage';
|
import UserPage from 'flarum/forum/components/UserPage';
|
||||||
import LinkButton from 'flarum/common/components/LinkButton';
|
import LinkButton from 'flarum/common/components/LinkButton';
|
||||||
import User from 'flarum/common/models/User';
|
|
||||||
import Model from 'flarum/common/Model';
|
|
||||||
|
|
||||||
export { default as extend } from './extend';
|
export { default as extend } from './extend';
|
||||||
|
|
||||||
|
@ -90,8 +88,4 @@ app.initializers.add('flarum-mentions', function () {
|
||||||
|
|
||||||
export * from './utils/textFormatter';
|
export * from './utils/textFormatter';
|
||||||
|
|
||||||
// Expose compat API
|
import './forum';
|
||||||
import mentionsCompat from './compat';
|
|
||||||
import { compat } from '@flarum/core/forum';
|
|
||||||
|
|
||||||
Object.assign(compat, mentionsCompat);
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import app from 'flarum/forum/app';
|
import app from 'flarum/forum/app';
|
||||||
import Badge from 'flarum/common/components/Badge';
|
import Badge from 'flarum/common/components/Badge';
|
||||||
import highlight from 'flarum/common/helpers/highlight';
|
import highlight from 'flarum/common/helpers/highlight';
|
||||||
import type Tag from 'flarum/tags/common/models/Tag';
|
import type Tag from 'ext:flarum/tags/common/models/Tag';
|
||||||
import type Mithril from 'mithril';
|
import type Mithril from 'mithril';
|
||||||
import MentionableModel from './MentionableModel';
|
import MentionableModel from './MentionableModel';
|
||||||
import type HashMentionFormat from './formats/HashMentionFormat';
|
import type HashMentionFormat from './formats/HashMentionFormat';
|
||||||
|
|
|
@ -10,12 +10,7 @@
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
||||||
"flarum/tags/*": ["../../tags/js/dist-typings/*"],
|
"ext:flarum/tags/*": ["../../tags/js/dist-typings/*"]
|
||||||
// TODO: remove after export registry system implemented
|
|
||||||
// Without this, the old-style `@flarum/core` import is resolved to
|
|
||||||
// source code in flarum/core instead of the dist typings.
|
|
||||||
// This causes an inaccurate "duplicate export" error.
|
|
||||||
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,7 @@
|
||||||
// This will output typings to `dist-typings`
|
// This will output typings to `dist-typings`
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
|
||||||
// TODO: remove after export registry system implemented
|
|
||||||
// Without this, the old-style `@flarum/core` import is resolved to
|
|
||||||
// source code in flarum/core instead of the dist typings.
|
|
||||||
// This causes an inaccurate "duplicate export" error.
|
|
||||||
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import IndexPage from 'flarum/forum/components/IndexPage';
|
||||||
import Button from 'flarum/common/components/Button';
|
import Button from 'flarum/common/components/Button';
|
||||||
import ItemList from 'flarum/common/utils/ItemList';
|
import ItemList from 'flarum/common/utils/ItemList';
|
||||||
import type { Children } from 'mithril';
|
import type { Children } from 'mithril';
|
||||||
import type Tag from 'flarum/tags/common/models/Tag';
|
import type Tag from 'ext:flarum/tags/common/models/Tag';
|
||||||
|
|
||||||
export type PusherBinding = {
|
export type PusherBinding = {
|
||||||
channels: {
|
channels: {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
||||||
"flarum/tags/*": ["../../tags/js/dist-typings/*"]
|
"ext:flarum/tags/*": ["../../tags/js/dist-typings/*"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,7 @@
|
||||||
// This will output typings to `dist-typings`
|
// This will output typings to `dist-typings`
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
|
||||||
// TODO: remove after export registry system implemented
|
|
||||||
// Without this, the old-style `@flarum/core` import is resolved to
|
|
||||||
// source code in flarum/core instead of the dist typings.
|
|
||||||
// This causes an inaccurate "duplicate export" error.
|
|
||||||
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../vendor/flarum/core/js/dist-typings/*"],
|
"flarum/*": ["../vendor/flarum/core/js/dist-typings/*"]
|
||||||
"@flarum/core/*": ["../vendor/flarum/core/js/dist-typings/*"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import app from 'flarum/app';
|
import app from 'flarum/admin/app';
|
||||||
|
|
||||||
app.initializers.add('flarum-suspend', () => {
|
app.initializers.add('flarum-suspend', () => {
|
||||||
app.extensionData.for('flarum-suspend').registerPermission(
|
app.extensionData.for('flarum-suspend').registerPermission(
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
import SuspendUserModal from './components/SuspendUserModal';
|
|
||||||
import SuspensionInfoModal from './components/SuspensionInfoModal';
|
|
||||||
import UserSuspendedNotification from './components/UserSuspendedNotification';
|
|
||||||
import UserUnsuspendedNotification from './components/UserUnsuspendedNotification';
|
|
||||||
import checkForSuspension from './checkForSuspension';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
'suspend/components/suspendUserModal': SuspendUserModal,
|
|
||||||
'suspend/components/suspensionInfoModal': SuspensionInfoModal,
|
|
||||||
'suspend/components/UserSuspendedNotification': UserSuspendedNotification,
|
|
||||||
'suspend/components/UserUnsuspendedNotification': UserUnsuspendedNotification,
|
|
||||||
'suspend/checkForSuspension': checkForSuspension,
|
|
||||||
};
|
|
|
@ -1,10 +1,10 @@
|
||||||
import app from 'flarum/forum/app';
|
import app from 'flarum/forum/app';
|
||||||
import Modal from 'flarum/components/Modal';
|
import Modal from 'flarum/common/components/Modal';
|
||||||
import Button from 'flarum/components/Button';
|
import Button from 'flarum/common/components/Button';
|
||||||
|
import Stream from 'flarum/common/utils/Stream';
|
||||||
import Stream from 'flarum/utils/Stream';
|
import withAttr from 'flarum/common/utils/withAttr';
|
||||||
import withAttr from 'flarum/utils/withAttr';
|
|
||||||
import ItemList from 'flarum/common/utils/ItemList';
|
import ItemList from 'flarum/common/utils/ItemList';
|
||||||
|
|
||||||
import { getPermanentSuspensionDate } from '../helpers/suspensionHelper';
|
import { getPermanentSuspensionDate } from '../helpers/suspensionHelper';
|
||||||
|
|
||||||
export default class SuspendUserModal extends Modal {
|
export default class SuspendUserModal extends Modal {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import app from 'flarum/forum/app';
|
import app from 'flarum/forum/app';
|
||||||
import Notification from 'flarum/components/Notification';
|
import Notification from 'flarum/forum/components/Notification';
|
||||||
|
|
||||||
import { isPermanentSuspensionDate } from '../helpers/suspensionHelper';
|
import { isPermanentSuspensionDate } from '../helpers/suspensionHelper';
|
||||||
|
|
||||||
export default class UserSuspendedNotification extends Notification {
|
export default class UserSuspendedNotification extends Notification {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import app from 'flarum/forum/app';
|
import app from 'flarum/forum/app';
|
||||||
import Notification from 'flarum/components/Notification';
|
import Notification from 'flarum/forum/components/Notification';
|
||||||
|
|
||||||
export default class UserUnsuspendedNotification extends Notification {
|
export default class UserUnsuspendedNotification extends Notification {
|
||||||
icon() {
|
icon() {
|
||||||
|
|
6
extensions/suspend/js/src/forum/forum.ts
Normal file
6
extensions/suspend/js/src/forum/forum.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import './components/SuspendUserModal';
|
||||||
|
import './components/SuspensionInfoModal';
|
||||||
|
import './components/UserSuspendedNotification';
|
||||||
|
import './components/UserUnsuspendedNotification';
|
||||||
|
|
||||||
|
import './checkForSuspension';
|
|
@ -1,9 +1,9 @@
|
||||||
import { extend } from 'flarum/extend';
|
import { extend } from 'flarum/common/extend';
|
||||||
import app from 'flarum/app';
|
import app from 'flarum/forum/app';
|
||||||
import UserControls from 'flarum/utils/UserControls';
|
import UserControls from 'flarum/forum/utils/UserControls';
|
||||||
import Button from 'flarum/components/Button';
|
import Button from 'flarum/common/components/Button';
|
||||||
import Badge from 'flarum/components/Badge';
|
import Badge from 'flarum/common/components/Badge';
|
||||||
import User from 'flarum/models/User';
|
import User from 'flarum/common/models/User';
|
||||||
|
|
||||||
import SuspendUserModal from './components/SuspendUserModal';
|
import SuspendUserModal from './components/SuspendUserModal';
|
||||||
import UserSuspendedNotification from './components/UserSuspendedNotification';
|
import UserSuspendedNotification from './components/UserSuspendedNotification';
|
||||||
|
@ -42,8 +42,4 @@ app.initializers.add('flarum-suspend', () => {
|
||||||
checkForSuspension();
|
checkForSuspension();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Expose compat API
|
import './forum';
|
||||||
import suspendCompat from './compat';
|
|
||||||
import { compat } from '@flarum/core/forum';
|
|
||||||
|
|
||||||
Object.assign(compat, suspendCompat);
|
|
||||||
|
|
|
@ -9,12 +9,7 @@
|
||||||
// This will output typings to `dist-typings`
|
// This will output typings to `dist-typings`
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
|
||||||
// TODO: remove after export registry system implemented
|
|
||||||
// Without this, the old-style `@flarum/core` import is resolved to
|
|
||||||
// source code in flarum/core instead of the dist typings.
|
|
||||||
// This causes an inaccurate "duplicate export" error.
|
|
||||||
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
9
extensions/tags/js/src/admin/admin.ts
Normal file
9
extensions/tags/js/src/admin/admin.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import '../common/common';
|
||||||
|
|
||||||
|
import './components/TagsPage';
|
||||||
|
import './components/EditTagModal';
|
||||||
|
|
||||||
|
import './addTagsHomePageOption';
|
||||||
|
import './addTagChangePermission';
|
||||||
|
import './addTagPermission';
|
||||||
|
import './addTagsPermissionScope';
|
|
@ -1,17 +0,0 @@
|
||||||
import compat from '../common/compat';
|
|
||||||
|
|
||||||
import addTagsHomePageOption from './addTagsHomePageOption';
|
|
||||||
import addTagChangePermission from './addTagChangePermission';
|
|
||||||
import TagsPage from './components/TagsPage';
|
|
||||||
import EditTagModal from './components/EditTagModal';
|
|
||||||
import addTagPermission from './addTagPermission';
|
|
||||||
import addTagsPermissionScope from './addTagsPermissionScope';
|
|
||||||
|
|
||||||
export default Object.assign(compat, {
|
|
||||||
'tags/addTagsHomePageOption': addTagsHomePageOption,
|
|
||||||
'tags/addTagChangePermission': addTagChangePermission,
|
|
||||||
'tags/components/TagsPage': TagsPage,
|
|
||||||
'tags/components/EditTagModal': EditTagModal,
|
|
||||||
'tags/addTagPermission': addTagPermission,
|
|
||||||
'tags/addTagsPermissionScope': addTagsPermissionScope,
|
|
||||||
});
|
|
|
@ -21,8 +21,4 @@ app.initializers.add('flarum-tags', (app) => {
|
||||||
addTagSelectionSettingComponent();
|
addTagSelectionSettingComponent();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Expose compat API
|
import './admin';
|
||||||
import tagsCompat from './compat';
|
|
||||||
import { compat } from '@flarum/core/admin';
|
|
||||||
|
|
||||||
Object.assign(compat, tagsCompat);
|
|
||||||
|
|
11
extensions/tags/js/src/common/common.ts
Normal file
11
extensions/tags/js/src/common/common.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import './utils/sortTags';
|
||||||
|
|
||||||
|
import './models/Tag';
|
||||||
|
|
||||||
|
import './helpers/tagsLabel';
|
||||||
|
import './helpers/tagIcon';
|
||||||
|
import './helpers/tagLabel';
|
||||||
|
|
||||||
|
import './components/TagSelectionModal';
|
||||||
|
|
||||||
|
import './states/TagListState';
|
|
@ -1,17 +0,0 @@
|
||||||
import sortTags from './utils/sortTags';
|
|
||||||
import Tag from './models/Tag';
|
|
||||||
import tagsLabel from './helpers/tagsLabel';
|
|
||||||
import tagIcon from './helpers/tagIcon';
|
|
||||||
import tagLabel from './helpers/tagLabel';
|
|
||||||
import TagSelectionModal from './components/TagSelectionModal';
|
|
||||||
import TagListState from './states/TagListState';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
'tags/utils/sortTags': sortTags,
|
|
||||||
'tags/models/Tag': Tag,
|
|
||||||
'tags/helpers/tagsLabel': tagsLabel,
|
|
||||||
'tags/helpers/tagIcon': tagIcon,
|
|
||||||
'tags/helpers/tagLabel': tagLabel,
|
|
||||||
'tags/components/TagSelectionModal': TagSelectionModal,
|
|
||||||
'tags/states/TagListState': TagListState,
|
|
||||||
};
|
|
|
@ -1,27 +0,0 @@
|
||||||
import compat from '../common/compat';
|
|
||||||
|
|
||||||
import addTagFilter from './addTagFilter';
|
|
||||||
import addTagControl from './addTagControl';
|
|
||||||
import TagHero from './components/TagHero';
|
|
||||||
import TagDiscussionModal from './components/TagDiscussionModal';
|
|
||||||
import TagsPage from './components/TagsPage';
|
|
||||||
import DiscussionTaggedPost from './components/DiscussionTaggedPost';
|
|
||||||
import TagLinkButton from './components/TagLinkButton';
|
|
||||||
import addTagList from './addTagList';
|
|
||||||
import addTagLabels from './addTagLabels';
|
|
||||||
import addTagComposer from './addTagComposer';
|
|
||||||
import getSelectableTags from './utils/getSelectableTags';
|
|
||||||
|
|
||||||
export default Object.assign(compat, {
|
|
||||||
'tags/addTagFilter': addTagFilter,
|
|
||||||
'tags/addTagControl': addTagControl,
|
|
||||||
'tags/components/TagHero': TagHero,
|
|
||||||
'tags/components/TagDiscussionModal': TagDiscussionModal,
|
|
||||||
'tags/components/TagsPage': TagsPage,
|
|
||||||
'tags/components/DiscussionTaggedPost': DiscussionTaggedPost,
|
|
||||||
'tags/components/TagLinkButton': TagLinkButton,
|
|
||||||
'tags/addTagList': addTagList,
|
|
||||||
'tags/addTagLabels': addTagLabels,
|
|
||||||
'tags/addTagComposer': addTagComposer,
|
|
||||||
'tags/utils/getSelectableTags': getSelectableTags,
|
|
||||||
});
|
|
15
extensions/tags/js/src/forum/forum.ts
Normal file
15
extensions/tags/js/src/forum/forum.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import '../common/common';
|
||||||
|
|
||||||
|
import './utils/getSelectableTags';
|
||||||
|
|
||||||
|
import './components/TagHero';
|
||||||
|
import './components/TagDiscussionModal';
|
||||||
|
import './components/TagsPage';
|
||||||
|
import './components/DiscussionTaggedPost';
|
||||||
|
import './components/TagLinkButton';
|
||||||
|
|
||||||
|
import './addTagFilter';
|
||||||
|
import './addTagControl';
|
||||||
|
import './addTagList';
|
||||||
|
import './addTagLabels';
|
||||||
|
import './addTagComposer';
|
|
@ -20,8 +20,4 @@ app.initializers.add('flarum-tags', function () {
|
||||||
addTagComposer();
|
addTagComposer();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Expose compat API
|
import './forum';
|
||||||
import tagsCompat from './compat';
|
|
||||||
import { compat } from '@flarum/core/forum';
|
|
||||||
|
|
||||||
Object.assign(compat, tagsCompat);
|
|
||||||
|
|
|
@ -9,12 +9,7 @@
|
||||||
// This will output typings to `dist-typings`
|
// This will output typings to `dist-typings`
|
||||||
"declarationDir": "./dist-typings",
|
"declarationDir": "./dist-typings",
|
||||||
"paths": {
|
"paths": {
|
||||||
"flarum/*": ["../../../framework/core/js/dist-typings/*"],
|
"flarum/*": ["../../../framework/core/js/dist-typings/*"]
|
||||||
// TODO: remove after export registry system implemented
|
|
||||||
// Without this, the old-style `@flarum/core` import is resolved to
|
|
||||||
// source code in flarum/core instead of the dist typings.
|
|
||||||
// This causes an inaccurate "duplicate export" error.
|
|
||||||
"@flarum/core/*": ["../../../framework/core/js/dist-typings/*"],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
framework/core/js/src/@types/global.d.ts
vendored
2
framework/core/js/src/@types/global.d.ts
vendored
|
@ -98,6 +98,8 @@ interface FlarumObject {
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
extensions: Readonly<Record<string, ESModule>>;
|
extensions: Readonly<Record<string, ESModule>>;
|
||||||
|
|
||||||
|
reg: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const flarum: FlarumObject;
|
declare const flarum: FlarumObject;
|
||||||
|
|
40
framework/core/js/src/admin/admin.ts
Normal file
40
framework/core/js/src/admin/admin.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import '../common/common';
|
||||||
|
|
||||||
|
import './utils/saveSettings';
|
||||||
|
import './utils/ExtensionData';
|
||||||
|
import './utils/isExtensionEnabled';
|
||||||
|
import './utils/getCategorizedExtensions';
|
||||||
|
import './utils/generateElementId';
|
||||||
|
|
||||||
|
import './components/SettingDropdown';
|
||||||
|
import './components/EditCustomFooterModal';
|
||||||
|
import './components/SessionDropdown';
|
||||||
|
import './components/HeaderPrimary';
|
||||||
|
import './components/AdminPage';
|
||||||
|
import './components/AppearancePage';
|
||||||
|
import './components/StatusWidget';
|
||||||
|
import './components/ExtensionsWidget';
|
||||||
|
import './components/HeaderSecondary';
|
||||||
|
import './components/SettingsModal';
|
||||||
|
import './components/DashboardWidget';
|
||||||
|
import './components/ExtensionPage';
|
||||||
|
import './components/ExtensionLinkButton';
|
||||||
|
import './components/PermissionGrid';
|
||||||
|
import './components/ExtensionPermissionGrid';
|
||||||
|
import './components/MailPage';
|
||||||
|
import './components/UploadImageButton';
|
||||||
|
import './components/LoadingModal';
|
||||||
|
import './components/DashboardPage';
|
||||||
|
import './components/BasicsPage';
|
||||||
|
import './components/UserListPage';
|
||||||
|
import './components/EditCustomHeaderModal';
|
||||||
|
import './components/PermissionsPage';
|
||||||
|
import './components/PermissionDropdown';
|
||||||
|
import './components/AdminNav';
|
||||||
|
import './components/AdminHeader';
|
||||||
|
import './components/EditCustomCssModal';
|
||||||
|
import './components/EditGroupModal';
|
||||||
|
import './components/CreateUserModal';
|
||||||
|
|
||||||
|
import './routes';
|
||||||
|
import './AdminApplication';
|
|
@ -1,77 +0,0 @@
|
||||||
import compat from '../common/compat';
|
|
||||||
|
|
||||||
import saveSettings from './utils/saveSettings';
|
|
||||||
import ExtensionData from './utils/ExtensionData';
|
|
||||||
import isExtensionEnabled from './utils/isExtensionEnabled';
|
|
||||||
import getCategorizedExtensions from './utils/getCategorizedExtensions';
|
|
||||||
import SettingDropdown from './components/SettingDropdown';
|
|
||||||
import EditCustomFooterModal from './components/EditCustomFooterModal';
|
|
||||||
import SessionDropdown from './components/SessionDropdown';
|
|
||||||
import HeaderPrimary from './components/HeaderPrimary';
|
|
||||||
import AdminPage from './components/AdminPage';
|
|
||||||
import AppearancePage from './components/AppearancePage';
|
|
||||||
import StatusWidget from './components/StatusWidget';
|
|
||||||
import ExtensionsWidget from './components/ExtensionsWidget';
|
|
||||||
import HeaderSecondary from './components/HeaderSecondary';
|
|
||||||
import SettingsModal from './components/SettingsModal';
|
|
||||||
import DashboardWidget from './components/DashboardWidget';
|
|
||||||
import ExtensionPage from './components/ExtensionPage';
|
|
||||||
import ExtensionLinkButton from './components/ExtensionLinkButton';
|
|
||||||
import PermissionGrid from './components/PermissionGrid';
|
|
||||||
import ExtensionPermissionGrid from './components/ExtensionPermissionGrid';
|
|
||||||
import MailPage from './components/MailPage';
|
|
||||||
import UploadImageButton from './components/UploadImageButton';
|
|
||||||
import LoadingModal from './components/LoadingModal';
|
|
||||||
import DashboardPage from './components/DashboardPage';
|
|
||||||
import BasicsPage from './components/BasicsPage';
|
|
||||||
import UserListPage from './components/UserListPage';
|
|
||||||
import EditCustomHeaderModal from './components/EditCustomHeaderModal';
|
|
||||||
import PermissionsPage from './components/PermissionsPage';
|
|
||||||
import PermissionDropdown from './components/PermissionDropdown';
|
|
||||||
import AdminNav from './components/AdminNav';
|
|
||||||
import AdminHeader from './components/AdminHeader';
|
|
||||||
import EditCustomCssModal from './components/EditCustomCssModal';
|
|
||||||
import EditGroupModal from './components/EditGroupModal';
|
|
||||||
import routes from './routes';
|
|
||||||
import AdminApplication from './AdminApplication';
|
|
||||||
import generateElementId from './utils/generateElementId';
|
|
||||||
import CreateUserModal from './components/CreateUserModal';
|
|
||||||
|
|
||||||
export default Object.assign(compat, {
|
|
||||||
'utils/saveSettings': saveSettings,
|
|
||||||
'utils/ExtensionData': ExtensionData,
|
|
||||||
'utils/isExtensionEnabled': isExtensionEnabled,
|
|
||||||
'utils/getCategorizedExtensions': getCategorizedExtensions,
|
|
||||||
'utils/generateElementId': generateElementId,
|
|
||||||
'components/SettingDropdown': SettingDropdown,
|
|
||||||
'components/EditCustomFooterModal': EditCustomFooterModal,
|
|
||||||
'components/SessionDropdown': SessionDropdown,
|
|
||||||
'components/HeaderPrimary': HeaderPrimary,
|
|
||||||
'components/AdminPage': AdminPage,
|
|
||||||
'components/AppearancePage': AppearancePage,
|
|
||||||
'components/StatusWidget': StatusWidget,
|
|
||||||
'components/ExtensionsWidget': ExtensionsWidget,
|
|
||||||
'components/HeaderSecondary': HeaderSecondary,
|
|
||||||
'components/SettingsModal': SettingsModal,
|
|
||||||
'components/DashboardWidget': DashboardWidget,
|
|
||||||
'components/ExtensionPage': ExtensionPage,
|
|
||||||
'components/ExtensionLinkButton': ExtensionLinkButton,
|
|
||||||
'components/PermissionGrid': PermissionGrid,
|
|
||||||
'components/ExtensionPermissionGrid': ExtensionPermissionGrid,
|
|
||||||
'components/MailPage': MailPage,
|
|
||||||
'components/UploadImageButton': UploadImageButton,
|
|
||||||
'components/LoadingModal': LoadingModal,
|
|
||||||
'components/DashboardPage': DashboardPage,
|
|
||||||
'components/BasicsPage': BasicsPage,
|
|
||||||
'components/UserListPage': UserListPage,
|
|
||||||
'components/EditCustomHeaderModal': EditCustomHeaderModal,
|
|
||||||
'components/PermissionsPage': PermissionsPage,
|
|
||||||
'components/PermissionDropdown': PermissionDropdown,
|
|
||||||
'components/AdminNav': AdminNav,
|
|
||||||
'components/AdminHeader': AdminHeader,
|
|
||||||
'components/EditCustomCssModal': EditCustomCssModal,
|
|
||||||
'components/EditGroupModal': EditGroupModal,
|
|
||||||
'components/CreateUserModal': CreateUserModal,
|
|
||||||
routes: routes,
|
|
||||||
AdminApplication: AdminApplication,
|
|
||||||
});
|
|
|
@ -2,13 +2,4 @@ import app from './app';
|
||||||
|
|
||||||
export { app };
|
export { app };
|
||||||
|
|
||||||
// Export public API
|
import './admin';
|
||||||
|
|
||||||
// Export compat API
|
|
||||||
import compatObj from './compat';
|
|
||||||
import proxifyCompat from '../common/utils/proxifyCompat';
|
|
||||||
|
|
||||||
// @ts-expect-error The `app` instance needs to be available on compat.
|
|
||||||
compatObj.app = app;
|
|
||||||
|
|
||||||
export const compat = proxifyCompat(compatObj, 'admin');
|
|
||||||
|
|
58
framework/core/js/src/common/ExportRegistry.ts
Normal file
58
framework/core/js/src/common/ExportRegistry.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export interface IExportRegistry {
|
||||||
|
moduleExports: Map<string, Map<string, any>>;
|
||||||
|
onLoads: Map<string, Map<string, Function[]>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an instance to the registry.
|
||||||
|
*/
|
||||||
|
add(namespace: string, id: string, object: any): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a function to run when object of id "id" is added (or overriden).
|
||||||
|
* If such an object is already registered, the handler will be applied immediately.
|
||||||
|
*/
|
||||||
|
onLoad(namespace: string, id: string, handler: Function): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an object of type `id` from the registry.
|
||||||
|
*/
|
||||||
|
get(namespace: string, id: string): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ExportRegistry implements IExportRegistry {
|
||||||
|
moduleExports = new Map<string, Map<string, any>>();
|
||||||
|
onLoads = new Map<string, Map<string, Function[]>>();
|
||||||
|
|
||||||
|
add(namespace: string, id: string, object: any): void {
|
||||||
|
this.moduleExports.set(namespace, this.moduleExports.get(namespace) || new Map());
|
||||||
|
this.moduleExports.get(namespace)?.set(id, object);
|
||||||
|
|
||||||
|
this.onLoads
|
||||||
|
.get(namespace)
|
||||||
|
?.get(id)
|
||||||
|
?.forEach((handler) => handler(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(namespace: string, id: string, handler: Function): void {
|
||||||
|
if (this.moduleExports.has(namespace) && this.moduleExports.get(namespace)?.has(id)) {
|
||||||
|
handler(this.moduleExports.get(namespace)?.get(id));
|
||||||
|
} else {
|
||||||
|
this.onLoads.set(namespace, this.onLoads.get(namespace) || new Map());
|
||||||
|
this.onLoads.get(namespace)?.set(id, this.onLoads.get(namespace)?.get(id) || []);
|
||||||
|
this.onLoads.get(namespace)?.get(id)?.push(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get(namespace: string, id: string): any {
|
||||||
|
const module = this.moduleExports.get(namespace)?.get(id);
|
||||||
|
|
||||||
|
if (!module) {
|
||||||
|
console.warn(`No module found for ${namespace}:${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
}
|
89
framework/core/js/src/common/common.ts
Normal file
89
framework/core/js/src/common/common.ts
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import './extend';
|
||||||
|
import './extenders';
|
||||||
|
|
||||||
|
import './states/PaginatedListState';
|
||||||
|
import './states/AlertManagerState';
|
||||||
|
import './states/ModalManagerState';
|
||||||
|
import './states/PageState';
|
||||||
|
|
||||||
|
import './utils/isObject';
|
||||||
|
import './utils/mixin';
|
||||||
|
import './utils/insertText';
|
||||||
|
import './utils/styleSelectedText';
|
||||||
|
import './utils/Drawer';
|
||||||
|
import './utils/anchorScroll';
|
||||||
|
import './utils/RequestError';
|
||||||
|
import './utils/abbreviateNumber';
|
||||||
|
import './utils/escapeRegExp';
|
||||||
|
import './utils/string';
|
||||||
|
import './utils/throttleDebounce';
|
||||||
|
import './utils/Stream';
|
||||||
|
import './utils/SubtreeRetainer';
|
||||||
|
import './utils/setRouteWithForcedRefresh';
|
||||||
|
import './utils/extract';
|
||||||
|
import './utils/ScrollListener';
|
||||||
|
import './utils/stringToColor';
|
||||||
|
import './utils/subclassOf';
|
||||||
|
import './utils/patchMithril';
|
||||||
|
import './utils/classList';
|
||||||
|
import './utils/extractText';
|
||||||
|
import './utils/formatNumber';
|
||||||
|
import './utils/mapRoutes';
|
||||||
|
import './utils/withAttr';
|
||||||
|
import './utils/focusTrap';
|
||||||
|
import './utils/isDark';
|
||||||
|
import './utils/KeyboardNavigatable';
|
||||||
|
|
||||||
|
import './models/Notification';
|
||||||
|
import './models/User';
|
||||||
|
import './models/Post';
|
||||||
|
import './models/Discussion';
|
||||||
|
import './models/Group';
|
||||||
|
import './models/Forum';
|
||||||
|
|
||||||
|
import './components/AlertManager';
|
||||||
|
import './components/Page';
|
||||||
|
import './components/Switch';
|
||||||
|
import './components/Badge';
|
||||||
|
import './components/LoadingIndicator';
|
||||||
|
import './components/Placeholder';
|
||||||
|
import './components/Separator';
|
||||||
|
import './components/Dropdown';
|
||||||
|
import './components/SplitDropdown';
|
||||||
|
import './components/RequestErrorModal';
|
||||||
|
import './components/FieldSet';
|
||||||
|
import './components/Select';
|
||||||
|
import './components/Navigation';
|
||||||
|
import './components/Alert';
|
||||||
|
import './components/Link';
|
||||||
|
import './components/LinkButton';
|
||||||
|
import './components/Checkbox';
|
||||||
|
import './components/ColorPreviewInput';
|
||||||
|
import './components/SelectDropdown';
|
||||||
|
import './components/ModalManager';
|
||||||
|
import './components/Button';
|
||||||
|
import './components/Modal';
|
||||||
|
import './components/GroupBadge';
|
||||||
|
import './components/TextEditor';
|
||||||
|
import './components/TextEditorButton';
|
||||||
|
import './components/EditUserModal';
|
||||||
|
import './components/Tooltip';
|
||||||
|
|
||||||
|
import './helpers/fullTime';
|
||||||
|
import './helpers/avatar';
|
||||||
|
import './helpers/icon';
|
||||||
|
import './helpers/humanTime';
|
||||||
|
import './helpers/punctuateSeries';
|
||||||
|
import './helpers/highlight';
|
||||||
|
import './helpers/username';
|
||||||
|
import './helpers/userOnline';
|
||||||
|
import './helpers/listItems';
|
||||||
|
import './helpers/textContrastClass';
|
||||||
|
|
||||||
|
import './resolvers/DefaultResolver';
|
||||||
|
|
||||||
|
import './Component';
|
||||||
|
import './Translator';
|
||||||
|
import './Model';
|
||||||
|
import './Application';
|
||||||
|
import './Fragment';
|
|
@ -1,187 +0,0 @@
|
||||||
import * as extend from './extend';
|
|
||||||
import extenders from './extenders';
|
|
||||||
import Session from './Session';
|
|
||||||
import Store from './Store';
|
|
||||||
import BasicEditorDriver from './utils/BasicEditorDriver';
|
|
||||||
import evented from './utils/evented';
|
|
||||||
import EventEmitter from './utils/EventEmitter';
|
|
||||||
import KeyboardNavigatable from './utils/KeyboardNavigatable';
|
|
||||||
import liveHumanTimes from './utils/liveHumanTimes';
|
|
||||||
import ItemList from './utils/ItemList';
|
|
||||||
import mixin from './utils/mixin';
|
|
||||||
import humanTime from './utils/humanTime';
|
|
||||||
import computed from './utils/computed';
|
|
||||||
import insertText from './utils/insertText';
|
|
||||||
import styleSelectedText from './utils/styleSelectedText';
|
|
||||||
import Drawer from './utils/Drawer';
|
|
||||||
import anchorScroll from './utils/anchorScroll';
|
|
||||||
import RequestError from './utils/RequestError';
|
|
||||||
import abbreviateNumber from './utils/abbreviateNumber';
|
|
||||||
import escapeRegExp from './utils/escapeRegExp';
|
|
||||||
import * as string from './utils/string';
|
|
||||||
import * as ThrottleDebounce from './utils/throttleDebounce';
|
|
||||||
import Stream from './utils/Stream';
|
|
||||||
import SubtreeRetainer from './utils/SubtreeRetainer';
|
|
||||||
import setRouteWithForcedRefresh from './utils/setRouteWithForcedRefresh';
|
|
||||||
import extract from './utils/extract';
|
|
||||||
import ScrollListener from './utils/ScrollListener';
|
|
||||||
import stringToColor from './utils/stringToColor';
|
|
||||||
import subclassOf from './utils/subclassOf';
|
|
||||||
import patchMithril from './utils/patchMithril';
|
|
||||||
import proxifyCompat from './utils/proxifyCompat';
|
|
||||||
import classList from './utils/classList';
|
|
||||||
import extractText from './utils/extractText';
|
|
||||||
import formatNumber from './utils/formatNumber';
|
|
||||||
import mapRoutes from './utils/mapRoutes';
|
|
||||||
import withAttr from './utils/withAttr';
|
|
||||||
import * as FocusTrap from './utils/focusTrap';
|
|
||||||
import isDark from './utils/isDark';
|
|
||||||
import Notification from './models/Notification';
|
|
||||||
import User from './models/User';
|
|
||||||
import Post from './models/Post';
|
|
||||||
import Discussion from './models/Discussion';
|
|
||||||
import Group from './models/Group';
|
|
||||||
import Forum from './models/Forum';
|
|
||||||
import Component from './Component';
|
|
||||||
import Translator from './Translator';
|
|
||||||
import AlertManager from './components/AlertManager';
|
|
||||||
import Page from './components/Page';
|
|
||||||
import Switch from './components/Switch';
|
|
||||||
import Badge from './components/Badge';
|
|
||||||
import LoadingIndicator from './components/LoadingIndicator';
|
|
||||||
import Placeholder from './components/Placeholder';
|
|
||||||
import Separator from './components/Separator';
|
|
||||||
import Dropdown from './components/Dropdown';
|
|
||||||
import SplitDropdown from './components/SplitDropdown';
|
|
||||||
import RequestErrorModal from './components/RequestErrorModal';
|
|
||||||
import FieldSet from './components/FieldSet';
|
|
||||||
import Select from './components/Select';
|
|
||||||
import Navigation from './components/Navigation';
|
|
||||||
import Alert from './components/Alert';
|
|
||||||
import Link from './components/Link';
|
|
||||||
import LinkButton from './components/LinkButton';
|
|
||||||
import Checkbox from './components/Checkbox';
|
|
||||||
import ColorPreviewInput from './components/ColorPreviewInput';
|
|
||||||
import SelectDropdown from './components/SelectDropdown';
|
|
||||||
import ModalManager from './components/ModalManager';
|
|
||||||
import Button from './components/Button';
|
|
||||||
import Modal from './components/Modal';
|
|
||||||
import GroupBadge from './components/GroupBadge';
|
|
||||||
import TextEditor from './components/TextEditor';
|
|
||||||
import TextEditorButton from './components/TextEditorButton';
|
|
||||||
import EditUserModal from './components/EditUserModal';
|
|
||||||
import Tooltip from './components/Tooltip';
|
|
||||||
import Model from './Model';
|
|
||||||
import Application from './Application';
|
|
||||||
import fullTime from './helpers/fullTime';
|
|
||||||
import avatar from './helpers/avatar';
|
|
||||||
import icon from './helpers/icon';
|
|
||||||
import humanTimeHelper from './helpers/humanTime';
|
|
||||||
import punctuateSeries from './helpers/punctuateSeries';
|
|
||||||
import highlight from './helpers/highlight';
|
|
||||||
import username from './helpers/username';
|
|
||||||
import userOnline from './helpers/userOnline';
|
|
||||||
import listItems from './helpers/listItems';
|
|
||||||
import textContrastClass from './helpers/textContrastClass';
|
|
||||||
import Fragment from './Fragment';
|
|
||||||
import DefaultResolver from './resolvers/DefaultResolver';
|
|
||||||
import PaginatedListState from './states/PaginatedListState';
|
|
||||||
import isObject from './utils/isObject';
|
|
||||||
import AlertManagerState from './states/AlertManagerState';
|
|
||||||
import ModalManagerState from './states/ModalManagerState';
|
|
||||||
import PageState from './states/PageState';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
extenders,
|
|
||||||
extend: extend,
|
|
||||||
Session: Session,
|
|
||||||
Store: Store,
|
|
||||||
'utils/BasicEditorDriver': BasicEditorDriver,
|
|
||||||
'utils/evented': evented,
|
|
||||||
'utils/EventEmitter': EventEmitter,
|
|
||||||
'utils/KeyboardNavigatable': KeyboardNavigatable,
|
|
||||||
'utils/liveHumanTimes': liveHumanTimes,
|
|
||||||
'utils/ItemList': ItemList,
|
|
||||||
'utils/mixin': mixin,
|
|
||||||
'utils/humanTime': humanTime,
|
|
||||||
'utils/computed': computed,
|
|
||||||
'utils/insertText': insertText,
|
|
||||||
'utils/styleSelectedText': styleSelectedText,
|
|
||||||
'utils/Drawer': Drawer,
|
|
||||||
'utils/anchorScroll': anchorScroll,
|
|
||||||
'utils/RequestError': RequestError,
|
|
||||||
'utils/abbreviateNumber': abbreviateNumber,
|
|
||||||
'utils/string': string,
|
|
||||||
'utils/SubtreeRetainer': SubtreeRetainer,
|
|
||||||
'utils/escapeRegExp': escapeRegExp,
|
|
||||||
'utils/extract': extract,
|
|
||||||
'utils/ScrollListener': ScrollListener,
|
|
||||||
'utils/stringToColor': stringToColor,
|
|
||||||
'utils/Stream': Stream,
|
|
||||||
'utils/subclassOf': subclassOf,
|
|
||||||
'utils/setRouteWithForcedRefresh': setRouteWithForcedRefresh,
|
|
||||||
'utils/patchMithril': patchMithril,
|
|
||||||
'utils/proxifyCompat': proxifyCompat,
|
|
||||||
'utils/classList': classList,
|
|
||||||
'utils/extractText': extractText,
|
|
||||||
'utils/formatNumber': formatNumber,
|
|
||||||
'utils/mapRoutes': mapRoutes,
|
|
||||||
'utils/withAttr': withAttr,
|
|
||||||
'utils/throttleDebounce': ThrottleDebounce,
|
|
||||||
'utils/isObject': isObject,
|
|
||||||
'utils/focusTrap': FocusTrap,
|
|
||||||
'utils/isDark': isDark,
|
|
||||||
'models/Notification': Notification,
|
|
||||||
'models/User': User,
|
|
||||||
'models/Post': Post,
|
|
||||||
'models/Discussion': Discussion,
|
|
||||||
'models/Group': Group,
|
|
||||||
'models/Forum': Forum,
|
|
||||||
Component: Component,
|
|
||||||
Fragment: Fragment,
|
|
||||||
Translator: Translator,
|
|
||||||
'components/AlertManager': AlertManager,
|
|
||||||
'components/Page': Page,
|
|
||||||
'components/Switch': Switch,
|
|
||||||
'components/Badge': Badge,
|
|
||||||
'components/LoadingIndicator': LoadingIndicator,
|
|
||||||
'components/Placeholder': Placeholder,
|
|
||||||
'components/Separator': Separator,
|
|
||||||
'components/Dropdown': Dropdown,
|
|
||||||
'components/SplitDropdown': SplitDropdown,
|
|
||||||
'components/RequestErrorModal': RequestErrorModal,
|
|
||||||
'components/FieldSet': FieldSet,
|
|
||||||
'components/Select': Select,
|
|
||||||
'components/Navigation': Navigation,
|
|
||||||
'components/Alert': Alert,
|
|
||||||
'components/Link': Link,
|
|
||||||
'components/LinkButton': LinkButton,
|
|
||||||
'components/Checkbox': Checkbox,
|
|
||||||
'components/ColorPreviewInput': ColorPreviewInput,
|
|
||||||
'components/SelectDropdown': SelectDropdown,
|
|
||||||
'components/ModalManager': ModalManager,
|
|
||||||
'components/Button': Button,
|
|
||||||
'components/Modal': Modal,
|
|
||||||
'components/GroupBadge': GroupBadge,
|
|
||||||
'components/TextEditor': TextEditor,
|
|
||||||
'components/TextEditorButton': TextEditorButton,
|
|
||||||
'components/Tooltip': Tooltip,
|
|
||||||
'components/EditUserModal': EditUserModal,
|
|
||||||
Model: Model,
|
|
||||||
Application: Application,
|
|
||||||
'helpers/fullTime': fullTime,
|
|
||||||
'helpers/avatar': avatar,
|
|
||||||
'helpers/icon': icon,
|
|
||||||
'helpers/humanTime': humanTimeHelper,
|
|
||||||
'helpers/punctuateSeries': punctuateSeries,
|
|
||||||
'helpers/highlight': highlight,
|
|
||||||
'helpers/username': username,
|
|
||||||
'helpers/userOnline': userOnline,
|
|
||||||
'helpers/listItems': listItems,
|
|
||||||
'helpers/textContrastClass': textContrastClass,
|
|
||||||
'resolvers/DefaultResolver': DefaultResolver,
|
|
||||||
'states/PaginatedListState': PaginatedListState,
|
|
||||||
'states/AlertManagerState': AlertManagerState,
|
|
||||||
'states/ModalManagerState': ModalManagerState,
|
|
||||||
'states/PageState': PageState,
|
|
||||||
};
|
|
|
@ -3,9 +3,11 @@ import PostTypes from './PostTypes';
|
||||||
import Routes from './Routes';
|
import Routes from './Routes';
|
||||||
import Store from './Store';
|
import Store from './Store';
|
||||||
|
|
||||||
export default {
|
const extenders = {
|
||||||
Model,
|
Model,
|
||||||
PostTypes,
|
PostTypes,
|
||||||
Routes,
|
Routes,
|
||||||
Store,
|
Store,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default extenders;
|
||||||
|
|
|
@ -15,6 +15,8 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
dayjs.extend(localizedFormat);
|
dayjs.extend(localizedFormat);
|
||||||
|
|
||||||
|
import './registry';
|
||||||
|
|
||||||
import patchMithril from './utils/patchMithril';
|
import patchMithril from './utils/patchMithril';
|
||||||
|
|
||||||
patchMithril(window);
|
patchMithril(window);
|
||||||
|
|
3
framework/core/js/src/common/registry.ts
Normal file
3
framework/core/js/src/common/registry.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import ExportRegistry from './ExportRegistry';
|
||||||
|
|
||||||
|
flarum.reg = new ExportRegistry();
|
|
@ -1,12 +0,0 @@
|
||||||
export default function proxifyCompat(compat: Record<string, unknown>, namespace: string) {
|
|
||||||
// regex to replace common/ and NAMESPACE/ for core & core extensions
|
|
||||||
// and remove .js, .ts and .tsx extensions
|
|
||||||
// e.g. admin/utils/extract --> utils/extract
|
|
||||||
// e.g. tags/common/utils/sortTags --> tags/utils/sortTags
|
|
||||||
const regex = new RegExp(String.raw`(\w+\/)?(${namespace}|common)\/`);
|
|
||||||
const fileExt = /(\.js|\.tsx?)$/;
|
|
||||||
|
|
||||||
return new Proxy(compat, {
|
|
||||||
get: (obj, prop: string) => obj[prop] || obj[prop.replace(regex, '$1').replace(fileExt, '')],
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,3 +1,3 @@
|
||||||
// Re-exports `throttle-debounce` to be used in `compat.js`.
|
// Re-exports `throttle-debounce` to be added in the export registry.
|
||||||
|
|
||||||
export { throttle, debounce } from 'throttle-debounce';
|
export { throttle, debounce } from 'throttle-debounce';
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
* Replaces m.withAttr for Mithril 2.0.
|
* Replaces m.withAttr for Mithril 2.0.
|
||||||
* @see https://mithril.js.org/archive/v0.2.5/mithril.withAttr.html
|
* @see https://mithril.js.org/archive/v0.2.5/mithril.withAttr.html
|
||||||
*/
|
*/
|
||||||
export default (key: string, cb: Function) =>
|
export default function withAttr(key: string, cb: Function) {
|
||||||
function (this: Element) {
|
return function (this: Element) {
|
||||||
cb(this.getAttribute(key) || (this as any)[key]);
|
cb(this.getAttribute(key) || (this as any)[key]);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
import compat from '../common/compat';
|
|
||||||
|
|
||||||
import PostControls from './utils/PostControls';
|
|
||||||
import KeyboardNavigatable from '../common/utils/KeyboardNavigatable';
|
|
||||||
import slidable from './utils/slidable';
|
|
||||||
import History from './utils/History';
|
|
||||||
import DiscussionControls from './utils/DiscussionControls';
|
|
||||||
import alertEmailConfirmation from './utils/alertEmailConfirmation';
|
|
||||||
import UserControls from './utils/UserControls';
|
|
||||||
import Pane from './utils/Pane';
|
|
||||||
import ComposerState from './states/ComposerState';
|
|
||||||
import DiscussionListState from './states/DiscussionListState';
|
|
||||||
import GlobalSearchState from './states/GlobalSearchState';
|
|
||||||
import NotificationListState from './states/NotificationListState';
|
|
||||||
import PostStreamState from './states/PostStreamState';
|
|
||||||
import SearchState from './states/SearchState';
|
|
||||||
import UserSecurityPageState from './states/UserSecurityPageState';
|
|
||||||
import AffixedSidebar from './components/AffixedSidebar';
|
|
||||||
import DiscussionPage from './components/DiscussionPage';
|
|
||||||
import DiscussionListPane from './components/DiscussionListPane';
|
|
||||||
import LogInModal from './components/LogInModal';
|
|
||||||
import ComposerBody from './components/ComposerBody';
|
|
||||||
import ForgotPasswordModal from './components/ForgotPasswordModal';
|
|
||||||
import Notification from './components/Notification';
|
|
||||||
import LogInButton from './components/LogInButton';
|
|
||||||
import DiscussionsUserPage from './components/DiscussionsUserPage';
|
|
||||||
import Composer from './components/Composer';
|
|
||||||
import SessionDropdown from './components/SessionDropdown';
|
|
||||||
import HeaderPrimary from './components/HeaderPrimary';
|
|
||||||
import PostEdited from './components/PostEdited';
|
|
||||||
import PostStream from './components/PostStream';
|
|
||||||
import ChangePasswordModal from './components/ChangePasswordModal';
|
|
||||||
import IndexPage from './components/IndexPage';
|
|
||||||
import DiscussionRenamedNotification from './components/DiscussionRenamedNotification';
|
|
||||||
import DiscussionsSearchSource from './components/DiscussionsSearchSource';
|
|
||||||
import HeaderSecondary from './components/HeaderSecondary';
|
|
||||||
import ComposerButton from './components/ComposerButton';
|
|
||||||
import DiscussionList from './components/DiscussionList';
|
|
||||||
import ReplyPlaceholder from './components/ReplyPlaceholder';
|
|
||||||
import AvatarEditor from './components/AvatarEditor';
|
|
||||||
import Post from './components/Post';
|
|
||||||
import SettingsPage from './components/SettingsPage';
|
|
||||||
import TerminalPost from './components/TerminalPost';
|
|
||||||
import ChangeEmailModal from './components/ChangeEmailModal';
|
|
||||||
import NotificationsDropdown from './components/NotificationsDropdown';
|
|
||||||
import UserPage from './components/UserPage';
|
|
||||||
import PostUser from './components/PostUser';
|
|
||||||
import UserCard from './components/UserCard';
|
|
||||||
import UsersSearchSource from './components/UsersSearchSource';
|
|
||||||
import UserSecurityPage from './components/UserSecurityPage';
|
|
||||||
import NotificationGrid from './components/NotificationGrid';
|
|
||||||
import PostPreview from './components/PostPreview';
|
|
||||||
import EventPost from './components/EventPost';
|
|
||||||
import DiscussionHero from './components/DiscussionHero';
|
|
||||||
import PostMeta from './components/PostMeta';
|
|
||||||
import DiscussionRenamedPost from './components/DiscussionRenamedPost';
|
|
||||||
import DiscussionComposer from './components/DiscussionComposer';
|
|
||||||
import LogInButtons from './components/LogInButtons';
|
|
||||||
import NotificationList from './components/NotificationList';
|
|
||||||
import WelcomeHero from './components/WelcomeHero';
|
|
||||||
import SignUpModal from './components/SignUpModal';
|
|
||||||
import CommentPost from './components/CommentPost';
|
|
||||||
import ComposerPostPreview from './components/ComposerPostPreview';
|
|
||||||
import ReplyComposer from './components/ReplyComposer';
|
|
||||||
import NotificationsPage from './components/NotificationsPage';
|
|
||||||
import PostStreamScrubber from './components/PostStreamScrubber';
|
|
||||||
import EditPostComposer from './components/EditPostComposer';
|
|
||||||
import RenameDiscussionModal from './components/RenameDiscussionModal';
|
|
||||||
import Search from './components/Search';
|
|
||||||
import DiscussionListItem from './components/DiscussionListItem';
|
|
||||||
import LoadingPost from './components/LoadingPost';
|
|
||||||
import PostsUserPage from './components/PostsUserPage';
|
|
||||||
import DiscussionPageResolver from './resolvers/DiscussionPageResolver';
|
|
||||||
import BasicEditorDriver from '../common/utils/BasicEditorDriver';
|
|
||||||
import routes from './routes';
|
|
||||||
import ForumApplication from './ForumApplication';
|
|
||||||
import isSafariMobile from './utils/isSafariMobile';
|
|
||||||
|
|
||||||
export default Object.assign(compat, {
|
|
||||||
'utils/PostControls': PostControls,
|
|
||||||
// @deprecated import from 'flarum/common/utils/KeyboardNavigatable' instead
|
|
||||||
'utils/KeyboardNavigatable': KeyboardNavigatable,
|
|
||||||
'utils/slidable': slidable,
|
|
||||||
'utils/History': History,
|
|
||||||
'utils/DiscussionControls': DiscussionControls,
|
|
||||||
'utils/alertEmailConfirmation': alertEmailConfirmation,
|
|
||||||
'utils/UserControls': UserControls,
|
|
||||||
'utils/Pane': Pane,
|
|
||||||
'utils/BasicEditorDriver': BasicEditorDriver,
|
|
||||||
'utils/isSafariMobile': isSafariMobile,
|
|
||||||
'states/ComposerState': ComposerState,
|
|
||||||
'states/DiscussionListState': DiscussionListState,
|
|
||||||
'states/GlobalSearchState': GlobalSearchState,
|
|
||||||
'states/NotificationListState': NotificationListState,
|
|
||||||
'states/PostStreamState': PostStreamState,
|
|
||||||
'states/SearchState': SearchState,
|
|
||||||
'states/UserSecurityPageState': UserSecurityPageState,
|
|
||||||
'components/AffixedSidebar': AffixedSidebar,
|
|
||||||
'components/DiscussionPage': DiscussionPage,
|
|
||||||
'components/DiscussionListPane': DiscussionListPane,
|
|
||||||
'components/LogInModal': LogInModal,
|
|
||||||
'components/ComposerBody': ComposerBody,
|
|
||||||
'components/ForgotPasswordModal': ForgotPasswordModal,
|
|
||||||
'components/Notification': Notification,
|
|
||||||
'components/LogInButton': LogInButton,
|
|
||||||
'components/DiscussionsUserPage': DiscussionsUserPage,
|
|
||||||
'components/Composer': Composer,
|
|
||||||
'components/SessionDropdown': SessionDropdown,
|
|
||||||
'components/HeaderPrimary': HeaderPrimary,
|
|
||||||
'components/PostEdited': PostEdited,
|
|
||||||
'components/PostStream': PostStream,
|
|
||||||
'components/ChangePasswordModal': ChangePasswordModal,
|
|
||||||
'components/IndexPage': IndexPage,
|
|
||||||
'components/DiscussionRenamedNotification': DiscussionRenamedNotification,
|
|
||||||
'components/DiscussionsSearchSource': DiscussionsSearchSource,
|
|
||||||
'components/HeaderSecondary': HeaderSecondary,
|
|
||||||
'components/ComposerButton': ComposerButton,
|
|
||||||
'components/DiscussionList': DiscussionList,
|
|
||||||
'components/ReplyPlaceholder': ReplyPlaceholder,
|
|
||||||
'components/AvatarEditor': AvatarEditor,
|
|
||||||
'components/Post': Post,
|
|
||||||
'components/SettingsPage': SettingsPage,
|
|
||||||
'components/TerminalPost': TerminalPost,
|
|
||||||
'components/ChangeEmailModal': ChangeEmailModal,
|
|
||||||
'components/NotificationsDropdown': NotificationsDropdown,
|
|
||||||
'components/UserPage': UserPage,
|
|
||||||
'components/PostUser': PostUser,
|
|
||||||
'components/UserCard': UserCard,
|
|
||||||
'components/UsersSearchSource': UsersSearchSource,
|
|
||||||
'components/UserSecurityPage': UserSecurityPage,
|
|
||||||
'components/NotificationGrid': NotificationGrid,
|
|
||||||
'components/PostPreview': PostPreview,
|
|
||||||
'components/EventPost': EventPost,
|
|
||||||
'components/DiscussionHero': DiscussionHero,
|
|
||||||
'components/PostMeta': PostMeta,
|
|
||||||
'components/DiscussionRenamedPost': DiscussionRenamedPost,
|
|
||||||
'components/DiscussionComposer': DiscussionComposer,
|
|
||||||
'components/LogInButtons': LogInButtons,
|
|
||||||
'components/NotificationList': NotificationList,
|
|
||||||
'components/WelcomeHero': WelcomeHero,
|
|
||||||
'components/SignUpModal': SignUpModal,
|
|
||||||
'components/CommentPost': CommentPost,
|
|
||||||
'components/ComposerPostPreview': ComposerPostPreview,
|
|
||||||
'components/ReplyComposer': ReplyComposer,
|
|
||||||
'components/NotificationsPage': NotificationsPage,
|
|
||||||
'components/PostStreamScrubber': PostStreamScrubber,
|
|
||||||
'components/EditPostComposer': EditPostComposer,
|
|
||||||
'components/RenameDiscussionModal': RenameDiscussionModal,
|
|
||||||
'components/Search': Search,
|
|
||||||
'components/DiscussionListItem': DiscussionListItem,
|
|
||||||
'components/LoadingPost': LoadingPost,
|
|
||||||
'components/PostsUserPage': PostsUserPage,
|
|
||||||
'resolvers/DiscussionPageResolver': DiscussionPageResolver,
|
|
||||||
routes: routes,
|
|
||||||
ForumApplication: ForumApplication,
|
|
||||||
});
|
|
75
framework/core/js/src/forum/forum.ts
Normal file
75
framework/core/js/src/forum/forum.ts
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import '../common/common';
|
||||||
|
import '../common/utils/BasicEditorDriver';
|
||||||
|
|
||||||
|
import './utils/PostControls';
|
||||||
|
import './utils/slidable';
|
||||||
|
import './utils/History';
|
||||||
|
import './utils/DiscussionControls';
|
||||||
|
import './utils/alertEmailConfirmation';
|
||||||
|
import './utils/UserControls';
|
||||||
|
import './utils/Pane';
|
||||||
|
import './states/ComposerState';
|
||||||
|
import './states/DiscussionListState';
|
||||||
|
import './states/GlobalSearchState';
|
||||||
|
import './states/NotificationListState';
|
||||||
|
import './states/PostStreamState';
|
||||||
|
import './states/SearchState';
|
||||||
|
import './states/UserSecurityPageState';
|
||||||
|
import './components/AffixedSidebar';
|
||||||
|
import './components/DiscussionPage';
|
||||||
|
import './components/DiscussionListPane';
|
||||||
|
import './components/LogInModal';
|
||||||
|
import './components/ComposerBody';
|
||||||
|
import './components/ForgotPasswordModal';
|
||||||
|
import './components/Notification';
|
||||||
|
import './components/LogInButton';
|
||||||
|
import './components/DiscussionsUserPage';
|
||||||
|
import './components/Composer';
|
||||||
|
import './components/SessionDropdown';
|
||||||
|
import './components/HeaderPrimary';
|
||||||
|
import './components/PostEdited';
|
||||||
|
import './components/PostStream';
|
||||||
|
import './components/ChangePasswordModal';
|
||||||
|
import './components/IndexPage';
|
||||||
|
import './components/DiscussionRenamedNotification';
|
||||||
|
import './components/DiscussionsSearchSource';
|
||||||
|
import './components/HeaderSecondary';
|
||||||
|
import './components/ComposerButton';
|
||||||
|
import './components/DiscussionList';
|
||||||
|
import './components/ReplyPlaceholder';
|
||||||
|
import './components/AvatarEditor';
|
||||||
|
import './components/Post';
|
||||||
|
import './components/SettingsPage';
|
||||||
|
import './components/TerminalPost';
|
||||||
|
import './components/ChangeEmailModal';
|
||||||
|
import './components/NotificationsDropdown';
|
||||||
|
import './components/UserPage';
|
||||||
|
import './components/PostUser';
|
||||||
|
import './components/UserCard';
|
||||||
|
import './components/UsersSearchSource';
|
||||||
|
import './components/UserSecurityPage';
|
||||||
|
import './components/NotificationGrid';
|
||||||
|
import './components/PostPreview';
|
||||||
|
import './components/EventPost';
|
||||||
|
import './components/DiscussionHero';
|
||||||
|
import './components/PostMeta';
|
||||||
|
import './components/DiscussionRenamedPost';
|
||||||
|
import './components/DiscussionComposer';
|
||||||
|
import './components/LogInButtons';
|
||||||
|
import './components/NotificationList';
|
||||||
|
import './components/WelcomeHero';
|
||||||
|
import './components/SignUpModal';
|
||||||
|
import './components/CommentPost';
|
||||||
|
import './components/ComposerPostPreview';
|
||||||
|
import './components/ReplyComposer';
|
||||||
|
import './components/NotificationsPage';
|
||||||
|
import './components/PostStreamScrubber';
|
||||||
|
import './components/EditPostComposer';
|
||||||
|
import './components/RenameDiscussionModal';
|
||||||
|
import './components/Search';
|
||||||
|
import './components/DiscussionListItem';
|
||||||
|
import './components/LoadingPost';
|
||||||
|
import './components/PostsUserPage';
|
||||||
|
import './resolvers/DiscussionPageResolver';
|
||||||
|
import './routes';
|
||||||
|
import './ForumApplication';
|
|
@ -6,11 +6,4 @@ import app from './app';
|
||||||
|
|
||||||
export { app };
|
export { app };
|
||||||
|
|
||||||
// Export compat API
|
import './forum';
|
||||||
import compatObj from './compat';
|
|
||||||
import proxifyCompat from '../common/utils/proxifyCompat';
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
compatObj.app = app;
|
|
||||||
|
|
||||||
export const compat = proxifyCompat(compatObj, 'forum');
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import extractText from '../../common/utils/extractText';
|
||||||
* The `DiscussionControls` utility constructs a list of buttons for a
|
* The `DiscussionControls` utility constructs a list of buttons for a
|
||||||
* discussion which perform actions on it.
|
* discussion which perform actions on it.
|
||||||
*/
|
*/
|
||||||
export default {
|
const DiscussionControls = {
|
||||||
/**
|
/**
|
||||||
* Get a list of controls for a discussion.
|
* Get a list of controls for a discussion.
|
||||||
*
|
*
|
||||||
|
@ -240,3 +240,5 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default DiscussionControls;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import extractText from '../../common/utils/extractText';
|
||||||
* The `PostControls` utility constructs a list of buttons for a post which
|
* The `PostControls` utility constructs a list of buttons for a post which
|
||||||
* perform actions on it.
|
* perform actions on it.
|
||||||
*/
|
*/
|
||||||
export default {
|
const PostControls = {
|
||||||
/**
|
/**
|
||||||
* Get a list of controls for a post.
|
* Get a list of controls for a post.
|
||||||
*
|
*
|
||||||
|
@ -183,3 +183,5 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default PostControls;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ItemList from '../../common/utils/ItemList';
|
||||||
* The `UserControls` utility constructs a list of buttons for a user which
|
* The `UserControls` utility constructs a list of buttons for a user which
|
||||||
* perform actions on it.
|
* perform actions on it.
|
||||||
*/
|
*/
|
||||||
export default {
|
const UserControls = {
|
||||||
/**
|
/**
|
||||||
* Get a list of controls for a user.
|
* Get a list of controls for a user.
|
||||||
*
|
*
|
||||||
|
@ -146,3 +146,5 @@ export default {
|
||||||
app.modal.show(EditUserModal, { user });
|
app.modal.show(EditUserModal, { user });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default UserControls;
|
||||||
|
|
|
@ -40,7 +40,7 @@ class AddTranslations
|
||||||
$sources->addString(function () use ($locale) {
|
$sources->addString(function () use ($locale) {
|
||||||
$translations = $this->getTranslations($locale);
|
$translations = $this->getTranslations($locale);
|
||||||
|
|
||||||
return 'flarum.core.app.translator.addTranslations('.json_encode($translations).')';
|
return 'app.translator.addTranslations('.json_encode($translations).')';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,9 @@
|
||||||
document.getElementById('flarum-loading').style.display = 'none';
|
document.getElementById('flarum-loading').style.display = 'none';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
flarum.core.app.load(data);
|
app.load(data);
|
||||||
flarum.core.app.bootExtensions(flarum.extensions);
|
app.bootExtensions(flarum.extensions);
|
||||||
flarum.core.app.boot();
|
app.boot();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var error = document.getElementById('flarum-loading-error');
|
var error = document.getElementById('flarum-loading-error');
|
||||||
error.innerHTML += document.getElementById('flarum-content').textContent;
|
error.innerHTML += document.getElementById('flarum-content').textContent;
|
||||||
|
|
|
@ -6,7 +6,7 @@ module.exports = (options = {}) => ({
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.[tj]sx?$': [
|
'^.+\\.[tj]sx?$': [
|
||||||
'babel-jest',
|
'babel-jest',
|
||||||
require('flarum-webpack-config/babel.config.js'),
|
require('flarum-webpack-config/babel.config.cjs'),
|
||||||
],
|
],
|
||||||
'^.+\\.tsx?$': [
|
'^.+\\.tsx?$': [
|
||||||
'ts-jest',
|
'ts-jest',
|
||||||
|
|
|
@ -31,27 +31,3 @@ Add another build script to your `package.json` like the one below:
|
||||||
You'll need to configure a `tsconfig.json` file to ensure your IDE sets up Typescript support correctly.
|
You'll need to configure a `tsconfig.json` file to ensure your IDE sets up Typescript support correctly.
|
||||||
|
|
||||||
For details about this, see the [`flarum/flarum-tsconfig` repository](https://github.com/flarum/flarum-tsconfig)
|
For details about this, see the [`flarum/flarum-tsconfig` repository](https://github.com/flarum/flarum-tsconfig)
|
||||||
|
|
||||||
## Options
|
|
||||||
|
|
||||||
### `useExtensions`
|
|
||||||
|
|
||||||
`Array<string>`, defaults to `[]`.
|
|
||||||
|
|
||||||
An array of extensions whose modules should be made available. This is a shortcut to add [`externals`](https://webpack.js.org/configuration/externals/) configuration for extension modules. Imported extension modules will not be bundled, but will instead refer to the extension's exports included in the Flarum runtime (ie. `flarum.extensions["vendor/package"]`).
|
|
||||||
|
|
||||||
For example, to access the Tags extension module within your extension:
|
|
||||||
|
|
||||||
**forum.js**
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { Tag } from '@flarum/tags/forum';
|
|
||||||
```
|
|
||||||
|
|
||||||
**webpack.config.js**
|
|
||||||
|
|
||||||
```js
|
|
||||||
module.exports = config({
|
|
||||||
useExtensions: ['flarum/tags'],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "flarum-webpack-config",
|
"name": "flarum-webpack-config",
|
||||||
|
"type": "module",
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"description": "Webpack config for Flarum JS and TS transpilation.",
|
"description": "Webpack config for Flarum JS and TS transpilation.",
|
||||||
"main": "index.js",
|
"main": "src/index.cjs",
|
||||||
"author": "Flarum Team",
|
"author": "Flarum Team",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"prettier": "@flarum/prettier-config",
|
"prettier": "@flarum/prettier-config",
|
||||||
|
@ -21,13 +22,18 @@
|
||||||
"@babel/preset-typescript": "^7.18.6",
|
"@babel/preset-typescript": "^7.18.6",
|
||||||
"@babel/runtime": "^7.20.1",
|
"@babel/runtime": "^7.20.1",
|
||||||
"babel-loader": "^9.1.0",
|
"babel-loader": "^9.1.0",
|
||||||
|
"loader-utils": "^1.4.0",
|
||||||
|
"schema-utils": "^3.0.0",
|
||||||
"typescript": "^4.9.3",
|
"typescript": "^4.9.3",
|
||||||
"webpack": "^5.76.0",
|
"webpack": "^5.76.0",
|
||||||
"webpack-bundle-analyzer": "^4.7.0"
|
"webpack-bundle-analyzer": "^4.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^2.8.0",
|
"@flarum/prettier-config": "^1.0.0",
|
||||||
"@flarum/prettier-config": "^1.0.0"
|
"babel-jest": "^29.5.0",
|
||||||
|
"jest": "^29.5.0",
|
||||||
|
"memfs": "^3.5.3",
|
||||||
|
"prettier": "^2.8.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "echo 'skipping..'",
|
"dev": "echo 'skipping..'",
|
||||||
|
@ -39,6 +45,10 @@
|
||||||
"build-typings": "echo 'skipping..'",
|
"build-typings": "echo 'skipping..'",
|
||||||
"post-build-typings": "echo 'skipping..'",
|
"post-build-typings": "echo 'skipping..'",
|
||||||
"check-typings": "echo 'skipping..'",
|
"check-typings": "echo 'skipping..'",
|
||||||
"check-typings-coverage": "echo 'skipping..'"
|
"check-typings-coverage": "echo 'skipping..'",
|
||||||
|
"test": "jest"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"testEnvironment": "node"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
185
js-packages/webpack-config/src/autoExportLoader.cjs
Normal file
185
js-packages/webpack-config/src/autoExportLoader.cjs
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/**
|
||||||
|
* Auto Export Loader
|
||||||
|
*
|
||||||
|
* This loader will automatically pick up all core and extension exports and add them to the registry.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const { validate } = require('schema-utils');
|
||||||
|
const { getOptions, interpolateName } = require('loader-utils');
|
||||||
|
|
||||||
|
const optionsSchema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
extension: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let namespace;
|
||||||
|
|
||||||
|
function addAutoExports(source, pathToModule, moduleName) {
|
||||||
|
let addition = '';
|
||||||
|
|
||||||
|
const defaultExportMatches = [...source.matchAll(/export\s+?default\s(?:abstract\s)?(?:(?:function|abstract|class)\s)?([A-Za-z_]*)/gm)];
|
||||||
|
const defaultExport = defaultExportMatches.length ? defaultExportMatches[0][1] : null;
|
||||||
|
|
||||||
|
// In case of an index.js file that exports multiple modules
|
||||||
|
// we need to add the directory as a module.
|
||||||
|
// For an example checkout the `common/extenders/index.js` file.
|
||||||
|
if (moduleName === 'index') {
|
||||||
|
const id = pathToModule.substring(0, pathToModule.length - 1);
|
||||||
|
|
||||||
|
// Add code at the end of the file to add the file to registry
|
||||||
|
addition += `\nflarum.reg.add('${namespace}', '${id}', ${defaultExport})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In a normal case, we do one of two things:
|
||||||
|
else {
|
||||||
|
// 1. If there is a default export, we add the module to the registry with the default export.
|
||||||
|
// Example: `export default class Foo {}` will be added to the registry as `Foo`,
|
||||||
|
// and can be imported using `import Foo from 'flarum/../Foo'`.
|
||||||
|
if (defaultExport) {
|
||||||
|
// Add code at the end of the file to add the file to registry
|
||||||
|
addition += `\nflarum.reg.add('${namespace}', '${pathToModule}${moduleName}', ${defaultExport})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. If there is no default export, then there are named exports,
|
||||||
|
// so we add the module to the registry with the map of named exports.
|
||||||
|
// Example: `export class Foo {}` will be added to the registry as `{ Foo: 'Foo' }`,
|
||||||
|
// and can be imported using `import { Foo } from 'flarum/../Foo'`,
|
||||||
|
// (checkout the `common/utils/string.ts` file for an example).
|
||||||
|
else {
|
||||||
|
// Another two case scenarios is when using `export { A, B } from 'x'`.
|
||||||
|
// 2.1. If there is a default export, we add the module to the registry with the default export and ignore the named exports.
|
||||||
|
// Example: `export { nanoid as default, x } from 'nanoid'` will be added to the registry as `nanoid`,
|
||||||
|
// and can be imported using `import nanoid from 'flarum/../nanoid'`. x will be ignored.
|
||||||
|
const objectExportWithDefaultMatches = [...source.matchAll(/export\s+?{.*as\s+?default.*}\s+?from\s+?['"](.*)['"]/gm)];
|
||||||
|
|
||||||
|
if (objectExportWithDefaultMatches.length) {
|
||||||
|
let objectDefaultExport = null;
|
||||||
|
|
||||||
|
source = source.replace(/export\s+?{\s?([A-z_0-9]*)\s?as\s+?default.*}\s+?from\s+?['"](.*)['"]/gm, (match, defaultExport, path) => {
|
||||||
|
objectDefaultExport = defaultExport;
|
||||||
|
|
||||||
|
return `import { ${defaultExport} } from '${path}';\nexport default ${defaultExport}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
addition += `\nflarum.reg.add('${namespace}', '${pathToModule}${moduleName}', ${objectDefaultExport})`;
|
||||||
|
}
|
||||||
|
// 2.2. If there is no default export, check for direct exports from other modules.
|
||||||
|
// We add the module to the registry with the map of named exports.
|
||||||
|
// Example: `export { A, B } from 'nanoid'` will be added to the registry as `{ A, B }`,
|
||||||
|
// and can be imported using `import { A, B } from 'flarum/../nanoid'`.
|
||||||
|
else {
|
||||||
|
const exportCurlyPattern = /export\s+?{(.*)}\s+?from\s+?['"](.*)['"]/gm;
|
||||||
|
const namedExportMatches = [...source.matchAll(exportCurlyPattern)];
|
||||||
|
|
||||||
|
if (namedExportMatches.length) {
|
||||||
|
source = source.replaceAll(exportCurlyPattern, (match, names, path) => {
|
||||||
|
return names
|
||||||
|
.split(',')
|
||||||
|
.map((name) => `import { ${name} } from '${path}';\nexport { ${name} }`)
|
||||||
|
.join('\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Addition to the registry is taken care of in step 2.3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.3. Finally, we check for all named exports
|
||||||
|
// these can be `export function|class|.. Name ..`
|
||||||
|
// or `export { ... };
|
||||||
|
{
|
||||||
|
const matches = [...source.matchAll(/export\s+?(?:\* as|function|{\s*([A-z0-9, ]+)+\s?}|const|abstract\s?|class)+?\s?([A-Za-z_]*)?/gm)];
|
||||||
|
|
||||||
|
if (matches.length) {
|
||||||
|
const map = matches.reduce((map, match) => {
|
||||||
|
const names = match[1] ? match[1].split(',') : (match[2] ? [match[2]] : null);
|
||||||
|
|
||||||
|
if (!names) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let name of names) {
|
||||||
|
name = name.trim();
|
||||||
|
|
||||||
|
if (name === 'interface' || name === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
map += `${name}: ${name},`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}, '');
|
||||||
|
|
||||||
|
// Add code at the end of the file to add the file to registry
|
||||||
|
if (map) addition += `\nflarum.reg.add('${namespace}', '${pathToModule}${moduleName}', { ${map} })`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return source + addition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom loader logic
|
||||||
|
module.exports = function autoExportLoader(source) {
|
||||||
|
const options = getOptions(this) || {};
|
||||||
|
|
||||||
|
validate(optionsSchema, options, {
|
||||||
|
name: 'Flarum Webpack Loader',
|
||||||
|
composerPath: 'Path to the extension composer.json file',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure that composer.json is watched for changes
|
||||||
|
// so that the loader is run again when composer.json
|
||||||
|
// is updated.
|
||||||
|
const composerJsonPath = path.resolve(options.composerPath || '../composer.json');
|
||||||
|
this.addDependency(composerJsonPath);
|
||||||
|
|
||||||
|
// Get the namespace of the module to be exported
|
||||||
|
// the namespace is essentially just the usual extension ID.
|
||||||
|
if (!namespace) {
|
||||||
|
const composerJson = JSON.parse(fs.readFileSync(composerJsonPath, 'utf8'));
|
||||||
|
|
||||||
|
// Get the value of the 'name' property
|
||||||
|
namespace =
|
||||||
|
composerJson.name === 'flarum/core' ? 'core' : composerJson.name.replace('/flarum-ext-', '-').replace('/flarum-', '').replace('/', '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the type of the module to be exported
|
||||||
|
const location = interpolateName(this, '[folder]/', {
|
||||||
|
context: this.rootContext || this.context,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the name of module to be exported
|
||||||
|
const moduleName = interpolateName(this, '[name]', {
|
||||||
|
context: this.rootContext || this.context,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Don't export low level files
|
||||||
|
if ((/(admin|forum)\/$/.test(location) && moduleName !== 'app') || /(compat|ExportRegistry|registry)$/.test(moduleName)) {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't export index.js of common
|
||||||
|
if (moduleName === 'index' && location === 'common/') {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't export extend.js of extensions
|
||||||
|
if (namespace !== 'core' && /extend$/.test(moduleName)) {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the path of the module to be exported
|
||||||
|
// relative to the src directory.
|
||||||
|
// Example: src/forum/components/UserCard.js => forum/components
|
||||||
|
const pathToModule = this.resourcePath.replace(path.resolve(this.rootContext, 'src') + '/', '').replace(/[A-Za-z_]+\.[A-Za-z_]+$/, '');
|
||||||
|
|
||||||
|
return addAutoExports(source, pathToModule, moduleName);
|
||||||
|
};
|
|
@ -55,7 +55,7 @@ if (useBundleAnalyzer) {
|
||||||
plugins.push(new (require('webpack-bundle-analyzer').BundleAnalyzerPlugin)());
|
plugins.push(new (require('webpack-bundle-analyzer').BundleAnalyzerPlugin)());
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function (options = {}) {
|
module.exports = function () {
|
||||||
return {
|
return {
|
||||||
// Set up entry points for each of the forum + admin apps, but only
|
// Set up entry points for each of the forum + admin apps, but only
|
||||||
// if they exist.
|
// if they exist.
|
||||||
|
@ -69,12 +69,15 @@ module.exports = function (options = {}) {
|
||||||
|
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
{
|
||||||
|
include: /src/, // Only apply this loader to files in the src directory
|
||||||
|
loader: path.resolve(__dirname, './autoExportLoader.cjs'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Matches .js, .jsx, .ts, .tsx
|
// Matches .js, .jsx, .ts, .tsx
|
||||||
// See: https://regexr.com/5snjd
|
|
||||||
test: /\.[jt]sx?$/,
|
test: /\.[jt]sx?$/,
|
||||||
loader: require.resolve('babel-loader'),
|
loader: require.resolve('babel-loader'),
|
||||||
options: require('./babel.config'),
|
options: require('../babel.config.cjs'),
|
||||||
resolve: {
|
resolve: {
|
||||||
fullySpecified: false,
|
fullySpecified: false,
|
||||||
},
|
},
|
||||||
|
@ -91,33 +94,24 @@ module.exports = function (options = {}) {
|
||||||
|
|
||||||
externals: [
|
externals: [
|
||||||
{
|
{
|
||||||
'@flarum/core/forum': 'flarum.core',
|
|
||||||
'@flarum/core/admin': 'flarum.core',
|
|
||||||
jquery: 'jQuery',
|
jquery: 'jQuery',
|
||||||
},
|
},
|
||||||
|
|
||||||
(function () {
|
|
||||||
const externals = {};
|
|
||||||
|
|
||||||
if (options.useExtensions) {
|
|
||||||
for (const extension of options.useExtensions) {
|
|
||||||
externals['@' + extension] =
|
|
||||||
externals['@' + extension + '/forum'] =
|
|
||||||
externals['@' + extension + '/admin'] =
|
|
||||||
"flarum.extensions['" + extension + "']";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return externals;
|
|
||||||
})(),
|
|
||||||
|
|
||||||
// Support importing old-style core modules.
|
|
||||||
function ({ request }, callback) {
|
function ({ request }, callback) {
|
||||||
|
let namespace;
|
||||||
|
let id;
|
||||||
let matches;
|
let matches;
|
||||||
if ((matches = /^flarum\/(.+)$/.exec(request))) {
|
if ((matches = /^flarum\/(.+)$/.exec(request))) {
|
||||||
return callback(null, "root flarum.core.compat['" + matches[1] + "']");
|
namespace = 'core';
|
||||||
|
id = matches[1];
|
||||||
|
} else if ((matches = /^ext:([^\/]+)\/(?:flarum-(?:ext-)?)?([^\/]+)(?:\/(.+))?$/.exec(request))) {
|
||||||
|
namespace = `${matches[1]}-${matches[2]}`;
|
||||||
|
id = matches[3];
|
||||||
|
} else {
|
||||||
|
return callback();
|
||||||
}
|
}
|
||||||
callback();
|
|
||||||
|
return callback(null, `root flarum.reg.get('${namespace}', '${id}')`);
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
54
js-packages/webpack-config/tests/autoExportLoader.test.js
Normal file
54
js-packages/webpack-config/tests/autoExportLoader.test.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* @jest-environment node
|
||||||
|
*/
|
||||||
|
import compiler from './compiler.js';
|
||||||
|
import 'regenerator-runtime/runtime';
|
||||||
|
|
||||||
|
const compile = async (path, useFinalOutput = false) => {
|
||||||
|
const stats = await compiler(path);
|
||||||
|
return useFinalOutput
|
||||||
|
? stats.finalOutput
|
||||||
|
: stats.toJson({
|
||||||
|
source: true,
|
||||||
|
}).modules[0].source;
|
||||||
|
};
|
||||||
|
|
||||||
|
test('A directory with index.js that exports multiple modules adds the directory as a module', async () => {
|
||||||
|
let output = await compile('src/common/bars/index.js', true);
|
||||||
|
expect(output).toContain("flarum.reg.add('flarum-framework', 'common/bars', bars)");
|
||||||
|
|
||||||
|
output = await compile('src/common/bars/Acme.js');
|
||||||
|
expect(output).toContain("flarum.reg.add('flarum-framework', 'common/bars/Acme', Acme)");
|
||||||
|
|
||||||
|
output = await compile('src/common/bars/Foo.js');
|
||||||
|
expect(output).toContain("flarum.reg.add('flarum-framework', 'common/bars/Foo', Foo)");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Simple default exports are added', async () => {
|
||||||
|
const output = await compile('src/common/Test.js');
|
||||||
|
expect(output).toContain("flarum.reg.add('flarum-framework', 'common/Test', Test)");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Named exports are added', async () => {
|
||||||
|
const output = await compile('src/common/foos/namedExports.js');
|
||||||
|
expect(output).toContain(
|
||||||
|
"flarum.reg.add('flarum-framework', 'common/foos/namedExports', { baz: baz,foo: foo,Bar: Bar,sasha: sasha,flarum: flarum,david: david, })"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Export as default from another module is added', async () => {
|
||||||
|
const output = await compile('src/common/foos/exportDefaultFrom.js', true);
|
||||||
|
expect(output).toContain("flarum.reg.add('flarum-framework', 'common/foos/exportDefaultFrom', potato");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Export from other modules is added', async () => {
|
||||||
|
const output = await compile('src/common/foos/exportFrom.js', true);
|
||||||
|
expect(output).toContain("flarum.reg.add('flarum-framework', 'common/foos/exportFrom', { potato: potato,franz: franz, }");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Export from with other named exports works', async () => {
|
||||||
|
const output = await compile('src/common/foos/exportFromWithNamedExports.js', true);
|
||||||
|
expect(output).toContain(
|
||||||
|
"flarum.reg.add('flarum-framework', 'common/foos/exportFromWithNamedExports', { potato: potato,franz: franz,baz: baz,foo: foo,Bar: Bar,sasha: sasha,forum: forum,david: david, }"
|
||||||
|
);
|
||||||
|
});
|
48
js-packages/webpack-config/tests/compiler.js
Normal file
48
js-packages/webpack-config/tests/compiler.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import path from 'path';
|
||||||
|
import webpack from 'webpack';
|
||||||
|
import { createFsFromVolume, Volume } from 'memfs';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
export default (fixture, options = {}) => {
|
||||||
|
const compiler = webpack({
|
||||||
|
context: __dirname,
|
||||||
|
entry: `./${fixture}`,
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname),
|
||||||
|
filename: 'bundle.js',
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
use: {
|
||||||
|
loader: path.resolve(__dirname, '../src/autoExportLoader.cjs'),
|
||||||
|
options: {
|
||||||
|
...options,
|
||||||
|
composerPath: '../../composer.json',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
minimize: false,
|
||||||
|
minimizer: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
compiler.outputFileSystem = createFsFromVolume(new Volume());
|
||||||
|
compiler.outputFileSystem.join = path.join.bind(path);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
compiler.run((err, stats) => {
|
||||||
|
if (err) reject(err);
|
||||||
|
if (stats.hasErrors()) reject(stats.toJson().errors);
|
||||||
|
|
||||||
|
const outputFilepath = path.join(compiler.options.output.path, compiler.options.output.filename);
|
||||||
|
stats.finalOutput = compiler.outputFileSystem.readFileSync(outputFilepath, 'utf-8');
|
||||||
|
|
||||||
|
resolve(stats);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
1
js-packages/webpack-config/tests/src/common/Test.js
Normal file
1
js-packages/webpack-config/tests/src/common/Test.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export default class Test {}
|
1
js-packages/webpack-config/tests/src/common/bars/Acme.js
Normal file
1
js-packages/webpack-config/tests/src/common/bars/Acme.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export default class Acme {}
|
1
js-packages/webpack-config/tests/src/common/bars/Foo.js
Normal file
1
js-packages/webpack-config/tests/src/common/bars/Foo.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export default class Foo {}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import Acme from './Acme.js';
|
||||||
|
import Foo from './Foo.js';
|
||||||
|
|
||||||
|
const bars = {
|
||||||
|
Acme,
|
||||||
|
Foo,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default bars;
|
|
@ -0,0 +1 @@
|
||||||
|
export { potato as default } from '../support/potato.js';
|
|
@ -0,0 +1 @@
|
||||||
|
export { potato, franz } from '../support/potato.js';
|
|
@ -0,0 +1,16 @@
|
||||||
|
export { potato, franz } from '../support/potato.js';
|
||||||
|
|
||||||
|
export function baz() {}
|
||||||
|
|
||||||
|
export function foo() {}
|
||||||
|
|
||||||
|
export class Bar {}
|
||||||
|
|
||||||
|
const sasha = 'camel';
|
||||||
|
|
||||||
|
export { sasha };
|
||||||
|
|
||||||
|
const forum = 'Flarum';
|
||||||
|
const david = 'david';
|
||||||
|
|
||||||
|
export { forum, david };
|
|
@ -0,0 +1,14 @@
|
||||||
|
export function baz() {}
|
||||||
|
|
||||||
|
export function foo() {}
|
||||||
|
|
||||||
|
export class Bar {}
|
||||||
|
|
||||||
|
const sasha = 'camel';
|
||||||
|
|
||||||
|
export { sasha };
|
||||||
|
|
||||||
|
const flarum = 'Flarum';
|
||||||
|
const david = 'david';
|
||||||
|
|
||||||
|
export { flarum, david };
|
|
@ -0,0 +1,4 @@
|
||||||
|
const potato = 'potato';
|
||||||
|
const franz = 'franz';
|
||||||
|
|
||||||
|
export { potato, franz };
|
Loading…
Reference in New Issue
Block a user