From 65c8da0f34b81afc9d622c40e57152ddab6e38a7 Mon Sep 17 00:00:00 2001 From: Kiwi Date: Wed, 27 Jun 2018 19:06:30 -0300 Subject: [PATCH] Merge client into next (#1709) * Merge client * Add linting script * Rename serve to start:development * Move error harmonization and handling to network layer * Show Comment Stream * Added initial test --- .gitignore | 15 +- .nodemonrc.json | 5 - .prettierignore | 1 - .prettierrc.json | 2 +- config/env.js | 93 + config/jest.config.js | 41 + config/jest/cssTransform.js | 14 + config/jest/fileTransform.js | 12 + config/nodemon/relay-stream.json | 8 + config/nodemon/server.json | 10 + config/paths.js | 65 + config/polyfills.js | 1 + config/postcss.config.js | 32 + config/webpack.config.dev.js | 328 + config/webpack.config.prod.js | 388 + config/webpackDevServer.config.js | 101 + doczrc.js | 44 + loaders/locales-loader.js | 149 + package-lock.json | 16791 +++++++++++++++- package.json | 92 +- scripts/build.js | 145 + scripts/start.js | 107 + scripts/test.js | 29 + src/core/client/.babelrc.js | 14 + src/core/client/framework/README.md | 8 + src/core/client/framework/lib/README.md | 3 + .../framework/lib/bootstrap/TalkContext.tsx | 33 + .../framework/lib/bootstrap/createContext.ts | 55 + .../client/framework/lib/bootstrap/index.ts | 3 + .../framework/lib/bootstrap/withContext.tsx | 23 + .../framework/lib/errors/badUserInputError.ts | 79 + .../framework/lib/errors/graphqlError.ts | 25 + src/core/client/framework/lib/errors/index.ts | 5 + .../framework/lib/errors/networkError.ts | 18 + .../lib/errors/unknownServerError.ts | 26 + src/core/client/framework/lib/form.tsx | 12 + src/core/client/framework/lib/i18n.ts | 103 + src/core/client/framework/lib/messages.tsx | 19 + .../framework/lib/network/fetchQuery.ts | 61 + .../client/framework/lib/network/index.ts | 1 + .../framework/lib/relay/QueryRenderer.tsx | 40 + .../lib/relay/commitMutationPromise.ts | 67 + .../framework/lib/relay/createAndRetain.ts | 23 + .../lib/relay/createMutationContainer.tsx | 39 + src/core/client/framework/lib/relay/index.ts | 14 + .../lib/relay/withFragmentContainer.ts | 12 + .../lib/relay/withLocalStateContainer.tsx | 71 + .../lib/relay/withPaginationContainer.ts | 20 + .../lib/relay/withRefetchContainer.ts | 19 + .../client/framework/lib/validation.spec.tsx | 12 + src/core/client/framework/lib/validation.tsx | 33 + src/core/client/framework/types.ts | 2 + src/core/client/stream/.babelrc.js | 8 + src/core/client/stream/components/App.tsx | 36 + .../client/stream/components/AssetList.tsx | 16 + src/core/client/stream/components/Comment.css | 11 + src/core/client/stream/components/Comment.tsx | 32 + src/core/client/stream/components/Logo.tsx | 22 + .../stream/components/PostCommentForm.css | 12 + .../stream/components/PostCommentForm.tsx | 52 + src/core/client/stream/components/Stream.tsx | 20 + .../client/stream/containers/AppContainer.tsx | 40 + .../stream/containers/AssetListContainer.tsx | 33 + .../stream/containers/CommentContainer.tsx | 29 + .../containers/PostCommentFormContainer.tsx | 38 + .../stream/containers/StreamContainer.tsx | 33 + src/core/client/stream/index.html | 15 + src/core/client/stream/index.tsx | 37 + src/core/client/stream/local/constants.ts | 6 + src/core/client/stream/local/index.ts | 2 + .../client/stream/local/initLocalState.ts | 39 + src/core/client/stream/local/local.graphql | 13 + src/core/client/stream/locales.ts | 9 + .../stream/mutations/CreateCommentMutation.ts | 71 + .../mutations/SetNetworkStatusMutation.ts | 23 + src/core/client/stream/mutations/index.ts | 2 + src/core/client/stream/queries/AppQuery.tsx | 60 + src/core/client/tsconfig.json | 41 + src/core/client/tslint.json | 14 + src/core/client/ui/README.md | 8 + .../ui/components/BaseButton/BaseButton.css | 10 + .../ui/components/BaseButton/BaseButton.mdx | 28 + .../ui/components/BaseButton/BaseButton.tsx | 61 + .../client/ui/components/BaseButton/index.ts | 2 + .../client/ui/components/Button/Button.css | 78 + .../client/ui/components/Button/Button.mdx | 20 + .../client/ui/components/Button/Button.tsx | 64 + src/core/client/ui/components/Button/index.ts | 2 + .../client/ui/components/Center/Center.css | 6 + .../client/ui/components/Center/Center.tsx | 30 + src/core/client/ui/components/Center/index.ts | 2 + .../ui/components/Typography/Typography.css | 94 + .../ui/components/Typography/Typography.tsx | 140 + .../client/ui/components/Typography/index.ts | 2 + src/core/client/ui/components/index.ts | 4 + src/core/client/ui/hocs/index.ts | 2 + src/core/client/ui/hocs/withKeyboardFocus.tsx | 64 + src/core/client/ui/hocs/withStyles.ts | 30 + src/core/client/ui/shared/buttonReset.css | 34 + src/core/client/ui/shared/typography.css | 59 + src/core/client/ui/theme/variables.ts | 73 + src/core/client/ui/types.ts | 32 + .../server/app/middleware/passport/index.ts | 4 +- src/core/server/app/middleware/tenant.ts | 2 +- .../server/graph/tenant/loaders/comments.ts | 1 - .../server/graph/tenant/resolvers/asset.ts | 2 + .../server/graph/tenant/resolvers/query.ts | 3 +- .../server/graph/tenant/schema/schema.graphql | 8 +- src/core/server/models/comment.ts | 2 +- src/docs/introduction.mdx | 9 + src/docs/workarounds.mdx | 80 + src/locales/de/common.ftl | 1 + src/locales/de/framework.ftl | 5 + src/locales/de/stream.ftl | 1 + src/locales/en-US/common.ftl | 1 + src/locales/en-US/framework.ftl | 5 + src/locales/en-US/stream.ftl | 1 + src/locales/es/framework.ftl | 4 + src/locales/es/stream.ftl | 0 src/types/fluent.d.ts | 52 + tsconfig.json | 32 +- tslint.json | 14 +- 122 files changed, 21057 insertions(+), 42 deletions(-) delete mode 100644 .nodemonrc.json delete mode 100644 .prettierignore create mode 100644 config/env.js create mode 100644 config/jest.config.js create mode 100644 config/jest/cssTransform.js create mode 100644 config/jest/fileTransform.js create mode 100644 config/nodemon/relay-stream.json create mode 100644 config/nodemon/server.json create mode 100644 config/paths.js create mode 100644 config/polyfills.js create mode 100644 config/postcss.config.js create mode 100644 config/webpack.config.dev.js create mode 100644 config/webpack.config.prod.js create mode 100644 config/webpackDevServer.config.js create mode 100644 doczrc.js create mode 100644 loaders/locales-loader.js create mode 100644 scripts/build.js create mode 100644 scripts/start.js create mode 100644 scripts/test.js create mode 100644 src/core/client/.babelrc.js create mode 100644 src/core/client/framework/README.md create mode 100644 src/core/client/framework/lib/README.md create mode 100644 src/core/client/framework/lib/bootstrap/TalkContext.tsx create mode 100644 src/core/client/framework/lib/bootstrap/createContext.ts create mode 100644 src/core/client/framework/lib/bootstrap/index.ts create mode 100644 src/core/client/framework/lib/bootstrap/withContext.tsx create mode 100644 src/core/client/framework/lib/errors/badUserInputError.ts create mode 100644 src/core/client/framework/lib/errors/graphqlError.ts create mode 100644 src/core/client/framework/lib/errors/index.ts create mode 100644 src/core/client/framework/lib/errors/networkError.ts create mode 100644 src/core/client/framework/lib/errors/unknownServerError.ts create mode 100644 src/core/client/framework/lib/form.tsx create mode 100644 src/core/client/framework/lib/i18n.ts create mode 100644 src/core/client/framework/lib/messages.tsx create mode 100644 src/core/client/framework/lib/network/fetchQuery.ts create mode 100644 src/core/client/framework/lib/network/index.ts create mode 100644 src/core/client/framework/lib/relay/QueryRenderer.tsx create mode 100644 src/core/client/framework/lib/relay/commitMutationPromise.ts create mode 100644 src/core/client/framework/lib/relay/createAndRetain.ts create mode 100644 src/core/client/framework/lib/relay/createMutationContainer.tsx create mode 100644 src/core/client/framework/lib/relay/index.ts create mode 100644 src/core/client/framework/lib/relay/withFragmentContainer.ts create mode 100644 src/core/client/framework/lib/relay/withLocalStateContainer.tsx create mode 100644 src/core/client/framework/lib/relay/withPaginationContainer.ts create mode 100644 src/core/client/framework/lib/relay/withRefetchContainer.ts create mode 100644 src/core/client/framework/lib/validation.spec.tsx create mode 100644 src/core/client/framework/lib/validation.tsx create mode 100644 src/core/client/framework/types.ts create mode 100644 src/core/client/stream/.babelrc.js create mode 100644 src/core/client/stream/components/App.tsx create mode 100644 src/core/client/stream/components/AssetList.tsx create mode 100644 src/core/client/stream/components/Comment.css create mode 100644 src/core/client/stream/components/Comment.tsx create mode 100644 src/core/client/stream/components/Logo.tsx create mode 100644 src/core/client/stream/components/PostCommentForm.css create mode 100644 src/core/client/stream/components/PostCommentForm.tsx create mode 100644 src/core/client/stream/components/Stream.tsx create mode 100644 src/core/client/stream/containers/AppContainer.tsx create mode 100644 src/core/client/stream/containers/AssetListContainer.tsx create mode 100644 src/core/client/stream/containers/CommentContainer.tsx create mode 100644 src/core/client/stream/containers/PostCommentFormContainer.tsx create mode 100644 src/core/client/stream/containers/StreamContainer.tsx create mode 100644 src/core/client/stream/index.html create mode 100644 src/core/client/stream/index.tsx create mode 100644 src/core/client/stream/local/constants.ts create mode 100644 src/core/client/stream/local/index.ts create mode 100644 src/core/client/stream/local/initLocalState.ts create mode 100644 src/core/client/stream/local/local.graphql create mode 100644 src/core/client/stream/locales.ts create mode 100644 src/core/client/stream/mutations/CreateCommentMutation.ts create mode 100644 src/core/client/stream/mutations/SetNetworkStatusMutation.ts create mode 100644 src/core/client/stream/mutations/index.ts create mode 100644 src/core/client/stream/queries/AppQuery.tsx create mode 100644 src/core/client/tsconfig.json create mode 100644 src/core/client/tslint.json create mode 100644 src/core/client/ui/README.md create mode 100644 src/core/client/ui/components/BaseButton/BaseButton.css create mode 100644 src/core/client/ui/components/BaseButton/BaseButton.mdx create mode 100644 src/core/client/ui/components/BaseButton/BaseButton.tsx create mode 100644 src/core/client/ui/components/BaseButton/index.ts create mode 100644 src/core/client/ui/components/Button/Button.css create mode 100644 src/core/client/ui/components/Button/Button.mdx create mode 100644 src/core/client/ui/components/Button/Button.tsx create mode 100644 src/core/client/ui/components/Button/index.ts create mode 100644 src/core/client/ui/components/Center/Center.css create mode 100644 src/core/client/ui/components/Center/Center.tsx create mode 100644 src/core/client/ui/components/Center/index.ts create mode 100644 src/core/client/ui/components/Typography/Typography.css create mode 100644 src/core/client/ui/components/Typography/Typography.tsx create mode 100644 src/core/client/ui/components/Typography/index.ts create mode 100644 src/core/client/ui/components/index.ts create mode 100644 src/core/client/ui/hocs/index.ts create mode 100644 src/core/client/ui/hocs/withKeyboardFocus.tsx create mode 100644 src/core/client/ui/hocs/withStyles.ts create mode 100644 src/core/client/ui/shared/buttonReset.css create mode 100644 src/core/client/ui/shared/typography.css create mode 100644 src/core/client/ui/theme/variables.ts create mode 100644 src/core/client/ui/types.ts create mode 100644 src/docs/introduction.mdx create mode 100644 src/docs/workarounds.mdx create mode 100644 src/locales/de/common.ftl create mode 100644 src/locales/de/framework.ftl create mode 100644 src/locales/de/stream.ftl create mode 100644 src/locales/en-US/common.ftl create mode 100644 src/locales/en-US/framework.ftl create mode 100644 src/locales/en-US/stream.ftl create mode 100644 src/locales/es/framework.ftl create mode 100644 src/locales/es/stream.ftl create mode 100644 src/types/fluent.d.ts diff --git a/.gitignore b/.gitignore index 25251254a..f9359967b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,16 @@ node_modules dist .env -*.js -yarn.lock \ No newline at end of file +npm-debug.log* +yarn-error.log +yarn.lock +coverage + +.idea/ +.docz +*.swp +*.DS_STORE + +*.css.d.ts +__generated__ + diff --git a/.nodemonrc.json b/.nodemonrc.json deleted file mode 100644 index 0d7fe4c44..000000000 --- a/.nodemonrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "execMap": { - "ts": "ts-node" - } -} \ No newline at end of file diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 53c37a166..000000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -dist \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index 1b016bffe..c4be887be 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,3 +1,3 @@ { - "trailingComma": "es5" + "trailingComma": "es5" } \ No newline at end of file diff --git a/config/env.js b/config/env.js new file mode 100644 index 000000000..2240e824f --- /dev/null +++ b/config/env.js @@ -0,0 +1,93 @@ +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const paths = require("./paths"); + +// Make sure that including paths.js after env.js will read .env variables. +delete require.cache[require.resolve("./paths")]; + +const NODE_ENV = process.env.NODE_ENV; +if (!NODE_ENV) { + throw new Error( + "The NODE_ENV environment variable is required but was not specified." + ); +} + +// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use +var dotenvFiles = [ + `${paths.dotenv}.${NODE_ENV}.local`, + `${paths.dotenv}.${NODE_ENV}`, + // Don't include `.env.local` for `test` environment + // since normally you expect tests to produce the same + // results for everyone + NODE_ENV !== "test" && `${paths.dotenv}.local`, + paths.dotenv, +].filter(Boolean); + +// Load environment variables from .env* files. Suppress warnings using silent +// if this file is missing. dotenv will never modify any environment variables +// that have already been set. Variable expansion is supported in .env files. +// https://github.com/motdotla/dotenv +// https://github.com/motdotla/dotenv-expand +dotenvFiles.forEach(dotenvFile => { + if (fs.existsSync(dotenvFile)) { + require("dotenv-expand")( + require("dotenv").config({ + path: dotenvFile, + }) + ); + } +}); + +// We support resolving modules according to `NODE_PATH`. +// This lets you use absolute paths in imports inside large monorepos: +// https://github.com/facebookincubator/create-react-app/issues/253. +// It works similar to `NODE_PATH` in Node itself: +// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders +// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. +// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. +// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 +// We also resolve them to make sure all tools using them work consistently. +const appDirectory = fs.realpathSync(process.cwd()); +process.env.NODE_PATH = (process.env.NODE_PATH || "") + .split(path.delimiter) + .filter(folder => folder && !path.isAbsolute(folder)) + .map(folder => path.resolve(appDirectory, folder)) + .join(path.delimiter); + +// Grab NODE_ENV and TALK_* environment variables and prepare them to be +// injected into the application via DefinePlugin in Webpack configuration. +const REACT_APP = /^TALK_/i; + +function getClientEnvironment(publicUrl) { + const raw = Object.keys(process.env) + .filter(key => REACT_APP.test(key)) + .reduce( + (env, key) => { + env[key] = process.env[key]; + return env; + }, + { + // Useful for determining whether we’re running in production mode. + // Most importantly, it switches React into the correct mode. + NODE_ENV: process.env.NODE_ENV || "development", + // Useful for resolving the correct path to static assets in `public`. + // For example, . + // This should only be used as an escape hatch. Normally you would put + // images into the `src` and `import` them in code to get their paths. + PUBLIC_URL: publicUrl, + } + ); + // Stringify all values so we can feed into Webpack DefinePlugin + const stringified = { + "process.env": Object.keys(raw).reduce((env, key) => { + env[key] = JSON.stringify(raw[key]); + return env; + }, {}), + }; + + return { raw, stringified }; +} + +module.exports = getClientEnvironment; diff --git a/config/jest.config.js b/config/jest.config.js new file mode 100644 index 000000000..39cb8dbdb --- /dev/null +++ b/config/jest.config.js @@ -0,0 +1,41 @@ +const paths = require("./paths"); + +module.exports = { + rootDir: "../", + roots: ["/src", "/scripts"], + collectCoverageFrom: [ + "src/**/*.{js,jsx,mjs,ts,tsx}" + ], + coveragePathIgnorePatterns: ["/node_modules/"], + setupFiles: [ + "/config/polyfills.js" + ], + testMatch: [ + "**/__tests__/**/*.{js,jsx,mjs,ts,tsx}", + "**/*.(spec|test).{js,jsx,mjs,ts,tsx}" + ], + testEnvironment: "node", + testURL: "http://localhost", + transform: { + "^.+\\.(js|jsx|mjs|ts|tsx)$": "/node_modules/ts-jest", + "^.+\\.css$": "/config/jest/cssTransform.js", + "^(?!.*\\.(js|jsx|mjs|css|json|ftl)$)": "/config/jest/fileTransform.js" + }, + transformIgnorePatterns: [ + "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|ts|tsx)$" + ], + moduleNameMapper: { + "^react-native$": "react-native-web" + }, + moduleFileExtensions: [ + "web.js", + "js", + "json", + "web.jsx", + "jsx", + "node", + "mjs", + "ts", + "tsx" + ], +} diff --git a/config/jest/cssTransform.js b/config/jest/cssTransform.js new file mode 100644 index 000000000..8f6511481 --- /dev/null +++ b/config/jest/cssTransform.js @@ -0,0 +1,14 @@ +'use strict'; + +// This is a custom Jest transformer turning style imports into empty objects. +// http://facebook.github.io/jest/docs/en/webpack.html + +module.exports = { + process() { + return 'module.exports = {};'; + }, + getCacheKey() { + // The output is always the same. + return 'cssTransform'; + }, +}; diff --git a/config/jest/fileTransform.js b/config/jest/fileTransform.js new file mode 100644 index 000000000..9e4047d35 --- /dev/null +++ b/config/jest/fileTransform.js @@ -0,0 +1,12 @@ +'use strict'; + +const path = require('path'); + +// This is a custom Jest transformer turning file imports into filenames. +// http://facebook.github.io/jest/docs/en/webpack.html + +module.exports = { + process(src, filename) { + return `module.exports = ${JSON.stringify(path.basename(filename))};`; + }, +}; diff --git a/config/nodemon/relay-stream.json b/config/nodemon/relay-stream.json new file mode 100644 index 000000000..dc9556823 --- /dev/null +++ b/config/nodemon/relay-stream.json @@ -0,0 +1,8 @@ +{ + "exec": "npm-run-all compile:relay-stream", + "ext": "ts,tsx,graphql", + "watch": [ + "./src/core/client/stream", + "./src/core/**/*.graphql" + ] +} diff --git a/config/nodemon/server.json b/config/nodemon/server.json new file mode 100644 index 000000000..08472086e --- /dev/null +++ b/config/nodemon/server.json @@ -0,0 +1,10 @@ +{ + "exec": "npm run start:development", + "ext": "ts,graphql", + "watch": [ + "./src" + ], + "ignore": [ + "./src/client" + ] +} diff --git a/config/paths.js b/config/paths.js new file mode 100644 index 000000000..4d852d0f6 --- /dev/null +++ b/config/paths.js @@ -0,0 +1,65 @@ +"use strict"; + +// A script from `create-react-app` ejected `25.06.2018`. + +const path = require("path"); +const fs = require("fs"); +const url = require("url"); + +// Make sure any symlinks in the project folder are resolved: +// https://github.com/facebookincubator/create-react-app/issues/637 +const appDirectory = fs.realpathSync(process.cwd()); +const resolveApp = relativePath => path.resolve(appDirectory, relativePath); + +const envPublicUrl = process.env.PUBLIC_URL; + +function ensureSlash(p, needsSlash) { + const hasSlash = p.endsWith("/"); + if (hasSlash && !needsSlash) { + return p.substr(p, p.length - 1); + } else if (!hasSlash && needsSlash) { + return `${p}/`; + } else { + return p; + } +} + +const getPublicUrl = appPackageJson => + envPublicUrl || require(appPackageJson).homepage; + +// We use `PUBLIC_URL` environment variable or "homepage" field to infer +// "public path" at which the app is served. +// Webpack needs to know it to put the right