Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix global typings for extensions #2992

Merged
merged 14 commits into from
Aug 19, 2021
53 changes: 0 additions & 53 deletions js/@types/global/index.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@
"format": "prettier --write src",
"format-check": "prettier --check src",
"clean-typings": "npx rimraf dist-typings && mkdir dist-typings",
"build-typings": "npm run clean-typings && cp -r @types dist-typings/@types && tsc"
"build-typings": "npm run clean-typings && cp -r src/@types dist-typings/@types && tsc"
}
}
82 changes: 82 additions & 0 deletions js/src/@types/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* @deprecated Please import `app` from a namespace instead of using it as a global variable.
*
* @example App in forum JS
* ```
* import app from 'flarum/forum/app';
* ```
*
* @example App in admin JS
* ```
* import app from 'flarum/admin/app';
* ```
*
* @example App in common JS
* ```
* import app from 'flarum/common/app';
* ```
*/
declare const app: never;

declare const m: import('mithril').Static;
declare const dayjs: typeof import('dayjs');

type ESModule = { __esModule: true; [key: string]: unknown };

/**
* The global `flarum` variable.
*
* Contains the compiled ES Modules for all Flarum extensions and core.
*
* @example <caption>Check if `flarum-tags` is present</captions>
* if ('flarum-tags' in flarum.extensions) {
* // Tags is installed and enabled!
* }
*/
interface FlarumObject {
/**
* Contains the compiled ES Module for Flarum's core.
*
* You shouldn't need to access this directly for any reason.
*/
core: Readonly<ESModule>;
/**
* Contains the compiled ES Modules for all Flarum extensions.
*
* @example <caption>Check if `flarum-tags` is present</captions>
* if ('flarum-tags' in flarum.extensions) {
* // Tags is installed and enabled!
* }
*/
extensions: Readonly<Record<string, ESModule>>;
}

declare const flarum: FlarumObject;

// Extend JQuery with our custom functions, defined with $.fn
interface JQuery {
/**
* Flarum's tooltip JQuery plugin.
*
* Do not use this directly. Instead use the `<Tooltip>` component that
* is exported from `flarum/common/components/Tooltip`.
*
* This will be removed in a future version of Flarum.
*
* @deprecated
*/
tooltip: import('./tooltips/index').TooltipJQueryFunction;
davwheat marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* For more info, see: https://www.typescriptlang.org/docs/handbook/jsx.html#attribute-type-checking
*
* In a nutshell, we need to add `ElementAttributesProperty` to tell Typescript
* what property on component classes to look at for attribute typings. For our
* Component class, this would be `attrs` (e.g. `this.attrs...`)
*/
interface JSX {
ElementAttributesProperty: {
attrs: Record<string, unknown>;
};
}
File renamed without changes.
1 change: 1 addition & 0 deletions js/src/admin/components/AdminNav.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import ExtensionLinkButton from './ExtensionLinkButton';
import Component from '../../common/Component';
import LinkButton from '../../common/components/LinkButton';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/AdminPage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Page from '../../common/components/Page';
import Button from '../../common/components/Button';
import Switch from '../../common/components/Switch';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/AppearancePage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Button from '../../common/components/Button';
import EditCustomCssModal from './EditCustomCssModal';
import EditCustomHeaderModal from './EditCustomHeaderModal';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/BasicsPage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import FieldSet from '../../common/components/FieldSet';
import ItemList from '../../common/utils/ItemList';
import AdminPage from './AdminPage';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/DashboardPage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import StatusWidget from './StatusWidget';
import ExtensionsWidget from './ExtensionsWidget';
import ItemList from '../../common/utils/ItemList';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/EditCustomCssModal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import SettingsModal from './SettingsModal';

export default class EditCustomCssModal extends SettingsModal {
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/EditCustomFooterModal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import SettingsModal from './SettingsModal';

export default class EditCustomFooterModal extends SettingsModal {
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/EditCustomHeaderModal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import SettingsModal from './SettingsModal';

export default class EditCustomHeaderModal extends SettingsModal {
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/EditGroupModal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Modal from '../../common/components/Modal';
import Button from '../../common/components/Button';
import Badge from '../../common/components/Badge';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/ExtensionLinkButton.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import isExtensionEnabled from '../utils/isExtensionEnabled';
import LinkButton from '../../common/components/LinkButton';
import icon from '../../common/helpers/icon';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/ExtensionPage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Button from '../../common/components/Button';
import Link from '../../common/components/Link';
import LinkButton from '../../common/components/LinkButton';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/ExtensionPermissionGrid.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import PermissionGrid from './PermissionGrid';
import Button from '../../common/components/Button';
import ItemList from '../../common/utils/ItemList';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/ExtensionsWidget.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import DashboardWidget from './DashboardWidget';
import isExtensionEnabled from '../utils/isExtensionEnabled';
import getCategorizedExtensions from '../utils/getCategorizedExtensions';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/HeaderSecondary.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Component from '../../common/Component';
import LinkButton from '../../common/components/LinkButton';
import SessionDropdown from './SessionDropdown';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/LoadingModal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Modal from '../../common/components/Modal';

export default class LoadingModal extends Modal {
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/MailPage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import FieldSet from '../../common/components/FieldSet';
import Button from '../../common/components/Button';
import Alert from '../../common/components/Alert';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/PermissionDropdown.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Dropdown from '../../common/components/Dropdown';
import Button from '../../common/components/Button';
import Separator from '../../common/components/Separator';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/PermissionGrid.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Component from '../../common/Component';
import PermissionDropdown from './PermissionDropdown';
import SettingDropdown from './SettingDropdown';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/PermissionsPage.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import GroupBadge from '../../common/components/GroupBadge';
import EditGroupModal from './EditGroupModal';
import Group from '../../common/models/Group';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/SessionDropdown.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import avatar from '../../common/helpers/avatar';
import username from '../../common/helpers/username';
import Dropdown from '../../common/components/Dropdown';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/SettingDropdown.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import SelectDropdown from '../../common/components/SelectDropdown';
import Button from '../../common/components/Button';
import saveSettings from '../utils/saveSettings';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/SettingsModal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Modal from '../../common/components/Modal';
import Button from '../../common/components/Button';
import Stream from '../../common/utils/Stream';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/StatusWidget.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import DashboardWidget from './DashboardWidget';
import listItems from '../../common/helpers/listItems';
import ItemList from '../../common/utils/ItemList';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/components/UploadImageButton.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import Button from '../../common/components/Button';

export default class UploadImageButton extends Button {
Expand Down
2 changes: 2 additions & 0 deletions js/src/admin/components/UserListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import app from '../../admin/app';

import EditUserModal from '../../common/components/EditUserModal';
import LoadingIndicator from '../../common/components/LoadingIndicator';
import Button from '../../common/components/Button';
Expand Down
1 change: 1 addition & 0 deletions js/src/admin/resolvers/ExtensionPageResolver.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../admin/app';
import DefaultResolver from '../../common/resolvers/DefaultResolver';

/**
Expand Down
2 changes: 2 additions & 0 deletions js/src/admin/utils/getCategorizedExtensions.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import app from '../../admin/app';

export default function getCategorizedExtensions() {
let extensions = {};

Expand Down
2 changes: 2 additions & 0 deletions js/src/admin/utils/isExtensionEnabled.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import app from '../../admin/app';

export default function isExtensionEnabled(name) {
const enabled = JSON.parse(app.data.settings.extensions_enabled);

Expand Down
2 changes: 2 additions & 0 deletions js/src/admin/utils/saveSettings.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import app from '../../admin/app';

export default function saveSettings(settings) {
const oldSettings = JSON.parse(JSON.stringify(app.data.settings));

Expand Down
2 changes: 2 additions & 0 deletions js/src/common/Application.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import app from '../common/app';

import ItemList from './utils/ItemList';
import Button from './components/Button';
import ModalManager from './components/ModalManager';
Expand Down
2 changes: 1 addition & 1 deletion js/src/common/Component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as Mithril from 'mithril';
import type Mithril from 'mithril';

export interface ComponentAttrs extends Mithril.Attributes {}

Expand Down
2 changes: 1 addition & 1 deletion js/src/common/Fragment.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as Mithril from 'mithril';
import type Mithril from 'mithril';

/**
* The `Fragment` class represents a chunk of DOM that is rendered once with Mithril and then takes
Expand Down
2 changes: 2 additions & 0 deletions js/src/common/Model.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import app from '../common/app';

/**
* The `Model` class represents a local data resource. It provides methods to
* persist changes via the API.
Expand Down
2 changes: 2 additions & 0 deletions js/src/common/Session.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import app from '../common/app';

/**
* The `Session` class defines the current user session. It stores a reference
* to the current authenticated user, and provides methods to log in/out.
Expand Down
1 change: 1 addition & 0 deletions js/src/common/Store.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../common/app';
/**
* The `Store` class defines a local data store, and provides methods to
* retrieve data from the API.
Expand Down
31 changes: 31 additions & 0 deletions js/src/common/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type Application from './Application';

// Used to fix typings
const w = window as any;

/**
* Proxy app. Common JS is run first, at which point `window.app` is not
* set as this is done by the namespaced JS.
*
* When the corrent value is set, this code would retain the reference to
* the original invalid value.
*
* By using a proxy, we can ensure that our `window.app` value is always
* up-to-date with the latest reference.
*/
const appProxy = new Proxy(
{},
{
get(_, properties) {
return Reflect.get(w.app, properties, w.app);
},
set(_, properties, value) {
return Reflect.set(w.app, properties, value, w.app);
},
}
);

/**
* The instance of Application within the common namespace.
*/
export default appProxy as Application;
2 changes: 1 addition & 1 deletion js/src/common/components/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Component, { ComponentAttrs } from '../Component';
import Button from './Button';
import listItems from '../helpers/listItems';
import extract from '../utils/extract';
import Mithril from 'mithril';
import type Mithril from 'mithril';

export interface AlertAttrs extends ComponentAttrs {
/** The type of alert this is. Will be used to give the alert a class name of `Alert--{type}`. */
Expand Down
1 change: 1 addition & 0 deletions js/src/common/components/Dropdown.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../common/app';
import Component from '../Component';
import icon from '../helpers/icon';
import listItems from '../helpers/listItems';
Expand Down
1 change: 1 addition & 0 deletions js/src/common/components/EditUserModal.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../common/app';
import Modal from './Modal';
import Button from './Button';
import GroupBadge from './GroupBadge';
Expand Down
1 change: 1 addition & 0 deletions js/src/common/components/LoadingIndicator.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../common/app';
import Component, { ComponentAttrs } from '../Component';
import classList from '../utils/classList';

Expand Down
1 change: 1 addition & 0 deletions js/src/common/components/Navigation.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../common/app';
import Component from '../Component';
import Button from './Button';
import LinkButton from './LinkButton';
Expand Down
1 change: 1 addition & 0 deletions js/src/common/components/Page.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import app from '../../common/app';
import Component from '../Component';
import PageState from '../states/PageState';

Expand Down
Loading