Simplify ESLint dev dependencies and config, drop JSX syntax, use .mjs files.

This commit is contained in:
Jayden Seric 2022-05-20 11:00:12 +10:00
parent 32ac135165
commit 4a6bb2c992
27 changed files with 597 additions and 5400 deletions

View File

@ -1,3 +1,30 @@
{ {
"extends": ["env"] "extends": ["eslint:recommended"],
"env": {
"es2022": true,
"node": true
},
"parserOptions": {
"ecmaVersion": "latest"
},
"plugins": ["simple-import-sort"],
"rules": {
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error"
},
"overrides": [
{
"files": ["*.mjs"],
"parserOptions": {
"sourceType": "module"
},
"globals": {
"__dirname": "off",
"__filename": "off",
"exports": "off",
"module": "off",
"require": "off"
}
}
]
} }

2386
api/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -30,12 +30,7 @@
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.15.0", "eslint": "^8.15.0",
"eslint-config-env": "^23.0.2", "eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsdoc": "^37.9.7",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"nodemon": "^2.0.16", "nodemon": "^2.0.16",
"prettier": "^2.6.2" "prettier": "^2.6.2"
}, },

View File

@ -1,4 +1,5 @@
import { GraphQLNonNull, GraphQLObjectType, GraphQLString } from "graphql"; import { GraphQLNonNull, GraphQLObjectType, GraphQLString } from "graphql";
import UPLOAD_DIRECTORY_URL from "../config/UPLOAD_DIRECTORY_URL.mjs"; import UPLOAD_DIRECTORY_URL from "../config/UPLOAD_DIRECTORY_URL.mjs";
export default new GraphQLObjectType({ export default new GraphQLObjectType({

View File

@ -1,5 +1,6 @@
import { GraphQLList, GraphQLNonNull, GraphQLObjectType } from "graphql"; import { GraphQLList, GraphQLNonNull, GraphQLObjectType } from "graphql";
import GraphQLUpload from "graphql-upload/public/GraphQLUpload.js"; import GraphQLUpload from "graphql-upload/public/GraphQLUpload.js";
import storeUpload from "../storeUpload.mjs"; import storeUpload from "../storeUpload.mjs";
import FileType from "./FileType.mjs"; import FileType from "./FileType.mjs";

View File

@ -1,5 +1,6 @@
import fs from "fs"; import fs from "fs";
import { GraphQLList, GraphQLNonNull, GraphQLObjectType } from "graphql"; import { GraphQLList, GraphQLNonNull, GraphQLObjectType } from "graphql";
import UPLOAD_DIRECTORY_URL from "../config/UPLOAD_DIRECTORY_URL.mjs"; import UPLOAD_DIRECTORY_URL from "../config/UPLOAD_DIRECTORY_URL.mjs";
import FileType from "./FileType.mjs"; import FileType from "./FileType.mjs";

View File

@ -1,4 +1,5 @@
import { GraphQLSchema } from "graphql"; import { GraphQLSchema } from "graphql";
import MutationType from "./MutationType.mjs"; import MutationType from "./MutationType.mjs";
import QueryType from "./QueryType.mjs"; import QueryType from "./QueryType.mjs";

View File

@ -1,8 +1,9 @@
import { fileURLToPath } from "url";
import { ApolloServer } from "apollo-server-koa"; import { ApolloServer } from "apollo-server-koa";
import graphqlUploadKoa from "graphql-upload/public/graphqlUploadKoa.js"; import graphqlUploadKoa from "graphql-upload/public/graphqlUploadKoa.js";
import Koa from "koa"; import Koa from "koa";
import makeDir from "make-dir"; import makeDir from "make-dir";
import { fileURLToPath } from "url";
import UPLOAD_DIRECTORY_URL from "./config/UPLOAD_DIRECTORY_URL.mjs"; import UPLOAD_DIRECTORY_URL from "./config/UPLOAD_DIRECTORY_URL.mjs";
import schema from "./schema/index.mjs"; import schema from "./schema/index.mjs";

View File

@ -1,5 +1,6 @@
import { createWriteStream, unlink } from "fs"; import { createWriteStream, unlink } from "fs";
import shortId from "shortid"; import shortId from "shortid";
import UPLOAD_DIRECTORY_URL from "./config/UPLOAD_DIRECTORY_URL.mjs"; import UPLOAD_DIRECTORY_URL from "./config/UPLOAD_DIRECTORY_URL.mjs";
/** /**

37
app/.eslintrc.js Normal file
View File

@ -0,0 +1,37 @@
const { resolve } = require("path");
module.exports = {
extends: ["eslint:recommended", "plugin:react-hooks/recommended"],
env: {
es2022: true,
node: true,
browser: true,
},
parser: "@babel/eslint-parser",
parserOptions: {
ecmaVersion: "latest",
babelOptions: {
configFile: resolve(__dirname, ".babelrc"),
},
},
plugins: ["simple-import-sort"],
rules: {
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
},
overrides: [
{
files: ["*.mjs"],
parserOptions: {
sourceType: "module",
},
globals: {
__dirname: "off",
__filename: "off",
exports: "off",
module: "off",
require: "off",
},
},
],
};

View File

@ -1,11 +0,0 @@
{
"extends": ["env"],
"overrides": [
{
"files": ["components/**/*.js", "pages/**/*.js"],
"rules": {
"jsdoc/require-jsdoc": "off"
}
}
]
}

View File

@ -1,5 +0,0 @@
import styles from "./Header.module.css";
export const Header = (props) => (
<header {...props} className={styles.header} />
);

View File

@ -0,0 +1,6 @@
import { createElement as h } from "react";
import styles from "./Header.module.css";
export const Header = (props) =>
h("header", { ...props, className: styles.header });

View File

@ -1,16 +0,0 @@
import Head from "next/head";
import PropTypes from "prop-types";
export const Page = ({ title, children }) => (
<>
<Head>
<title>{title}</title>
</Head>
{children}
</>
);
Page.propTypes = {
title: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};

11
app/components/Page.mjs Normal file
View File

@ -0,0 +1,11 @@
import Head from "next/head";
import PropTypes from "prop-types";
import { createElement as h, Fragment } from "react";
export const Page = ({ title, children }) =>
h(Fragment, null, h(Head, null, h("title", null, title)), children);
Page.propTypes = {
title: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};

View File

@ -1,5 +0,0 @@
import styles from "./Section.module.css";
export const Section = (props) => (
<section {...props} className={styles.section} />
);

View File

@ -0,0 +1,6 @@
import { createElement as h } from "react";
import styles from "./Section.module.css";
export const Section = (props) =>
h("section", { ...props, className: styles.section });

View File

@ -3,7 +3,7 @@ import ButtonSubmit from "device-agnostic-ui/ButtonSubmit.mjs";
import Code from "device-agnostic-ui/Code.mjs"; import Code from "device-agnostic-ui/Code.mjs";
import Fieldset from "device-agnostic-ui/Fieldset.mjs"; import Fieldset from "device-agnostic-ui/Fieldset.mjs";
import Textbox from "device-agnostic-ui/Textbox.mjs"; import Textbox from "device-agnostic-ui/Textbox.mjs";
import React from "react"; import { createElement as h, Fragment, useState } from "react";
const SINGLE_UPLOAD_MUTATION = gql` const SINGLE_UPLOAD_MUTATION = gql`
mutation singleUpload($file: Upload!) { mutation singleUpload($file: Upload!) {
@ -14,8 +14,8 @@ const SINGLE_UPLOAD_MUTATION = gql`
`; `;
export function UploadBlob() { export function UploadBlob() {
const [name, setName] = React.useState(""); const [name, setName] = useState("");
const [content, setContent] = React.useState(""); const [content, setContent] = useState("");
const [singleUploadMutation, { loading }] = useMutation( const [singleUploadMutation, { loading }] = useMutation(
SINGLE_UPLOAD_MUTATION SINGLE_UPLOAD_MUTATION
); );
@ -34,32 +34,38 @@ export function UploadBlob() {
}); });
}; };
return ( return h(
<form onSubmit={onSubmit}> "form",
<Fieldset { onSubmit },
legend={ h(
<> Fieldset,
File name (without <Code>.txt</Code>) {
</> legend: h(
} Fragment,
> null,
<Textbox "File name (without ",
placeholder="Name" h(Code, null, ".txt"),
required ")"
value={name} ),
onChange={onNameChange} },
/> h(Textbox, {
</Fieldset> placeholder: "Name",
<Fieldset legend="File content"> required: true,
<Textbox value: name,
type="textarea" onChange: onNameChange,
placeholder="Content" })
required ),
value={content} h(
onChange={onContentChange} Fieldset,
/> { legend: "File content" },
</Fieldset> h(Textbox, {
<ButtonSubmit loading={loading}>Upload</ButtonSubmit> type: "textarea",
</form> placeholder: "Content",
required: true,
value: content,
onChange: onContentChange,
})
),
h(ButtonSubmit, { loading }, "Upload")
); );
} }

View File

@ -1,4 +1,5 @@
import { gql, useApolloClient, useMutation } from "@apollo/client"; import { gql, useApolloClient, useMutation } from "@apollo/client";
import { createElement as h } from "react";
const SINGLE_UPLOAD_MUTATION = gql` const SINGLE_UPLOAD_MUTATION = gql`
mutation singleUpload($file: Upload!) { mutation singleUpload($file: Upload!) {
@ -23,5 +24,5 @@ export function UploadFile() {
apolloClient.resetStore(); apolloClient.resetStore();
}); });
return <input type="file" required onChange={onChange} />; return h("input", { type: "file", required: true, onChange });
} }

View File

@ -1,4 +1,5 @@
import { gql, useApolloClient, useMutation } from "@apollo/client"; import { gql, useApolloClient, useMutation } from "@apollo/client";
import { createElement as h } from "react";
const MULTIPLE_UPLOAD_MUTATION = gql` const MULTIPLE_UPLOAD_MUTATION = gql`
mutation multipleUpload($files: [Upload!]!) { mutation multipleUpload($files: [Upload!]!) {
@ -18,5 +19,5 @@ export function UploadFileList() {
apolloClient.resetStore(); apolloClient.resetStore();
}); });
return <input type="file" multiple required onChange={onChange} />; return h("input", { type: "file", multiple: true, required: true, onChange });
} }

View File

@ -1,6 +1,7 @@
import { gql, useQuery } from "@apollo/client"; import { gql, useQuery } from "@apollo/client";
import Scroll from "device-agnostic-ui/Scroll.mjs"; import Scroll from "device-agnostic-ui/Scroll.mjs";
import Table from "device-agnostic-ui/Table.mjs"; import Table from "device-agnostic-ui/Table.mjs";
import { createElement as h } from "react";
const UPLOADS_QUERY = gql` const UPLOADS_QUERY = gql`
query uploads { query uploads {
@ -14,22 +15,18 @@ const UPLOADS_QUERY = gql`
export function Uploads() { export function Uploads() {
const { data: { uploads = [] } = {} } = useQuery(UPLOADS_QUERY); const { data: { uploads = [] } = {} } = useQuery(UPLOADS_QUERY);
return ( return h(
<Scroll> Scroll,
<Table> null,
<thead> h(
<tr> Table,
<th>Stored file URL</th> null,
</tr> h("thead", null, h("tr", null, h("th", null, "Stored file URL"))),
</thead> h(
<tbody> "tbody",
{uploads.map(({ id, url }) => ( null,
<tr key={id}> uploads.map(({ id, url }) => h("tr", { key: id }, h("td", null, url)))
<td>{url}</td> )
</tr> )
))}
</tbody>
</Table>
</Scroll>
); );
} }

View File

@ -1,4 +1,4 @@
module.exports = { export default {
env: { env: {
API_URI: process.env.API_URI, API_URI: process.env.API_URI,
}, },
@ -6,5 +6,6 @@ module.exports = {
locales: ["en-US"], locales: ["en-US"],
defaultLocale: "en-US", defaultLocale: "en-US",
}, },
pageExtensions: ["mjs"],
reactStrictMode: true, reactStrictMode: true,
}; };

3199
app/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -32,18 +32,10 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.17.0", "@babel/eslint-parser": "^7.17.0",
"@next/eslint-plugin-next": "^12.1.6",
"babel-plugin-graphql-tag": "^3.3.0", "babel-plugin-graphql-tag": "^3.3.0",
"eslint": "^8.15.0", "eslint": "^8.15.0",
"eslint-config-env": "^23.0.2",
"eslint-config-next": "^12.1.6",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsdoc": "^37.9.7",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.5.0", "eslint-plugin-react-hooks": "^4.5.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"prettier": "^2.6.2", "prettier": "^2.6.2",
"stylelint": "^14.8.2", "stylelint": "^14.8.2",
"stylelint-config-prettier": "^9.0.3", "stylelint-config-prettier": "^9.0.3",

View File

@ -10,10 +10,12 @@ import "device-agnostic-ui/Margin.css";
import "device-agnostic-ui/Scroll.css"; import "device-agnostic-ui/Scroll.css";
import "device-agnostic-ui/Table.css"; import "device-agnostic-ui/Table.css";
import "device-agnostic-ui/Textbox.css"; import "device-agnostic-ui/Textbox.css";
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client"; import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client";
import { createUploadLink } from "apollo-upload-client"; import { createUploadLink } from "apollo-upload-client";
import Head from "next/head"; import Head from "next/head";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { createElement as h } from "react";
const createApolloClient = (cache = {}) => const createApolloClient = (cache = {}) =>
new ApolloClient({ new ApolloClient({
@ -27,17 +29,23 @@ const App = ({
pageProps, pageProps,
apolloCache, apolloCache,
apolloClient = createApolloClient(apolloCache), apolloClient = createApolloClient(apolloCache),
}) => ( }) =>
<ApolloProvider client={apolloClient}> h(
<Head> ApolloProvider,
<meta name="viewport" content="width=device-width, initial-scale=1" /> { client: apolloClient },
<meta name="color-scheme" content="light dark" /> h(
<meta name="theme-color" content="white" /> Head,
<link rel="manifest" href="/manifest.webmanifest" /> null,
</Head> h("meta", {
<Component {...pageProps} /> name: "viewport",
</ApolloProvider> content: "width=device-width, initial-scale=1",
); }),
h("meta", { name: "color-scheme", content: "light dark" }),
h("meta", { name: "theme-color", content: "white" }),
h("link", { rel: "manifest", href: "/manifest.webmanifest" })
),
h(Component, pageProps)
);
App.getInitialProps = async (context) => { App.getInitialProps = async (context) => {
const props = { const props = {
@ -51,12 +59,12 @@ App.getInitialProps = async (context) => {
try { try {
const { getDataFromTree } = await import("@apollo/client/react/ssr"); const { getDataFromTree } = await import("@apollo/client/react/ssr");
await getDataFromTree( await getDataFromTree(
<App h(App, {
{...props} ...props,
apolloClient={apolloClient} apolloClient,
router={context.router} router: context.router,
Component={context.Component} Component: context.Component,
/> })
); );
} catch (error) { } catch (error) {
// Prevent crash from GraphQL errors. // Prevent crash from GraphQL errors.

View File

@ -1,58 +0,0 @@
import Code from "device-agnostic-ui/Code.mjs";
import Heading from "device-agnostic-ui/Heading.mjs";
import Margin from "device-agnostic-ui/Margin.mjs";
import { Header } from "../components/Header";
import { Page } from "../components/Page";
import { Section } from "../components/Section";
import { UploadBlob } from "../components/UploadBlob";
import { UploadFile } from "../components/UploadFile";
import { UploadFileList } from "../components/UploadFileList";
import { Uploads } from "../components/Uploads";
const IndexPage = () => (
<Page title="Apollo upload examples">
<Header>
<Heading level={1} size={1}>
Apollo upload examples
</Heading>
</Header>
<Section>
<Header>
<Heading level={2} size={2}>
Upload <Code>FileList</Code>
</Heading>
</Header>
<Margin>
<UploadFileList />
</Margin>
</Section>
<Section>
<Header>
<Heading level={2} size={2}>
Upload <Code>File</Code>
</Heading>
</Header>
<Margin>
<UploadFile />
</Margin>
</Section>
<Section>
<Header>
<Heading level={2} size={2}>
Upload <Code>Blob</Code>
</Heading>
</Header>
<Margin>
<UploadBlob />
</Margin>
</Section>
<Section>
<Header>
<Heading>Uploads</Heading>
</Header>
<Uploads />
</Section>
</Page>
);
export default IndexPage;

55
app/pages/index.mjs Normal file
View File

@ -0,0 +1,55 @@
import Code from "device-agnostic-ui/Code.mjs";
import Heading from "device-agnostic-ui/Heading.mjs";
import Margin from "device-agnostic-ui/Margin.mjs";
import { createElement as h } from "react";
import { Header } from "../components/Header.mjs";
import { Page } from "../components/Page.mjs";
import { Section } from "../components/Section.mjs";
import { UploadBlob } from "../components/UploadBlob.mjs";
import { UploadFile } from "../components/UploadFile.mjs";
import { UploadFileList } from "../components/UploadFileList.mjs";
import { Uploads } from "../components/Uploads.mjs";
export default function IndexPage() {
return h(
Page,
{ title: "Apollo upload examples" },
h(
Header,
null,
h(Heading, { level: 1, size: 1 }, "Apollo upload examples")
),
h(
Section,
null,
h(
Header,
null,
h(Heading, { level: 2, size: 2 }, "Upload ", h(Code, null, "FileList"))
),
h(Margin, null, h(UploadFileList))
),
h(
Section,
null,
h(
Header,
null,
h(Heading, { level: 2, size: 2 }, "Upload ", h(Code, null, "File"))
),
h(Margin, null, h(UploadFile))
),
h(
Section,
null,
h(
Header,
null,
h(Heading, { level: 2, size: 2 }, "Upload ", h(Code, null, "Blob"))
),
h(Margin, null, h(UploadBlob))
),
h(Section, null, h(Header, null, h(Heading, null, "Uploads")), h(Uploads))
);
}