diff --git a/.env b/.env index cee601ef1..840315ca6 100644 --- a/.env +++ b/.env @@ -1,2 +1 @@ REACT_APP_PLATFORM_VERSION=$npm_package_version -NODE_PATH=./ \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..e4135b230 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,6 @@ +node_modules +functions +functions-cron +build +cypress +lib \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 5b4e80e1b..5a16d1eb0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,5 +1,6 @@ +// https://www.robertcooper.me/using-eslint-and-prettier-in-a-typescript-project + { -<<<<<<< HEAD "parser": "@typescript-eslint/parser", "extends": [ "plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react @@ -12,14 +13,6 @@ "version": "detect" } }, - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true, - "modules": true - } - }, "rules": { "prettier/prettier": "warn", "@typescript-eslint/no-inferrable-types": "off", diff --git a/.firebase/hosting.YnVpbGQ.cache b/.firebase/hosting.YnVpbGQ.cache deleted file mode 100644 index 7c38ba991..000000000 --- a/.firebase/hosting.YnVpbGQ.cache +++ /dev/null @@ -1,10 +0,0 @@ -asset-manifest.json,1537949860342,0d87381706f5f063fe1f904b9b48417707c24b21a182d3ee99fa89aa32eb7916 -index.html,1537949860341,0e551be718bd77c91037eea185f2f2cf153d96a0d895d82228ba17f17a885192 -manifest.json,1537949850681,65d4aa66cd0b8963e88196705111adfccad2e8b80725b6a7a82ca8a9a0de8889 -favicon.ico,1537949850677,eae62e993eb980ec8a25058c39d5a51feab118bd2100c4deebb2a9c158ec11f9 -service-worker.js,1537949860446,db8526deabb1a10c3ad5db7712a840a9e585839d6f1d924a9392fb731d3b0dab -static/css/main.29266132.css.map,1537949860350,3d32ace435910b3df426d546fd9fe5c6403cf4581bc6c81785bfce6c569cc62d -static/css/main.29266132.css,1537949860350,0d737eb0d4b0dc1f4aea758db2c583db32d7497cc58bde8bb1ee92df806392fd -static/media/logo.5d5d9eef.svg,1537949860349,c0528de9db7d849577b204745e2df806c06fc14e27faf121c417111680b4280d -static/js/main.3248e625.js,1537949860349,550f3079b50bdde4f0151fc53edddf6b2a2852142e7c540b2f83c61c0c753dfb -static/js/main.3248e625.js.map,1537949860351,b0cd5913da52648efa5541fff343702ebd10b058a621a6f76325eaddb837d00a diff --git a/.gitignore b/.gitignore index da4999961..f204a8f0b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ npm-debug.log* yarn-debug.log* yarn-error.log* .vscode +.firebase/ # IntelliJ /.idea diff --git a/.huskyrc b/.huskyrc deleted file mode 100644 index 05ea0d92b..000000000 --- a/.huskyrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "hooks": { - "pre-commit": "lint-staged" - } -} \ No newline at end of file diff --git a/.lintstagedrc b/.lintstagedrc deleted file mode 100644 index 5e86c79ea..000000000 --- a/.lintstagedrc +++ /dev/null @@ -1,18 +0,0 @@ -{ - "linters": { - "src/**/*.{ts,tsx}": [ - "tslint --project tsconfig.json --config tslint.json" - ], - "cypress/**/*.{ts,tsx}": [ - "tslint --project cypress/tsconfig.json --config tslint.json" - ], - "*.{js,jsx}": [ - "tslint" - ], - "*.+(js|jsx|json|yml|yaml|css|less|scss|ts|tsx|md|graphql|mdx)": [ - "prettier --write", - "git add" - ] - }, - "ignore": ["functions/**",".storybook/**",config/**] -} diff --git a/.travis.yml b/.travis.yml index 75c2af247..603ea2142 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,15 +82,15 @@ jobs: - CI_NODE=1 <<: *_test_defaults # Note, Travis jobs combined with regular stage scripts below - # Deploy - Firebase deployment to dev/prod depending on branch + # Deploy - Firebase deployment to dev/prod depending on branch on push (not PR) - stage: Deploy Dev - if: branch = master + if: branch = master AND type = push script: # Note - syntax different from above as merging into array instead of creating key:value - *_predeploy_defaults - bash scripts/deploy.dev.sh - stage: Deploy Production - if: branch = production + if: branch = production AND type = push script: - *_predeploy_defaults - bash scripts/deploy.prod.sh diff --git a/UPGRADING.md b/UPGRADING.md deleted file mode 100644 index 0d7fe76c6..000000000 --- a/UPGRADING.md +++ /dev/null @@ -1,13 +0,0 @@ -The app has been ejected from create-react-app which makes upgrading more difficult. - -The current method consists of: - -1. Create a new project with create react app, making sure `--typescript` flag specified -2. Manually compare config/\*, package.json, tsconfig for changes -3. Update accordingly -4. Test -5. Fix - -Note, currently there should be no explicit changes to - -http://russelljanderson.com/updating-create-react-app/ diff --git a/config-overrides.js b/config-overrides.js new file mode 100644 index 000000000..c01b87684 --- /dev/null +++ b/config-overrides.js @@ -0,0 +1,86 @@ +/* + Custom overrides for default create-react-app build + Automatically read by react-app-rewired scripts + + Overrides: + - Add custom service worker behaviour +*/ +//eslint-disable-next-line +const WorkboxWebpackPlugin = require('workbox-webpack-plugin') +module.exports = function override(config, env) { + config.plugins = config.plugins.map(plugin => { + if (plugin.constructor.name === 'GenerateSW') { + return swPlugin() + } + return plugin + }) + return config +} + +/** + * Custom service worker plugin + */ +function swPlugin() { + return new WorkboxWebpackPlugin.GenerateSW({ + cacheId: 'oa', + clientsClaim: true, + skipWaiting: true, + // NOTE 2020-01-14 CC - Add support to cache firebase storage and map tiles + runtimeCaching: [ + { + urlPattern: new RegExp(/.*\.(?:png|gif|jpg|jpeg|webp|svg).*/gi), + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'oa-images', + fetchOptions: { + credentials: 'same-origin', + mode: 'cors', + }, + backgroundSync: { + name: 'oa-images-background', + options: { + maxRetentionTime: 60 * 60 * 24, + }, + }, + expiration: { + maxAgeSeconds: 60 * 60 * 24 * 365, + maxEntries: 1000, + }, + matchOptions: { + ignoreSearch: true, + }, + }, + }, + { + urlPattern: new RegExp('^https://firebasestorage\\.googleapis\\.com/'), + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'oa-other', + fetchOptions: { + credentials: 'same-origin', + mode: 'cors', + }, + matchOptions: { + ignoreSearch: true, + }, + }, + }, + { + urlPattern: new RegExp('^https://firestore\\.googleapis\\.com/'), + handler: 'NetworkOnly', + }, + ], + // end update 2020-01-14 + exclude: [/\.map$/, /asset-manifest\.json$/], + importWorkboxFrom: 'cdn', + navigateFallback: '/index.html', + navigateFallbackWhitelist: [/^(?!\/__)/], + navigateFallbackBlacklist: [ + // Exclude URLs starting with /_, as they're likely an API call + new RegExp('^/_'), + // Exclude URLs containing a dot, as they're likely a resource in + // public/ and not a SPA route + new RegExp('/[^/]+\\.[^/]+$'), + ], + }) +} diff --git a/config/env.js b/config/env.js deleted file mode 100644 index 000a02e2e..000000000 --- a/config/env.js +++ /dev/null @@ -1,93 +0,0 @@ -'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/facebook/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/facebook/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 REACT_APP_* environment variables and prepare them to be -// injected into the application via DefinePlugin in Webpack configuration. -const REACT_APP = /^REACT_APP_/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/enzyme.js b/config/enzyme.js deleted file mode 100644 index 7b74d5925..000000000 --- a/config/enzyme.js +++ /dev/null @@ -1,4 +0,0 @@ -import enzyme from 'enzyme' -import Adapter from 'enzyme-adapter-react-16' - -enzyme.configure({ adapter: new Adapter() }) diff --git a/config/jest/cssTransform.js b/config/jest/cssTransform.js deleted file mode 100644 index 8f6511481..000000000 --- a/config/jest/cssTransform.js +++ /dev/null @@ -1,14 +0,0 @@ -'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 deleted file mode 100644 index 07010e33a..000000000 --- a/config/jest/fileTransform.js +++ /dev/null @@ -1,30 +0,0 @@ -'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) { - const assetFilename = JSON.stringify(path.basename(filename)); - - if (filename.match(/\.svg$/)) { - return `module.exports = { - __esModule: true, - default: ${assetFilename}, - ReactComponent: (props) => ({ - $$typeof: Symbol.for('react.element'), - type: 'svg', - ref: null, - key: null, - props: Object.assign({}, props, { - children: ${assetFilename} - }) - }), - };`; - } - - return `module.exports = ${assetFilename};`; - }, -}; diff --git a/config/jest/typescriptTransform.js b/config/jest/typescriptTransform.js deleted file mode 100644 index 9b138ac8e..000000000 --- a/config/jest/typescriptTransform.js +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -'use strict'; - -const tsJestPreprocessor = require('ts-jest/preprocessor'); - -module.exports = tsJestPreprocessor; diff --git a/config/paths.js b/config/paths.js deleted file mode 100644 index c24b4dd1f..000000000 --- a/config/paths.js +++ /dev/null @@ -1,89 +0,0 @@ -'use strict'; - -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/facebook/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(inputPath, needsSlash) { - const hasSlash = inputPath.endsWith('/'); - if (hasSlash && !needsSlash) { - return inputPath.substr(0, inputPath.length - 1); - } else if (!hasSlash && needsSlash) { - return `${inputPath}/`; - } else { - return inputPath; - } -} - -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