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