mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-12-24 16:10:30 +00:00
[chore] Convert some settings / admin panel JS to TypeScript (#2247)
* initial conversion of STUFF to typescript * more stuff * update babel deps, include commonjs transform * update bundler & eslint configuration * eslint --fix * upgrade deps * update docs, build stuff, peripheral stuff --------- Co-authored-by: f0x <f0x@cthu.lu>
This commit is contained in:
parent
6e508830e1
commit
d173fcdfa3
84 changed files with 2365 additions and 1621 deletions
11
.drone.yml
11
.drone.yml
|
@ -53,8 +53,7 @@ steps:
|
|||
- name: yarn_cache
|
||||
path: /tmp/cache
|
||||
commands:
|
||||
- cd web/source
|
||||
- yarn --frozen-lockfile --cache-folder /tmp/cache
|
||||
- yarn --cwd ./web/source install --frozen-lockfile --cache-folder /tmp/cache
|
||||
|
||||
- name: web-lint
|
||||
image: node:18-alpine
|
||||
|
@ -65,8 +64,7 @@ steps:
|
|||
depends_on:
|
||||
- web-setup
|
||||
commands:
|
||||
- cd web/source
|
||||
- yarn run lint
|
||||
- yarn --cwd ./web/source lint
|
||||
|
||||
- name: web-build
|
||||
image: node:18-alpine
|
||||
|
@ -77,8 +75,7 @@ steps:
|
|||
depends_on:
|
||||
- web-setup
|
||||
commands:
|
||||
- cd web/source
|
||||
- yarn run build
|
||||
- yarn --cwd ./web/source build
|
||||
|
||||
- name: snapshot
|
||||
image: superseriousbusiness/gotosocial-drone-build:0.3.0 # https://github.com/superseriousbusiness/gotosocial-drone-build
|
||||
|
@ -194,6 +191,6 @@ steps:
|
|||
|
||||
---
|
||||
kind: signature
|
||||
hmac: 74653d67ed44ceefb7e19d6125d4a457e6308b5ef627df6325d72a0cc7d7cc0a
|
||||
hmac: c3efbd528a76016562f88ae435141cfb5fd6d4d07b6ad2a24ecc23cb529cc1c6
|
||||
|
||||
...
|
||||
|
|
|
@ -6,9 +6,9 @@ before:
|
|||
# generate the swagger.yaml file using go-swagger and bundle it into the assets directory
|
||||
- swagger generate spec --scan-models --exclude-deps -o web/assets/swagger.yaml
|
||||
- sed -i "s/REPLACE_ME/{{ incpatch .Version }}/" web/assets/swagger.yaml
|
||||
# bundle web assets
|
||||
- yarn install --cwd web/source
|
||||
- scripts/bundle.sh
|
||||
# Install web deps + bundle web assets
|
||||
- yarn --cwd ./web/source install
|
||||
- yarn --cwd ./web/source build
|
||||
builds:
|
||||
# https://goreleaser.com/customization/build/
|
||||
-
|
||||
|
|
|
@ -226,31 +226,44 @@ To bundle changes, you need [Node.js](https://nodejs.org/en/download/) and [Yarn
|
|||
|
||||
Using [NVM](https://github.com/nvm-sh/nvm) is one convenient way to install them which also supports managing different Node versions.
|
||||
|
||||
To install Yarn dependencies:
|
||||
To install frontend dependencies:
|
||||
|
||||
```bash
|
||||
yarn install --cwd web/source
|
||||
yarn --cwd web/source
|
||||
```
|
||||
|
||||
To recompile bundles:
|
||||
To recompile frontend bundles into `web/assets/dist`:
|
||||
|
||||
```bash
|
||||
node web/source
|
||||
yarn --cwd web/source build
|
||||
```
|
||||
|
||||
#### Live Reloading
|
||||
|
||||
For a more convenient development environment, you can run a livereloading version of the bundler alongside the [testrig](#testing).
|
||||
|
||||
Open two terminals, first start the testrig on port 8081:
|
||||
First build the GtS binary with DEBUG=1 to enable the testrig:
|
||||
|
||||
``` bash
|
||||
GTS_PORT=8081 go run ./cmd/gotosocial testrig start
|
||||
DEBUG=1 ./scripts/build.sh
|
||||
```
|
||||
|
||||
Now open two terminals.
|
||||
|
||||
In the first terminal, run the testrig on port 8081, using the binary you just built:
|
||||
|
||||
```bash
|
||||
DEBUG=1 GTS_PORT=8081 ./gotosocial testrig start
|
||||
```
|
||||
|
||||
Then start the bundler, which will run on port 8080, and proxy requests to the testrig instance where needed.
|
||||
|
||||
``` bash
|
||||
NODE_ENV=development node web/source
|
||||
NODE_ENV=development yarn --cwd ./web/source dev
|
||||
```
|
||||
|
||||
You can then log in to the GoToSocial settings panel at `http://localhost:8080/settings` and see your changes reflected in real time as the dev bundler reloads.
|
||||
|
||||
The livereloading bundler *will not* change the bundled assets in `dist/`, so once you are finished with changes and want to deploy it somewhere, you have to run `node web/source` to generate production-ready bundles.
|
||||
|
||||
### Project Structure
|
||||
|
|
|
@ -12,12 +12,12 @@ WORKDIR /go/src/github.com/superseriousbusiness/gotosocial
|
|||
RUN swagger generate spec -o /go/src/github.com/superseriousbusiness/gotosocial/swagger.yaml --scan-models
|
||||
|
||||
# stage 2: generate the web/assets/dist bundles
|
||||
FROM --platform=${BUILDPLATFORM} node:16.19.1-alpine3.17 AS bundler
|
||||
FROM --platform=${BUILDPLATFORM} node:18-alpine AS bundler
|
||||
|
||||
COPY web web
|
||||
RUN yarn install --cwd web/source && \
|
||||
BUDO_BUILD=1 node web/source && \
|
||||
rm -r web/source
|
||||
RUN yarn --cwd ./web/source install && \
|
||||
yarn --cwd ./web/source build && \
|
||||
rm -rf ./web/source
|
||||
|
||||
# stage 3: build the executor container
|
||||
FROM --platform=${TARGETPLATFORM} alpine:3.17.2 as executor
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# this script is really just here because GoReleaser doesn't let
|
||||
# you set env vars in your 'before' commands in the free version
|
||||
|
||||
set -eu
|
||||
|
||||
BUDO_BUILD=1 node web/source
|
|
@ -17,13 +17,15 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": ["@joepie91/eslint-config/react"],
|
||||
"plugins": ["license-header"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint", "license-header"],
|
||||
"rules": {
|
||||
"license-header/header": ["error", __dirname + "/.license-header.js"],
|
||||
"no-console": 'error'
|
||||
},
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
}
|
||||
};
|
3
web/source/.gitignore
vendored
3
web/source/.gitignore
vendored
|
@ -1,2 +1,5 @@
|
|||
node_modules
|
||||
public/bundle.*
|
||||
|
||||
# Built/Typescript-compiled settings files.
|
||||
settings-js
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Photoswipe = require("photoswipe/dist/umd/photoswipe.umd.min.js");
|
||||
const PhotoswipeLightbox = require("photoswipe/dist/umd/photoswipe-lightbox.umd.min.js");
|
||||
const PhotoswipeCaptionPlugin = require("photoswipe-dynamic-caption-plugin").default;
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const skulk = require("skulk");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
@ -70,10 +68,17 @@ skulk({
|
|||
entryFile: "settings",
|
||||
outputFile: "settings.js",
|
||||
prodCfg: prodCfg,
|
||||
plugin: [
|
||||
// Additional settings for TS are passed from tsconfig.json.
|
||||
// See: https://github.com/TypeStrong/tsify#tsconfigjson
|
||||
["tsify"]
|
||||
],
|
||||
transform: [
|
||||
// tsify is called before babelify, so we're just babelifying
|
||||
// commonjs here, no need for the typescript preset.
|
||||
["babelify", {
|
||||
global: true,
|
||||
ignore: [/node_modules\/(?!nanoid)/]
|
||||
ignore: [/node_modules\/(?!nanoid)/],
|
||||
}]
|
||||
],
|
||||
presets: [
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"author": "f0x",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"lint": "eslint . --ext .js,.jsx",
|
||||
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
||||
"build": "node index.js",
|
||||
"dev": "NODE_ENV=development node index.js"
|
||||
},
|
||||
|
@ -29,21 +29,25 @@
|
|||
"psl": "^1.9.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-redux": "^8.0.4",
|
||||
"react-redux": "^8.1.3",
|
||||
"redux": "^4.2.0",
|
||||
"redux-persist": "^6.0.0",
|
||||
"skulk": "^0.0.6",
|
||||
"skulk": "^0.0.8-fix",
|
||||
"split-filter-n": "^1.1.3",
|
||||
"syncpipe": "^1.0.0",
|
||||
"wouter": "^2.8.0-alpha.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.6",
|
||||
"@babel/preset-env": "^7.19.4",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/core": "^7.23.0",
|
||||
"@babel/preset-env": "^7.22.20",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@babel/preset-typescript": "^7.23.0",
|
||||
"@browserify/envify": "^6.0.0",
|
||||
"@browserify/uglifyify": "^6.0.0",
|
||||
"@joepie91/eslint-config": "^1.1.1",
|
||||
"@types/react-dom": "^18.2.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.4",
|
||||
"@typescript-eslint/parser": "^6.7.4",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"babelify": "^10.0.0",
|
||||
"css-extract": "^2.0.0",
|
||||
|
@ -56,6 +60,10 @@
|
|||
"postcss": "^8.4.18",
|
||||
"postcss-custom-prop-vars": "^0.0.5",
|
||||
"postcss-import": "^15.0.0",
|
||||
"postcss-nested": "^6.0.0"
|
||||
"postcss-nested": "^6.0.0",
|
||||
"source-map-loader": "^4.0.1",
|
||||
"ts-loader": "^9.4.4",
|
||||
"tsify": "^5.0.4",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { useRoute, Redirect } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Switch, Route, Link } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../../../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const ExpireRemote = require("./expireremote");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../../../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const Cleanup = require("./cleanup");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const splitFilterN = require("split-filter-n");
|
||||
const syncpipe = require('syncpipe');
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { useRoute, Link, Redirect } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Switch, Route } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../../../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Link } = require("wouter");
|
||||
const syncpipe = require("syncpipe");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../../../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const ParseFromToot = require("./parse-from-toot");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../../../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { useRoute, Redirect, useLocation } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
module.exports = function ExportFormatTable() {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../../../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Switch, Route, Redirect, useLocation } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../../../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Switch, Route } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Link, useLocation } = require("wouter");
|
||||
const { matchSorter } = require("match-sorter");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { useRoute, Redirect } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Link, Switch, Route } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Link } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Switch, Route, Link, Redirect, useRoute } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,23 +17,25 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
import { useVerifyCredentialsQuery } from "../../lib/query/oauth";
|
||||
import { store } from "../../redux/store";
|
||||
|
||||
const React = require("react");
|
||||
const Redux = require("react-redux");
|
||||
import React from "react";
|
||||
|
||||
const query = require("../../lib/query");
|
||||
import Login from "./login";
|
||||
import Loading from "../loading";
|
||||
import { Error } from "../error";
|
||||
|
||||
const Login = require("./login");
|
||||
const Loading = require("../loading");
|
||||
const { Error } = require("../error");
|
||||
export function Authorization({ App }) {
|
||||
const { loginState, expectingRedirect } = store.getState().oauth;
|
||||
const skip = (loginState == "none" || loginState == "logout" || expectingRedirect);
|
||||
|
||||
module.exports = function Authorization({ App }) {
|
||||
const { loginState, expectingRedirect } = Redux.useSelector((state) => state.oauth);
|
||||
|
||||
const { isLoading, isSuccess, data: account, error } = query.useVerifyCredentialsQuery(undefined, {
|
||||
skip: loginState == "none" || loginState == "logout" || expectingRedirect
|
||||
});
|
||||
const {
|
||||
isLoading,
|
||||
isSuccess,
|
||||
data: account,
|
||||
error,
|
||||
} = useVerifyCredentialsQuery(null, { skip: skip });
|
||||
|
||||
let showLogin = true;
|
||||
let content = null;
|
||||
|
@ -73,4 +75,4 @@ module.exports = function Authorization({ App }) {
|
|||
</section>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -17,18 +17,16 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
import React from "react";
|
||||
|
||||
const React = require("react");
|
||||
import { useAuthorizeFlowMutation } from "../../lib/query/oauth";
|
||||
import { useTextInput, useValue } from "../../lib/form";
|
||||
import useFormSubmit from "../../lib/form/submit";
|
||||
import { TextInput } from "../form/inputs";
|
||||
import MutationButton from "../form/mutation-button";
|
||||
import Loading from "../loading";
|
||||
|
||||
const query = require("../../lib/query");
|
||||
const { useTextInput, useValue } = require("../../lib/form");
|
||||
const useFormSubmit = require("../../lib/form/submit");
|
||||
const { TextInput } = require("../form/inputs");
|
||||
const MutationButton = require("../form/mutation-button");
|
||||
const Loading = require("../loading");
|
||||
|
||||
module.exports = function Login({ }) {
|
||||
export default function Login({ }) {
|
||||
const form = {
|
||||
instance: useTextInput("instance", {
|
||||
defaultValue: window.location.origin
|
||||
|
@ -38,8 +36,11 @@ module.exports = function Login({ }) {
|
|||
|
||||
const [formSubmit, result] = useFormSubmit(
|
||||
form,
|
||||
query.useAuthorizeFlowMutation(),
|
||||
{ changedOnly: false }
|
||||
useAuthorizeFlowMutation(),
|
||||
{
|
||||
changedOnly: false,
|
||||
onFinish: undefined,
|
||||
}
|
||||
);
|
||||
|
||||
if (result.isLoading) {
|
||||
|
@ -63,7 +64,11 @@ module.exports = function Login({ }) {
|
|||
label="Instance"
|
||||
name="instance"
|
||||
/>
|
||||
<MutationButton label="Login" result={result} />
|
||||
<MutationButton
|
||||
label="Login"
|
||||
result={result}
|
||||
disabled={false}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
}
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Link } = require("wouter");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
module.exports = function CheckList({ field, header = "All", EntryComponent, getExtraProps }) {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
function ErrorFallback({ error, resetErrorBoundary }) {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
module.exports = function FakeProfile({ avatar, header, display_name, username, role }) {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
function TextInput({ label, field, ...inputProps }) {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Error } = require("../error");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const langs = require("langs");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
module.exports = function Loading() {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../lib/query");
|
||||
|
|
|
@ -17,17 +17,15 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const ReactDom = require("react-dom/client");
|
||||
const { Provider } = require("react-redux");
|
||||
const { PersistGate } = require("redux-persist/integration/react");
|
||||
|
||||
const { store, persistor } = require("./redux");
|
||||
const { store, persistor } = require("./redux/store");
|
||||
const { createNavigation, Menu, Item } = require("./lib/navigation");
|
||||
|
||||
const AuthorizationGate = require("./components/authorization");
|
||||
const { Authorization } = require("./components/authorization");
|
||||
const Loading = require("./components/loading");
|
||||
const UserLogoutCard = require("./components/user-logout-card");
|
||||
const { RoleContext } = require("./lib/navigation/util");
|
||||
|
@ -90,7 +88,7 @@ function Main() {
|
|||
return (
|
||||
<Provider store={store}>
|
||||
<PersistGate loading={<section><Loading /></section>} persistor={persistor}>
|
||||
<AuthorizationGate App={App} />
|
||||
<Authorization App={App} />
|
||||
</PersistGate>
|
||||
</Provider>
|
||||
);
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const isValidDomain = require("is-valid-domain");
|
||||
const psl = require("psl");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const _default = false;
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const syncpipe = require("syncpipe");
|
||||
const { createSlice } = require("@reduxjs/toolkit");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const { useComboboxState } = require("ariakit/combobox");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const FormContext = React.createContext({});
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const getFormMutations = require("./get-form-mutations");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const prettierBytes = require("prettier-bytes");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Error } = require("../../components/error");
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const syncpipe = require("syncpipe");
|
||||
|
||||
module.exports = function getFormMutations(form, { changedOnly }) {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const getByDot = require("get-by-dot").default;
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const _default = "";
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Promise = require("bluebird");
|
||||
const React = require("react");
|
||||
const getFormMutations = require("./get-form-mutations");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const _default = "";
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { Link, Route, Redirect, Switch, useLocation, useRouter } = require("wouter");
|
||||
const syncpipe = require("syncpipe");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const { nanoid } = require("nanoid");
|
||||
const { Redirect } = require("wouter");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
const RoleContext = React.createContext([]);
|
||||
const BaseUrlContext = React.createContext(null);
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Promise = require("bluebird");
|
||||
|
||||
const { unwrapRes } = require("../lib");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Promise = require("bluebird");
|
||||
const fileDownload = require("js-file-download");
|
||||
const csv = require("papaparse");
|
||||
|
|
|
@ -17,15 +17,13 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
replaceCacheOnMutation,
|
||||
removeFromCacheOnMutation,
|
||||
domainListToObject,
|
||||
idListToObject
|
||||
} = require("../lib");
|
||||
const base = require("../base");
|
||||
const { gtsApi } = require("../gts-api");
|
||||
|
||||
const endpoints = (build) => ({
|
||||
updateInstance: build.mutation({
|
||||
|
@ -164,4 +162,4 @@ const endpoints = (build) => ({
|
|||
...require("./reports")(build)
|
||||
});
|
||||
|
||||
module.exports = base.injectEndpoints({ endpoints });
|
||||
module.exports = gtsApi.injectEndpoints({ endpoints });
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = (build) => ({
|
||||
listReports: build.query({
|
||||
query: (params = {}) => ({
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { createApi, fetchBaseQuery } = require("@reduxjs/toolkit/query/react");
|
||||
const { serialize: serializeForm } = require("object-to-formdata");
|
||||
|
||||
function instanceBasedQuery(args, api, extraOptions) {
|
||||
const state = api.getState();
|
||||
const { instance, token } = state.oauth;
|
||||
|
||||
if (args.baseUrl == undefined) {
|
||||
args.baseUrl = instance;
|
||||
}
|
||||
|
||||
if (args.discardEmpty) {
|
||||
if (args.body == undefined || Object.keys(args.body).length == 0) {
|
||||
return { data: null };
|
||||
}
|
||||
delete args.discardEmpty;
|
||||
}
|
||||
|
||||
if (args.asForm) {
|
||||
delete args.asForm;
|
||||
args.body = serializeForm(args.body, {
|
||||
indices: true, // Array indices, for profile fields
|
||||
});
|
||||
}
|
||||
|
||||
return fetchBaseQuery({
|
||||
baseUrl: args.baseUrl,
|
||||
prepareHeaders: (headers) => {
|
||||
if (token != undefined) {
|
||||
headers.set('Authorization', token);
|
||||
}
|
||||
headers.set("Accept", "application/json");
|
||||
return headers;
|
||||
},
|
||||
})(args, api, extraOptions);
|
||||
}
|
||||
|
||||
module.exports = createApi({
|
||||
reducerPath: "api",
|
||||
baseQuery: instanceBasedQuery,
|
||||
tagTypes: ["Auth", "Emoji", "Reports", "Account", "InstanceRules"],
|
||||
endpoints: (build) => ({
|
||||
instance: build.query({
|
||||
query: () => ({
|
||||
url: `/api/v1/instance`
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
149
web/source/settings/lib/query/gts-api.ts
Normal file
149
web/source/settings/lib/query/gts-api.ts
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
||||
import type {
|
||||
BaseQueryFn,
|
||||
FetchArgs,
|
||||
FetchBaseQueryError,
|
||||
} from '@reduxjs/toolkit/query/react';
|
||||
import { serialize as serializeForm } from "object-to-formdata";
|
||||
|
||||
import type { RootState } from '../../redux/store';
|
||||
|
||||
/**
|
||||
* GTSFetchArgs extends standard FetchArgs used by
|
||||
* RTK Query with a couple helpers of our own.
|
||||
*/
|
||||
export interface GTSFetchArgs extends FetchArgs {
|
||||
/**
|
||||
* If provided, will be used as base URL. Else,
|
||||
* will fall back to authorized instance as baseUrl.
|
||||
*/
|
||||
baseUrl?: string;
|
||||
/**
|
||||
* If true, and no args.body is set, or args.body is empty,
|
||||
* then a null response will be returned from the API call.
|
||||
*/
|
||||
discardEmpty?: boolean;
|
||||
/**
|
||||
* If true, then args.body will be serialized
|
||||
* as FormData before submission.
|
||||
*/
|
||||
asForm?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtsBaseQuery wraps the redux toolkit fetchBaseQuery with some helper functionality.
|
||||
*
|
||||
* For an explainer of what's happening in this function, see:
|
||||
* - https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#customizing-queries-with-basequery
|
||||
* - https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#constructing-a-dynamic-base-url-using-redux-state
|
||||
*
|
||||
* @param args
|
||||
* @param api
|
||||
* @param extraOptions
|
||||
* @returns
|
||||
*/
|
||||
const gtsBaseQuery: BaseQueryFn<
|
||||
string | GTSFetchArgs,
|
||||
any,
|
||||
FetchBaseQueryError
|
||||
> = async (args, api, extraOptions) => {
|
||||
// Retrieve state at the moment
|
||||
// this function was called.
|
||||
const state = api.getState() as RootState;
|
||||
const { instanceUrl, token } = state.oauth;
|
||||
|
||||
// Derive baseUrl dynamically.
|
||||
let baseUrl: string;
|
||||
|
||||
// Check if simple string baseUrl provided
|
||||
// as args, or if more complex args provided.
|
||||
if (typeof args === "string") {
|
||||
baseUrl = args;
|
||||
} else {
|
||||
if (args.baseUrl != undefined) {
|
||||
baseUrl = args.baseUrl;
|
||||
} else {
|
||||
baseUrl = instanceUrl;
|
||||
}
|
||||
|
||||
if (args.discardEmpty) {
|
||||
if (args.body == undefined || Object.keys(args.body).length == 0) {
|
||||
return { data: null };
|
||||
}
|
||||
}
|
||||
|
||||
if (args.asForm) {
|
||||
args.body = serializeForm(args.body, {
|
||||
// Array indices, for profile fields.
|
||||
indices: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Delete any of our extended arguments
|
||||
// to avoid confusing fetchBaseQuery.
|
||||
delete args.baseUrl;
|
||||
delete args.discardEmpty;
|
||||
delete args.asForm;
|
||||
}
|
||||
|
||||
if (!baseUrl) {
|
||||
return {
|
||||
error: {
|
||||
status: 400,
|
||||
statusText: 'Bad Request',
|
||||
data: {"error":"No baseUrl set for request"},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return fetchBaseQuery({
|
||||
baseUrl: baseUrl,
|
||||
prepareHeaders: (headers) => {
|
||||
if (token != undefined) {
|
||||
headers.set('Authorization', token);
|
||||
}
|
||||
headers.set("Accept", "application/json");
|
||||
return headers;
|
||||
},
|
||||
})(args, api, extraOptions);
|
||||
};
|
||||
|
||||
export const gtsApi = createApi({
|
||||
reducerPath: "api",
|
||||
baseQuery: gtsBaseQuery,
|
||||
tagTypes: [
|
||||
"Auth",
|
||||
"Emoji",
|
||||
"Reports",
|
||||
"Account",
|
||||
"InstanceRules",
|
||||
],
|
||||
endpoints: (builder) => ({
|
||||
instance: builder.query<any, void>({
|
||||
query: () => ({
|
||||
url: `/api/v1/instance`
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
export const { useInstanceQuery } = gtsApi;
|
|
@ -17,11 +17,9 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
...require("./base"),
|
||||
...require("./gts-api"),
|
||||
...require("./oauth"),
|
||||
...require("./user"),
|
||||
...require("./admin")
|
||||
};
|
||||
};
|
||||
|
|
|
@ -17,10 +17,8 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const syncpipe = require("syncpipe");
|
||||
const base = require("./base");
|
||||
const { gtsApi } = require("./gts-api");
|
||||
|
||||
module.exports = {
|
||||
unwrapRes(res) {
|
||||
|
@ -70,7 +68,7 @@ function makeCacheMutation(action) {
|
|||
return {
|
||||
onQueryStarted: (_, { dispatch, queryFulfilled }) => {
|
||||
queryFulfilled.then(({ data: newData }) => {
|
||||
dispatch(base.util.updateQueryData(queryName, arg, (draft) => {
|
||||
dispatch(gtsApi.util.updateQueryData(queryName, arg, (draft) => {
|
||||
if (findKey != undefined) {
|
||||
key = findKey(draft, newData);
|
||||
}
|
||||
|
|
|
@ -1,160 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Promise = require("bluebird");
|
||||
|
||||
const base = require("./base");
|
||||
const { unwrapRes } = require("./lib");
|
||||
const oauth = require("../../redux/oauth").actions;
|
||||
|
||||
function getSettingsURL() {
|
||||
/* needed in case the settings interface isn't hosted at /settings but
|
||||
some subpath like /gotosocial/settings. Other parts of the code don't
|
||||
take this into account yet so mostly future-proofing.
|
||||
|
||||
Also drops anything past /settings/, because authorization urls that are too long
|
||||
get rejected by GTS.
|
||||
*/
|
||||
let [pre, _past] = window.location.pathname.split("/settings");
|
||||
return `${window.location.origin}${pre}/settings`;
|
||||
}
|
||||
|
||||
const SETTINGS_URL = getSettingsURL();
|
||||
|
||||
const endpoints = (build) => ({
|
||||
verifyCredentials: build.query({
|
||||
providesTags: (_res, error) =>
|
||||
error == undefined
|
||||
? ["Auth"]
|
||||
: [],
|
||||
queryFn: (_arg, api, _extraOpts, baseQuery) => {
|
||||
const state = api.getState();
|
||||
|
||||
return Promise.try(() => {
|
||||
// Process callback code first, if available
|
||||
if (state.oauth.loginState == "callback") {
|
||||
let urlParams = new URLSearchParams(window.location.search);
|
||||
let code = urlParams.get("code");
|
||||
|
||||
if (code == undefined) {
|
||||
throw {
|
||||
message: "Waiting for callback, but no ?code= provided in url."
|
||||
};
|
||||
} else {
|
||||
let app = state.oauth.registration;
|
||||
|
||||
if (app == undefined || app.client_id == undefined) {
|
||||
throw {
|
||||
message: "No stored registration data, can't finish login flow."
|
||||
};
|
||||
}
|
||||
|
||||
return baseQuery({
|
||||
method: "POST",
|
||||
url: "/oauth/token",
|
||||
body: {
|
||||
client_id: app.client_id,
|
||||
client_secret: app.client_secret,
|
||||
redirect_uri: SETTINGS_URL,
|
||||
grant_type: "authorization_code",
|
||||
code: code
|
||||
}
|
||||
}).then(unwrapRes).then((token) => {
|
||||
// remove ?code= from url
|
||||
window.history.replaceState({}, document.title, window.location.pathname);
|
||||
api.dispatch(oauth.setToken(token));
|
||||
});
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
return baseQuery({
|
||||
url: `/api/v1/accounts/verify_credentials`
|
||||
});
|
||||
}).catch((e) => {
|
||||
return { error: e };
|
||||
});
|
||||
}
|
||||
}),
|
||||
authorizeFlow: build.mutation({
|
||||
queryFn: (formData, api, _extraOpts, baseQuery) => {
|
||||
let instance;
|
||||
const state = api.getState();
|
||||
|
||||
return Promise.try(() => {
|
||||
if (!formData.instance.startsWith("http")) {
|
||||
formData.instance = `https://${formData.instance}`;
|
||||
}
|
||||
instance = new URL(formData.instance).origin;
|
||||
|
||||
const stored = state.oauth.instance;
|
||||
if (stored?.instance == instance && stored.registration) {
|
||||
return stored.registration;
|
||||
}
|
||||
|
||||
return baseQuery({
|
||||
method: "POST",
|
||||
baseUrl: instance,
|
||||
url: "/api/v1/apps",
|
||||
body: {
|
||||
client_name: "GoToSocial Settings",
|
||||
scopes: formData.scopes,
|
||||
redirect_uris: SETTINGS_URL,
|
||||
website: SETTINGS_URL
|
||||
}
|
||||
}).then(unwrapRes).then((app) => {
|
||||
app.scopes = formData.scopes;
|
||||
|
||||
api.dispatch(oauth.authorize({
|
||||
instance: instance,
|
||||
registration: app,
|
||||
loginState: "callback",
|
||||
expectingRedirect: true
|
||||
}));
|
||||
|
||||
return app;
|
||||
});
|
||||
}).then((app) => {
|
||||
let url = new URL(instance);
|
||||
url.pathname = "/oauth/authorize";
|
||||
url.searchParams.set("client_id", app.client_id);
|
||||
url.searchParams.set("redirect_uri", SETTINGS_URL);
|
||||
url.searchParams.set("response_type", "code");
|
||||
url.searchParams.set("scope", app.scopes);
|
||||
|
||||
let redirectURL = url.toString();
|
||||
window.location.assign(redirectURL);
|
||||
|
||||
return { data: null };
|
||||
}).catch((e) => {
|
||||
return { error: e };
|
||||
});
|
||||
},
|
||||
}),
|
||||
logout: build.mutation({
|
||||
queryFn: (_arg, api) => {
|
||||
api.dispatch(oauth.remove());
|
||||
return { data: null };
|
||||
},
|
||||
invalidatesTags: ["Auth"]
|
||||
})
|
||||
});
|
||||
|
||||
module.exports = base.injectEndpoints({ endpoints });
|
204
web/source/settings/lib/query/oauth/index.ts
Normal file
204
web/source/settings/lib/query/oauth/index.ts
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import type { FetchBaseQueryError } from '@reduxjs/toolkit/query';
|
||||
|
||||
import { gtsApi } from "../gts-api";
|
||||
import {
|
||||
setToken as oauthSetToken,
|
||||
remove as oauthRemove,
|
||||
authorize as oauthAuthorize,
|
||||
} from "../../../redux/oauth";
|
||||
import { RootState } from '../../../redux/store';
|
||||
|
||||
export interface OauthTokenRequestBody {
|
||||
client_id: string;
|
||||
client_secret: string;
|
||||
redirect_uri: string;
|
||||
grant_type: string;
|
||||
code: string;
|
||||
}
|
||||
|
||||
function getSettingsURL() {
|
||||
/*
|
||||
needed in case the settings interface isn't hosted at /settings but
|
||||
some subpath like /gotosocial/settings. Other parts of the code don't
|
||||
take this into account yet so mostly future-proofing.
|
||||
|
||||
Also drops anything past /settings/, because authorization urls that are too long
|
||||
get rejected by GTS.
|
||||
*/
|
||||
let [pre, _past] = window.location.pathname.split("/settings");
|
||||
return `${window.location.origin}${pre}/settings`;
|
||||
}
|
||||
|
||||
const SETTINGS_URL = (getSettingsURL());
|
||||
|
||||
// Couple auth functions here require multiple requests as
|
||||
// part of an OAuth token 'flow'. To keep things simple for
|
||||
// callers of these query functions, the multiple requests
|
||||
// are chained within one query.
|
||||
//
|
||||
// https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#performing-multiple-requests-with-a-single-query
|
||||
const extended = gtsApi.injectEndpoints({
|
||||
endpoints: (builder) => ({
|
||||
verifyCredentials: builder.query<any, void>({
|
||||
providesTags: (_res, error) =>
|
||||
error == undefined ? ["Auth"] : [],
|
||||
async queryFn(_arg, api, _extraOpts, fetchWithBQ) {
|
||||
const state = api.getState() as RootState;
|
||||
const oauthState = state.oauth;
|
||||
|
||||
// If we're not in the middle of an auth/callback,
|
||||
// we may already have an auth token, so just
|
||||
// return a standard verify_credentials query.
|
||||
if (oauthState.loginState != 'callback') {
|
||||
return fetchWithBQ({
|
||||
url: `/api/v1/accounts/verify_credentials`
|
||||
});
|
||||
}
|
||||
|
||||
// We're in the middle of an auth/callback flow.
|
||||
// Try to retrieve callback code from URL query.
|
||||
let urlParams = new URLSearchParams(window.location.search);
|
||||
let code = urlParams.get("code");
|
||||
if (code == undefined) {
|
||||
return {
|
||||
error: {
|
||||
status: 400,
|
||||
statusText: 'Bad Request',
|
||||
data: {"error":"Waiting for callback, but no ?code= provided in url."},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Retrieve app with which the
|
||||
// callback code was generated.
|
||||
let app = oauthState.app;
|
||||
if (app == undefined || app.client_id == undefined) {
|
||||
return {
|
||||
error: {
|
||||
status: 400,
|
||||
statusText: 'Bad Request',
|
||||
data: {"error":"No stored app registration data, can't finish login flow."},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Use the provided code and app
|
||||
// secret to request an auth token.
|
||||
const tokenReqBody: OauthTokenRequestBody = {
|
||||
client_id: app.client_id,
|
||||
client_secret: app.client_secret,
|
||||
redirect_uri: SETTINGS_URL,
|
||||
grant_type: "authorization_code",
|
||||
code: code
|
||||
};
|
||||
|
||||
const tokenResult = await fetchWithBQ({
|
||||
method: "POST",
|
||||
url: "/oauth/token",
|
||||
body: tokenReqBody,
|
||||
});
|
||||
if (tokenResult.error) {
|
||||
return { error: tokenResult.error as FetchBaseQueryError };
|
||||
}
|
||||
|
||||
// Remove ?code= query param from
|
||||
// url, we don't want it anymore.
|
||||
window.history.replaceState({}, document.title, window.location.pathname);
|
||||
|
||||
// Store returned token in redux.
|
||||
api.dispatch(oauthSetToken(tokenResult.data));
|
||||
|
||||
// We're now authed! So return
|
||||
// standard verify_credentials query.
|
||||
return fetchWithBQ({
|
||||
url: `/api/v1/accounts/verify_credentials`
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
authorizeFlow: builder.mutation({
|
||||
async queryFn(formData, api, _extraOpts, fetchWithBQ) {
|
||||
const state = api.getState() as RootState;
|
||||
const oauthState = state.oauth;
|
||||
|
||||
let instanceUrl: string;
|
||||
if (!formData.instance.startsWith("http")) {
|
||||
formData.instance = `https://${formData.instance}`;
|
||||
}
|
||||
|
||||
instanceUrl = new URL(formData.instance).origin;
|
||||
if (oauthState?.instanceUrl == instanceUrl && oauthState.app) {
|
||||
return { data: oauthState.app };
|
||||
}
|
||||
|
||||
const appResult = await fetchWithBQ({
|
||||
method: "POST",
|
||||
baseUrl: instanceUrl,
|
||||
url: "/api/v1/apps",
|
||||
body: {
|
||||
client_name: "GoToSocial Settings",
|
||||
scopes: formData.scopes,
|
||||
redirect_uris: SETTINGS_URL,
|
||||
website: SETTINGS_URL
|
||||
}
|
||||
});
|
||||
if (appResult.error) {
|
||||
return { error: appResult.error as FetchBaseQueryError };
|
||||
}
|
||||
|
||||
let app = appResult.data as any;
|
||||
|
||||
app.scopes = formData.scopes;
|
||||
api.dispatch(oauthAuthorize({
|
||||
instanceUrl: instanceUrl,
|
||||
app: app,
|
||||
loginState: "callback",
|
||||
expectingRedirect: true
|
||||
}));
|
||||
|
||||
let url = new URL(instanceUrl);
|
||||
url.pathname = "/oauth/authorize";
|
||||
url.searchParams.set("client_id", app.client_id);
|
||||
url.searchParams.set("redirect_uri", SETTINGS_URL);
|
||||
url.searchParams.set("response_type", "code");
|
||||
url.searchParams.set("scope", app.scopes);
|
||||
|
||||
let redirectURL = url.toString();
|
||||
window.location.assign(redirectURL);
|
||||
return { data: null };
|
||||
},
|
||||
}),
|
||||
logout: builder.mutation({
|
||||
queryFn: (_arg, api) => {
|
||||
api.dispatch(oauthRemove());
|
||||
return { data: null };
|
||||
},
|
||||
invalidatesTags: ["Auth"]
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
export const {
|
||||
useVerifyCredentialsQuery,
|
||||
useAuthorizeFlowMutation,
|
||||
useLogoutMutation,
|
||||
} = extended;
|
|
@ -17,29 +17,32 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
import { replaceCacheOnMutation } from "../lib";
|
||||
import { gtsApi } from "../gts-api";
|
||||
|
||||
const { replaceCacheOnMutation } = require("./lib");
|
||||
const base = require("./base");
|
||||
|
||||
const endpoints = (build) => ({
|
||||
updateCredentials: build.mutation({
|
||||
query: (formData) => ({
|
||||
method: "PATCH",
|
||||
url: `/api/v1/accounts/update_credentials`,
|
||||
asForm: true,
|
||||
body: formData,
|
||||
discardEmpty: true
|
||||
const extended = gtsApi.injectEndpoints({
|
||||
endpoints: (builder) => ({
|
||||
updateCredentials: builder.mutation({
|
||||
query: (formData) => ({
|
||||
method: "PATCH",
|
||||
url: `/api/v1/accounts/update_credentials`,
|
||||
asForm: true,
|
||||
body: formData,
|
||||
discardEmpty: true
|
||||
}),
|
||||
...replaceCacheOnMutation("verifyCredentials")
|
||||
}),
|
||||
...replaceCacheOnMutation("verifyCredentials")
|
||||
}),
|
||||
passwordChange: build.mutation({
|
||||
query: (data) => ({
|
||||
method: "POST",
|
||||
url: `/api/v1/user/password_change`,
|
||||
body: data
|
||||
passwordChange: builder.mutation({
|
||||
query: (data) => ({
|
||||
method: "POST",
|
||||
url: `/api/v1/user/password_change`,
|
||||
body: data
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
module.exports = base.injectEndpoints({ endpoints });
|
||||
export const {
|
||||
useUpdateCredentialsMutation,
|
||||
usePasswordChangeMutation,
|
||||
} = extended;
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { createSlice } = require("@reduxjs/toolkit");
|
||||
|
||||
module.exports = createSlice({
|
||||
name: "oauth",
|
||||
initialState: {
|
||||
loginState: 'none',
|
||||
expectingRedirect: false
|
||||
},
|
||||
reducers: {
|
||||
authorize: (state, { payload }) => {
|
||||
return payload; // overrides state
|
||||
},
|
||||
setToken: (state, { payload }) => {
|
||||
state.token = `${payload.token_type} ${payload.access_token}`;
|
||||
state.loginState = "login";
|
||||
},
|
||||
remove: (state, { _payload }) => {
|
||||
delete state.token;
|
||||
delete state.registration;
|
||||
state.loginState = "logout";
|
||||
}
|
||||
}
|
||||
});
|
89
web/source/settings/redux/oauth.ts
Normal file
89
web/source/settings/redux/oauth.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
||||
|
||||
/**
|
||||
* OAuthToken represents a response
|
||||
* to an OAuth token request.
|
||||
*/
|
||||
export interface OAuthToken {
|
||||
/**
|
||||
* Most likely to be 'Bearer'
|
||||
* but may be something else.
|
||||
*/
|
||||
token_type: string;
|
||||
/**
|
||||
* The actual token. Can be passed in to
|
||||
* authenticate further requests using the
|
||||
* Authorization header and the token type.
|
||||
*/
|
||||
access_token: string;
|
||||
}
|
||||
|
||||
export interface OAuthApp {
|
||||
client_id: string;
|
||||
client_secret: string;
|
||||
}
|
||||
|
||||
export interface OAuthState {
|
||||
instanceUrl?: string;
|
||||
loginState: "none" | "callback" | "login" | "logout";
|
||||
expectingRedirect: boolean;
|
||||
/**
|
||||
* Token stored in easy-to-use format.
|
||||
* Will look something like:
|
||||
* "Authorization: Bearer BLAHBLAHBLAH"
|
||||
*/
|
||||
token?: string;
|
||||
app?: OAuthApp;
|
||||
}
|
||||
|
||||
const initialState: OAuthState = {
|
||||
loginState: 'none',
|
||||
expectingRedirect: false,
|
||||
};
|
||||
|
||||
export const oauthSlice = createSlice({
|
||||
name: "oauth",
|
||||
initialState: initialState,
|
||||
reducers: {
|
||||
authorize: (_state, action: PayloadAction<OAuthState>) => {
|
||||
// Overrides state with payload.
|
||||
return action.payload;
|
||||
},
|
||||
setToken: (state, action: PayloadAction<OAuthToken>) => {
|
||||
// Mark us as logged in by storing token.
|
||||
state.token = `${action.payload.token_type} ${action.payload.access_token}`;
|
||||
state.loginState = "login";
|
||||
},
|
||||
remove: (state) => {
|
||||
// Mark us as logged out by clearing auth.
|
||||
delete state.token;
|
||||
delete state.app;
|
||||
state.loginState = "logout";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const {
|
||||
authorize,
|
||||
setToken,
|
||||
remove,
|
||||
} = oauthSlice.actions;
|
|
@ -17,11 +17,9 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { combineReducers } = require("redux");
|
||||
const { configureStore } = require("@reduxjs/toolkit");
|
||||
const {
|
||||
import { combineReducers } from "redux";
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import {
|
||||
persistStore,
|
||||
persistReducer,
|
||||
FLUSH,
|
||||
|
@ -30,14 +28,14 @@ const {
|
|||
PERSIST,
|
||||
PURGE,
|
||||
REGISTER,
|
||||
} = require("redux-persist");
|
||||
} from "redux-persist";
|
||||
|
||||
const query = require("../lib/query/base");
|
||||
const { Promise } = require("bluebird");
|
||||
import { oauthSlice } from "./oauth";
|
||||
import { gtsApi } from "../lib/query/gts-api";
|
||||
|
||||
const combinedReducers = combineReducers({
|
||||
oauth: require("./oauth").reducer,
|
||||
[query.reducerPath]: query.reducer
|
||||
[gtsApi.reducerPath]: gtsApi.reducer,
|
||||
oauth: oauthSlice.reducer,
|
||||
});
|
||||
|
||||
const persistedReducer = persistReducer({
|
||||
|
@ -45,27 +43,41 @@ const persistedReducer = persistReducer({
|
|||
storage: require("redux-persist/lib/storage").default,
|
||||
stateReconciler: require("redux-persist/lib/stateReconciler/autoMergeLevel1").default,
|
||||
whitelist: ["oauth"],
|
||||
migrate: (state) => {
|
||||
return Promise.try(() => {
|
||||
if (state?.oauth != undefined) {
|
||||
state.oauth.expectingRedirect = false;
|
||||
}
|
||||
migrate: async (state) => {
|
||||
if (state == undefined) {
|
||||
return state;
|
||||
});
|
||||
}
|
||||
|
||||
// This is a cheeky workaround for
|
||||
// redux-persist being a stickler.
|
||||
let anyState = state as any;
|
||||
if (anyState?.oauth != undefined) {
|
||||
anyState.oauth.expectingRedirect = false;
|
||||
}
|
||||
|
||||
return anyState;
|
||||
}
|
||||
}, combinedReducers);
|
||||
|
||||
const store = configureStore({
|
||||
export const store = configureStore({
|
||||
reducer: persistedReducer,
|
||||
middleware: (getDefaultMiddleware) => {
|
||||
return getDefaultMiddleware({
|
||||
serializableCheck: {
|
||||
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
|
||||
ignoredActions: [
|
||||
FLUSH,
|
||||
REHYDRATE,
|
||||
PAUSE,
|
||||
PERSIST,
|
||||
PURGE,
|
||||
REGISTER,
|
||||
]
|
||||
}
|
||||
}).concat(query.middleware);
|
||||
}).concat(gtsApi.middleware);
|
||||
}
|
||||
});
|
||||
|
||||
const persistor = persistStore(store);
|
||||
export const persistor = persistStore(store);
|
||||
|
||||
module.exports = { store, persistor };
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../lib/query");
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("react");
|
||||
|
||||
const query = require("../lib/query");
|
||||
|
|
109
web/source/tsconfig.json
Normal file
109
web/source/tsconfig.json
Normal file
|
@ -0,0 +1,109 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
"jsx": "react" , /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
"noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": false, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
2753
web/source/yarn.lock
2753
web/source/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue