Simplify ESLint dev dependencies and config, drop JSX syntax, use .mjs files.
This commit is contained in:
parent
32ac135165
commit
4a6bb2c992
@ -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
2386
api/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -30,12 +30,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.15.0",
|
||||
"eslint-config-env": "^23.0.2",
|
||||
"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-simple-import-sort": "^7.0.0",
|
||||
"nodemon": "^2.0.16",
|
||||
"prettier": "^2.6.2"
|
||||
},
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { GraphQLNonNull, GraphQLObjectType, GraphQLString } from "graphql";
|
||||
|
||||
import UPLOAD_DIRECTORY_URL from "../config/UPLOAD_DIRECTORY_URL.mjs";
|
||||
|
||||
export default new GraphQLObjectType({
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { GraphQLList, GraphQLNonNull, GraphQLObjectType } from "graphql";
|
||||
import GraphQLUpload from "graphql-upload/public/GraphQLUpload.js";
|
||||
|
||||
import storeUpload from "../storeUpload.mjs";
|
||||
import FileType from "./FileType.mjs";
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import fs from "fs";
|
||||
import { GraphQLList, GraphQLNonNull, GraphQLObjectType } from "graphql";
|
||||
|
||||
import UPLOAD_DIRECTORY_URL from "../config/UPLOAD_DIRECTORY_URL.mjs";
|
||||
import FileType from "./FileType.mjs";
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { GraphQLSchema } from "graphql";
|
||||
|
||||
import MutationType from "./MutationType.mjs";
|
||||
import QueryType from "./QueryType.mjs";
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { fileURLToPath } from "url";
|
||||
import { ApolloServer } from "apollo-server-koa";
|
||||
import graphqlUploadKoa from "graphql-upload/public/graphqlUploadKoa.js";
|
||||
import Koa from "koa";
|
||||
import makeDir from "make-dir";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
import UPLOAD_DIRECTORY_URL from "./config/UPLOAD_DIRECTORY_URL.mjs";
|
||||
import schema from "./schema/index.mjs";
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { createWriteStream, unlink } from "fs";
|
||||
import shortId from "shortid";
|
||||
|
||||
import UPLOAD_DIRECTORY_URL from "./config/UPLOAD_DIRECTORY_URL.mjs";
|
||||
|
||||
/**
|
||||
|
||||
37
app/.eslintrc.js
Normal file
37
app/.eslintrc.js
Normal 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",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"extends": ["env"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["components/**/*.js", "pages/**/*.js"],
|
||||
"rules": {
|
||||
"jsdoc/require-jsdoc": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
import styles from "./Header.module.css";
|
||||
|
||||
export const Header = (props) => (
|
||||
<header {...props} className={styles.header} />
|
||||
);
|
||||
6
app/components/Header.mjs
Normal file
6
app/components/Header.mjs
Normal 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 });
|
||||
@ -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
11
app/components/Page.mjs
Normal 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,
|
||||
};
|
||||
@ -1,5 +0,0 @@
|
||||
import styles from "./Section.module.css";
|
||||
|
||||
export const Section = (props) => (
|
||||
<section {...props} className={styles.section} />
|
||||
);
|
||||
6
app/components/Section.mjs
Normal file
6
app/components/Section.mjs
Normal 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 });
|
||||
@ -3,7 +3,7 @@ import ButtonSubmit from "device-agnostic-ui/ButtonSubmit.mjs";
|
||||
import Code from "device-agnostic-ui/Code.mjs";
|
||||
import Fieldset from "device-agnostic-ui/Fieldset.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`
|
||||
mutation singleUpload($file: Upload!) {
|
||||
@ -14,8 +14,8 @@ const SINGLE_UPLOAD_MUTATION = gql`
|
||||
`;
|
||||
|
||||
export function UploadBlob() {
|
||||
const [name, setName] = React.useState("");
|
||||
const [content, setContent] = React.useState("");
|
||||
const [name, setName] = useState("");
|
||||
const [content, setContent] = useState("");
|
||||
const [singleUploadMutation, { loading }] = useMutation(
|
||||
SINGLE_UPLOAD_MUTATION
|
||||
);
|
||||
@ -34,32 +34,38 @@ export function UploadBlob() {
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={onSubmit}>
|
||||
<Fieldset
|
||||
legend={
|
||||
<>
|
||||
File name (without <Code>.txt</Code>)
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Textbox
|
||||
placeholder="Name"
|
||||
required
|
||||
value={name}
|
||||
onChange={onNameChange}
|
||||
/>
|
||||
</Fieldset>
|
||||
<Fieldset legend="File content">
|
||||
<Textbox
|
||||
type="textarea"
|
||||
placeholder="Content"
|
||||
required
|
||||
value={content}
|
||||
onChange={onContentChange}
|
||||
/>
|
||||
</Fieldset>
|
||||
<ButtonSubmit loading={loading}>Upload</ButtonSubmit>
|
||||
</form>
|
||||
return h(
|
||||
"form",
|
||||
{ onSubmit },
|
||||
h(
|
||||
Fieldset,
|
||||
{
|
||||
legend: h(
|
||||
Fragment,
|
||||
null,
|
||||
"File name (without ",
|
||||
h(Code, null, ".txt"),
|
||||
")"
|
||||
),
|
||||
},
|
||||
h(Textbox, {
|
||||
placeholder: "Name",
|
||||
required: true,
|
||||
value: name,
|
||||
onChange: onNameChange,
|
||||
})
|
||||
),
|
||||
h(
|
||||
Fieldset,
|
||||
{ legend: "File content" },
|
||||
h(Textbox, {
|
||||
type: "textarea",
|
||||
placeholder: "Content",
|
||||
required: true,
|
||||
value: content,
|
||||
onChange: onContentChange,
|
||||
})
|
||||
),
|
||||
h(ButtonSubmit, { loading }, "Upload")
|
||||
);
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
import { gql, useApolloClient, useMutation } from "@apollo/client";
|
||||
import { createElement as h } from "react";
|
||||
|
||||
const SINGLE_UPLOAD_MUTATION = gql`
|
||||
mutation singleUpload($file: Upload!) {
|
||||
@ -23,5 +24,5 @@ export function UploadFile() {
|
||||
apolloClient.resetStore();
|
||||
});
|
||||
|
||||
return <input type="file" required onChange={onChange} />;
|
||||
return h("input", { type: "file", required: true, onChange });
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
import { gql, useApolloClient, useMutation } from "@apollo/client";
|
||||
import { createElement as h } from "react";
|
||||
|
||||
const MULTIPLE_UPLOAD_MUTATION = gql`
|
||||
mutation multipleUpload($files: [Upload!]!) {
|
||||
@ -18,5 +19,5 @@ export function UploadFileList() {
|
||||
apolloClient.resetStore();
|
||||
});
|
||||
|
||||
return <input type="file" multiple required onChange={onChange} />;
|
||||
return h("input", { type: "file", multiple: true, required: true, onChange });
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import { gql, useQuery } from "@apollo/client";
|
||||
import Scroll from "device-agnostic-ui/Scroll.mjs";
|
||||
import Table from "device-agnostic-ui/Table.mjs";
|
||||
import { createElement as h } from "react";
|
||||
|
||||
const UPLOADS_QUERY = gql`
|
||||
query uploads {
|
||||
@ -14,22 +15,18 @@ const UPLOADS_QUERY = gql`
|
||||
export function Uploads() {
|
||||
const { data: { uploads = [] } = {} } = useQuery(UPLOADS_QUERY);
|
||||
|
||||
return (
|
||||
<Scroll>
|
||||
<Table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Stored file URL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{uploads.map(({ id, url }) => (
|
||||
<tr key={id}>
|
||||
<td>{url}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
</Scroll>
|
||||
return h(
|
||||
Scroll,
|
||||
null,
|
||||
h(
|
||||
Table,
|
||||
null,
|
||||
h("thead", null, h("tr", null, h("th", null, "Stored file URL"))),
|
||||
h(
|
||||
"tbody",
|
||||
null,
|
||||
uploads.map(({ id, url }) => h("tr", { key: id }, h("td", null, url)))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
export default {
|
||||
env: {
|
||||
API_URI: process.env.API_URI,
|
||||
},
|
||||
@ -6,5 +6,6 @@ module.exports = {
|
||||
locales: ["en-US"],
|
||||
defaultLocale: "en-US",
|
||||
},
|
||||
pageExtensions: ["mjs"],
|
||||
reactStrictMode: true,
|
||||
};
|
||||
3199
app/package-lock.json
generated
3199
app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -32,18 +32,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.17.0",
|
||||
"@next/eslint-plugin-next": "^12.1.6",
|
||||
"babel-plugin-graphql-tag": "^3.3.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-simple-import-sort": "^7.0.0",
|
||||
"prettier": "^2.6.2",
|
||||
"stylelint": "^14.8.2",
|
||||
"stylelint-config-prettier": "^9.0.3",
|
||||
|
||||
@ -10,10 +10,12 @@ import "device-agnostic-ui/Margin.css";
|
||||
import "device-agnostic-ui/Scroll.css";
|
||||
import "device-agnostic-ui/Table.css";
|
||||
import "device-agnostic-ui/Textbox.css";
|
||||
|
||||
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client";
|
||||
import { createUploadLink } from "apollo-upload-client";
|
||||
import Head from "next/head";
|
||||
import PropTypes from "prop-types";
|
||||
import { createElement as h } from "react";
|
||||
|
||||
const createApolloClient = (cache = {}) =>
|
||||
new ApolloClient({
|
||||
@ -27,17 +29,23 @@ const App = ({
|
||||
pageProps,
|
||||
apolloCache,
|
||||
apolloClient = createApolloClient(apolloCache),
|
||||
}) => (
|
||||
<ApolloProvider client={apolloClient}>
|
||||
<Head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="theme-color" content="white" />
|
||||
<link rel="manifest" href="/manifest.webmanifest" />
|
||||
</Head>
|
||||
<Component {...pageProps} />
|
||||
</ApolloProvider>
|
||||
);
|
||||
}) =>
|
||||
h(
|
||||
ApolloProvider,
|
||||
{ client: apolloClient },
|
||||
h(
|
||||
Head,
|
||||
null,
|
||||
h("meta", {
|
||||
name: "viewport",
|
||||
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) => {
|
||||
const props = {
|
||||
@ -51,12 +59,12 @@ App.getInitialProps = async (context) => {
|
||||
try {
|
||||
const { getDataFromTree } = await import("@apollo/client/react/ssr");
|
||||
await getDataFromTree(
|
||||
<App
|
||||
{...props}
|
||||
apolloClient={apolloClient}
|
||||
router={context.router}
|
||||
Component={context.Component}
|
||||
/>
|
||||
h(App, {
|
||||
...props,
|
||||
apolloClient,
|
||||
router: context.router,
|
||||
Component: context.Component,
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
// Prevent crash from GraphQL errors.
|
||||
@ -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
55
app/pages/index.mjs
Normal 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))
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user