@nsidc/snow-today-webapp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.circleci/config.yml +112 -0
  2. package/.dockerignore +2 -0
  3. package/.eslintrc.js +43 -0
  4. package/.stylelintrc.json +6 -0
  5. package/CODE_OF_CONDUCT.md +76 -0
  6. package/Dockerfile +40 -0
  7. package/LICENSE +21 -0
  8. package/README.md +60 -0
  9. package/doc/TODO.md +14 -0
  10. package/doc/_images/snow-today-screenshot.png +0 -0
  11. package/doc/architecture.md +24 -0
  12. package/doc/development.md +34 -0
  13. package/docker-compose.dev.yml +21 -0
  14. package/docker-compose.live.yml +8 -0
  15. package/docker-compose.yml +21 -0
  16. package/index.html +13 -0
  17. package/jest/README.md +8 -0
  18. package/jest/scripts/setupTests.ts +5 -0
  19. package/jest/scripts/test.js +19 -0
  20. package/jest/transforms/babelTransform.js +29 -0
  21. package/jest/transforms/cssTransform.js +14 -0
  22. package/jest/transforms/fileTransform.js +42 -0
  23. package/nginx/default.conf +16 -0
  24. package/nginx/default.dataserver.conf +25 -0
  25. package/nginx/nginx.conf +33 -0
  26. package/nginx/openssl.conf +21 -0
  27. package/package.json +125 -0
  28. package/postcss.config.js +5 -0
  29. package/public/index.html +18 -0
  30. package/public/manifest.json +9 -0
  31. package/src/App.tsx +24 -0
  32. package/src/clientState/rasterOpacity/atom.ts +9 -0
  33. package/src/clientState/rasterOpacity/index.ts +3 -0
  34. package/src/clientState/selectedBasemap/atom.ts +10 -0
  35. package/src/clientState/selectedBasemap/index.ts +3 -0
  36. package/src/clientState/selectedBasemapObject.ts +21 -0
  37. package/src/clientState/selectedRegion/atom.ts +9 -0
  38. package/src/clientState/selectedRegion/index.ts +3 -0
  39. package/src/clientState/selectedRegionObject.ts +29 -0
  40. package/src/clientState/selectedSatelliteVariable/atom.ts +9 -0
  41. package/src/clientState/selectedSatelliteVariable/index.ts +3 -0
  42. package/src/clientState/selectedSatelliteVariableObject.ts +30 -0
  43. package/src/components/ControlPanel/BasemapSelector.tsx +26 -0
  44. package/src/components/ControlPanel/DebugDumpButton.tsx +21 -0
  45. package/src/components/ControlPanel/RasterOpacitySlider.tsx +24 -0
  46. package/src/components/ControlPanel/RegionSelector.tsx +62 -0
  47. package/src/components/ControlPanel/SatelliteVariableSelector.tsx +59 -0
  48. package/src/components/ControlPanel/index.tsx +32 -0
  49. package/src/components/LinePlot.tsx +142 -0
  50. package/src/components/SlippyMap.tsx +100 -0
  51. package/src/components/__tests__/BasemapSelector.tsx +25 -0
  52. package/src/constants/dataServer.ts +9 -0
  53. package/src/index.tsx +43 -0
  54. package/src/serverState/plotData.ts +28 -0
  55. package/src/serverState/regionShape.ts +22 -0
  56. package/src/serverState/regionsIndex.ts +26 -0
  57. package/src/serverState/variablesIndex.ts +26 -0
  58. package/src/style/App.css +25 -0
  59. package/src/style/BasemapSelector.css +7 -0
  60. package/src/style/ControlPanel.css +9 -0
  61. package/src/style/DebugDumpButton.css +9 -0
  62. package/src/style/LinePlot.css +9 -0
  63. package/src/style/RegionSelector.css +7 -0
  64. package/src/style/SlippyMap.css +19 -0
  65. package/src/style/VariableSelector.css +7 -0
  66. package/src/style/card.css +15 -0
  67. package/src/style/index.css +13 -0
  68. package/src/types/Basemap.ts +19 -0
  69. package/src/types/SlippyMap.ts +16 -0
  70. package/src/types/misc.ts +3 -0
  71. package/src/types/query/plotData.ts +9 -0
  72. package/src/types/query/regions.ts +11 -0
  73. package/src/types/query/satelliteVariables.ts +15 -0
  74. package/src/util/__tests__/colormap.ts +28 -0
  75. package/src/util/colormap.ts +48 -0
  76. package/src/util/fetch/plotData.ts +20 -0
  77. package/src/util/fetch/regions.ts +30 -0
  78. package/src/util/fetch/variables.ts +17 -0
  79. package/src/util/layer/basemaps.ts +118 -0
  80. package/src/util/layer/raster.ts +97 -0
  81. package/src/util/layer/regionShape.ts +45 -0
  82. package/src/util/layer/source.ts +28 -0
  83. package/src/util/layer/switch.ts +65 -0
  84. package/src/util/query.ts +4 -0
  85. package/src/util/sideEffects/slippyMap.ts +123 -0
  86. package/src/util/test.ts +13 -0
  87. package/tsconfig.json +31 -0
  88. package/webpack.config.js +76 -0
@@ -0,0 +1,112 @@
1
+ version: 2
2
+
3
+ setup: &setup
4
+ working_directory: ~/snow-today-webapp
5
+
6
+ jobs:
7
+ test-and-bundle:
8
+ <<: *setup
9
+ docker:
10
+ - image: cimg/node:18.7
11
+ steps:
12
+ - checkout
13
+ - run:
14
+ name: Install dependencies
15
+ command: npm ci
16
+ - run:
17
+ name: Lint
18
+ command: npm run lint
19
+ - run:
20
+ name: Test
21
+ command: npm run test
22
+ - run:
23
+ name: Build Bundle
24
+ command: npm run build
25
+ - persist_to_workspace:
26
+ root: ~/snow-today-webapp
27
+ paths: .
28
+
29
+ publish-bundle-to-npm:
30
+ <<: *setup
31
+ docker:
32
+ - image: cimg/node:18.7
33
+ steps:
34
+ - attach_workspace:
35
+ at: ~/snow-today-webapp
36
+ - run:
37
+ name: Publish NPM Package
38
+ command: |
39
+ echo "//registry.npmjs.org/:_authToken=$NPM_DEPLOY_TOKEN" > .npmrc
40
+ npm publish --access public
41
+
42
+
43
+ build-docker-image-and-sometimes-publish:
44
+ <<: *setup
45
+ docker:
46
+ - image: docker:20.10.3-git
47
+ steps:
48
+ - checkout
49
+ # `setup_remote_docker` defaults to 17.09.0 which doesn't work with the
50
+ # node image we're trying to build...
51
+ # https://support.circleci.com/hc/en-us/articles/360050934711
52
+ # https://discuss.circleci.com/t/docker-build-fails-with-nonsensical-eperm-operation-not-permitted-copyfile/37364
53
+ - setup_remote_docker:
54
+ version: 20.10.2
55
+ - run:
56
+ name: Build and push Docker image
57
+ command: |
58
+ IMAGE_NAME="nsidc/snow-today-webapp"
59
+
60
+ echo "\$CIRCLE_TAG: ${CIRCLE_TAG}"
61
+ echo "\$CIRCLE_BRANCH: ${CIRCLE_BRANCH}"
62
+
63
+ if [[ "${CIRCLE_TAG}" ]]; then
64
+ TAG=${CIRCLE_TAG}
65
+ elif [[ "${CIRCLE_BRANCH}" = "main" ]]; then
66
+ TAG="latest"
67
+ else
68
+ # We don't really want images named after tags cluttering up our
69
+ # DH repo, so we use workflow filters to prevent this job from
70
+ # being triggered on a branch. Change the filters if we change
71
+ # our mind.
72
+ TAG=${CIRCLE_BRANCH}
73
+ fi
74
+ echo "\$TAG: ${TAG}"
75
+
76
+
77
+ DOCKER_IMAGE="${IMAGE_NAME}:${TAG}"
78
+ docker build -t ${DOCKER_IMAGE} .
79
+ echo "Built: ${DOCKER_IMAGE}"
80
+
81
+ docker login -u ${DOCKER_USER} -p ${DOCKER_PASS}
82
+ docker push "${DOCKER_IMAGE}"
83
+
84
+ workflows:
85
+ version: 2
86
+
87
+ build:
88
+ jobs:
89
+ - test-and-bundle:
90
+ filters:
91
+ tags:
92
+ only: /.*/
93
+
94
+ - publish-bundle-to-npm:
95
+ context: org-global
96
+ requires:
97
+ - test-and-bundle
98
+ filters:
99
+ branches:
100
+ ignore: /.*/
101
+ tags:
102
+ only: /^v\d+\.\d+\.\d+([\-\.\w]*)?$/
103
+
104
+ - build-docker-image-and-sometimes-publish:
105
+ context: org-global
106
+ requires:
107
+ - test-and-bundle
108
+ filters:
109
+ branches:
110
+ only: main
111
+ tags:
112
+ only: /^v[0-9]+(\.[0-9]+)*(\.[\-a-zA-Z0-9]+)?$/
package/.dockerignore ADDED
@@ -0,0 +1,2 @@
1
+ node_modules/
2
+ tags
package/.eslintrc.js ADDED
@@ -0,0 +1,43 @@
1
+ module.exports = {
2
+ "parser": "@typescript-eslint/parser",
3
+ // The below config enables type-aware linting, but significantly slows down
4
+ // eslint.
5
+ // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/README.md#configuration
6
+ "parserOptions": {
7
+ "tsconfigRootDir": __dirname,
8
+ "project": ["./tsconfig.json"],
9
+ },
10
+ "plugins": [
11
+ "@typescript-eslint",
12
+ "react-hooks",
13
+ ],
14
+ "extends": [
15
+ "react-app",
16
+ "react-app/jest",
17
+ "plugin:@typescript-eslint/recommended",
18
+ "plugin:@typescript-eslint/recommended-requiring-type-checking",
19
+ ],
20
+ "rules": {
21
+ "eqeqeq": [
22
+ "error",
23
+ ],
24
+ "react/function-component-definition": [
25
+ "error",
26
+ {
27
+ "namedComponents": "arrow-function",
28
+ "unnamedComponents": "arrow-function",
29
+ },
30
+ ],
31
+ "react-hooks/rules-of-hooks": "error",
32
+ "react-hooks/exhaustive-deps": "warn",
33
+ "@typescript-eslint/ban-ts-comment": [
34
+ "warn",
35
+ {
36
+ "ts-ignore": "allow-with-description",
37
+ },
38
+ ],
39
+ "@typescript-eslint/no-explicit-any": [
40
+ "warn",
41
+ ]
42
+ },
43
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": ["stylelint-config-standard"],
3
+ "customSyntax": "postcss-less",
4
+ "rules": {
5
+ }
6
+ }
@@ -0,0 +1,76 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at nsidc@nsidc.org. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
74
+
75
+ For answers to common questions about this code of conduct, see
76
+ https://www.contributor-covenant.org/faq
package/Dockerfile ADDED
@@ -0,0 +1,40 @@
1
+ FROM node:18-alpine AS builder
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package* ./
6
+ # Install from lockfile
7
+ RUN npm ci
8
+
9
+ # NOTE: _DO NOT_ copy node_modules, that would overwrite the install we just
10
+ # did.
11
+ # COPY scripts ./scripts
12
+ COPY src ./src
13
+ COPY index.html ./
14
+ COPY webpack.config.js tsconfig.json .eslintrc.js .stylelintrc.json ./
15
+
16
+ ARG env="production"
17
+ RUN if [ "$env" = "production" ]; then \
18
+ npm run build; \
19
+ fi
20
+
21
+ # These lines are only required to use this stage of the build to run a dev
22
+ # server (see docker-compose.dev.yml).
23
+ EXPOSE 3000
24
+ CMD ["npm", "run", "serve"]
25
+
26
+
27
+ FROM nginx:1.23-alpine AS server
28
+
29
+ WORKDIR /usr/share/nginx/html
30
+ COPY --from=builder /app/dist .
31
+
32
+ # Make a self-signed SSL certificate
33
+ RUN mkdir /cert
34
+ COPY ./nginx/openssl.conf .
35
+ RUN apk add openssl
36
+ RUN openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -config openssl.conf \
37
+ -keyout /cert/ssl.key -out /cert/ssl.crt
38
+
39
+ COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
40
+ COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Regents of the University of Colorado
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice (if present) and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # Snow Today Webapp
2
+
3
+ ![Snow Today screenshot](doc/_images/snow-today-screenshot.png)
4
+
5
+ Enable users to browse daily snow variables in various regions (South-West US, maybe
6
+ eventually High Mountain Asia).
7
+
8
+ Depends on [Snow Today Webapp Server](https://github.com/nsidc/snow-today-webapp-server)
9
+ to function.
10
+
11
+ **WARNING: This software is currently in early development. The data required for the
12
+ server component is not yet publicly exposed, so you should not expect this to work on
13
+ your machine.**
14
+
15
+
16
+ ## Level of Support
17
+
18
+ This repository is not actively supported by NSIDC but we welcome issue submissions and
19
+ pull requests in order to foster community contribution.
20
+
21
+ See the [LICENSE](LICENSE) for details on permissions and warranties. Please contact
22
+ nsidc@nsidc.org for more information.
23
+
24
+
25
+ ## Requirements
26
+
27
+ This package requires either Docker or the NPM environment described by `package.json`.
28
+
29
+
30
+ ## Installation
31
+
32
+ ```
33
+ docker-compose build
34
+ ```
35
+
36
+
37
+ ## Usage
38
+
39
+ ```
40
+ docker-compose up
41
+ ```
42
+
43
+
44
+ ## Troubleshooting
45
+
46
+ *TODO*
47
+
48
+
49
+ ## License
50
+
51
+ See [LICENSE](LICENSE).
52
+
53
+ ## Code of Conduct
54
+
55
+ See [Code of Conduct](CODE_OF_CONDUCT.md).
56
+
57
+ ## Credit
58
+
59
+ This software was developed by the National Snow and Ice Data Center with funding from
60
+ multiple sources.
package/doc/TODO.md ADDED
@@ -0,0 +1,14 @@
1
+ # TODO
2
+
3
+ ## Names
4
+
5
+ * RasterVariable -> SatelliteDataVariable ?
6
+
7
+ ## Versioning
8
+
9
+ * Version this app!
10
+ * CHANGELOG
11
+ * How to keep track of compatibility between the server (data schemas) and this app
12
+ (query types)? Can we write a utility that analyzes jsonschema files with typescript
13
+ type definitions for compatibility? Maybe we could use `typescript-json-schema` to
14
+ convert the Typescript interfaces to JSON schemas and diff?
@@ -0,0 +1,24 @@
1
+ # Architecture
2
+
3
+ This application has a client which runs in a user's browser that is responsible for
4
+ fetching data and visualizing it, and a server which is responsible for serving up
5
+ static data files generated in combination by code in this repository and external code
6
+ running on external systems.
7
+
8
+
9
+ ## Client
10
+
11
+ This repository contains a Typescript codebase for visualizing various data stored on a
12
+ server.
13
+
14
+ The client uses OpenLayers to display geospatial data, and ??? to display plots. It uses
15
+ `react-query` to manage many communications with the server, but for fetching
16
+ Cloud-Optimized GeoTIFFs, OpenLayers directly communicates with the server.
17
+
18
+
19
+ ## Server
20
+
21
+ The server is required for the client to function. The server is a simple HTTP server,
22
+ e.g. NGINX or Apache, serving static data files which must be structured in a specific
23
+ layout. See the [Snow Today Webapp Server
24
+ repository](https://github.com/nsidc/snow-today-webapp-server) for details.
@@ -0,0 +1,34 @@
1
+ # Development
2
+
3
+ To use the development configuration, create a compose override file:
4
+
5
+ ```
6
+ ln -s docker-compose.dev.yml docker-compose.override.yml
7
+ ```
8
+
9
+
10
+ ## State management
11
+
12
+ This app uses Recoil for state management.
13
+
14
+ Recoil freezes all objects used for state, so do not use objects that are expected to be
15
+ mutated in state, e.g. Layer objects. They are OK in derived state (with
16
+ `allowDangerousMutations`), but not state that will be directly updated.
17
+
18
+
19
+ ## Cloud-Optimized GeoTIFFs
20
+
21
+ The raster data is stored in COGs accessed by HTTP.
22
+
23
+ The COGs _must_ be in the same projection as the OpenLayers map in order to properly
24
+ display. A script `scripts/make_cogs.sh` can prepare the files correctly.
25
+
26
+
27
+ ## TODO
28
+
29
+ ### GeoTIFF Hosting
30
+
31
+ How are we going to deploy the server hosting the GeoTIFFs?
32
+
33
+ What's the simplest way to access those images in dev? Should we break that part into a
34
+ different repo?
@@ -0,0 +1,21 @@
1
+ version: '3.4'
2
+
3
+ services:
4
+ webapp:
5
+ build:
6
+ context: "."
7
+ target: "builder"
8
+ args:
9
+ - "env=dev"
10
+ image: "nsidc/snow-today-webapp:dev"
11
+ restart: "on-failure"
12
+ # Useful to skip linting errors and expose compiler errors:
13
+ # command: 'npm run serve:nolint'
14
+ ports:
15
+ # Webpack dev server and websocket for hot reload:
16
+ - "8080:8080"
17
+ volumes:
18
+ - "./src:/app/src:ro"
19
+ - "./index.html:/app/index.html:ro"
20
+ - "./public:/app/public:ro"
21
+ - "./.eslintrc.js:/app/.eslintrc.js:ro"
@@ -0,0 +1,8 @@
1
+ version: '3.4'
2
+
3
+ services:
4
+ webapp:
5
+ ports:
6
+ - "80:80"
7
+ - "443:443"
8
+ restart: always
@@ -0,0 +1,21 @@
1
+ # WARNING: This compose file alone will not yield a working stack. It is
2
+ # intended for use with an override (included).
3
+ version: '3.4'
4
+
5
+ services:
6
+ webapp:
7
+ image: "nsidc/snow-today-webapp:${APP_VERSION:-latest}"
8
+ # TODO: Pull, don't build in non-dev
9
+ build: .
10
+ logging:
11
+ options:
12
+ max-size: "10m"
13
+ max-file: "10"
14
+
15
+ data-server:
16
+ image: "nginx:1.23"
17
+ volumes:
18
+ - "/share/apps/snow-today:/usr/share/nginx/html:ro"
19
+ - "./nginx/default.dataserver.conf:/etc/nginx/conf.d/default.conf:ro"
20
+ ports:
21
+ - "8000:80"
package/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset="utf-8" />
6
+ <title>Snow Today</title>
7
+ </head>
8
+
9
+ <body>
10
+ <div id="root"></div>
11
+ </body>
12
+
13
+ </html>
package/jest/README.md ADDED
@@ -0,0 +1,8 @@
1
+ Some Jest config (e.g. transpiling with Babel) bootstrapped from `react-scripts` ([MIT
2
+ License](https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/LICENSE).
3
+
4
+ # TODO
5
+
6
+ * Consider using the documented `__mocks__` method to handle static assets
7
+ (https://jestjs.io/docs/webpack) instead of the `react-scripts` way. Everest-UI uses
8
+ the Jest-documented way.
@@ -0,0 +1,5 @@
1
+ // jest-dom adds custom jest matchers for asserting on DOM nodes.
2
+ // allows you to do things like:
3
+ // expect(element).toHaveTextContent(/react/i)
4
+ // learn more: https://github.com/testing-library/jest-dom
5
+ import '@testing-library/jest-dom';
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+
3
+ // Do this as the first thing so that any code reading it knows the right env.
4
+ process.env.BABEL_ENV = 'test';
5
+ process.env.NODE_ENV = 'test';
6
+ process.env.PUBLIC_URL = '';
7
+
8
+ // Makes the script crash on unhandled rejections instead of silently
9
+ // ignoring them. In the future, promise rejections that are not handled will
10
+ // terminate the Node.js process with a non-zero exit code.
11
+ process.on('unhandledRejection', err => {
12
+ throw err;
13
+ });
14
+
15
+ const jest = require('jest');
16
+ const execSync = require('child_process').execSync;
17
+ let argv = process.argv.slice(2);
18
+
19
+ jest.run(argv);
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ const babelJest = require('babel-jest').default;
4
+
5
+ const hasJsxRuntime = (() => {
6
+ if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
7
+ return false;
8
+ }
9
+
10
+ try {
11
+ require.resolve('react/jsx-runtime');
12
+ return true;
13
+ } catch (e) {
14
+ return false;
15
+ }
16
+ })();
17
+
18
+ module.exports = babelJest.createTransformer({
19
+ presets: [
20
+ [
21
+ require.resolve('babel-preset-react-app'),
22
+ {
23
+ runtime: hasJsxRuntime ? 'automatic' : 'classic',
24
+ },
25
+ ],
26
+ ],
27
+ babelrc: false,
28
+ configFile: false,
29
+ });
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ // This is a custom Jest transformer turning style imports into empty objects.
4
+ // http://facebook.github.io/jest/docs/en/webpack.html
5
+
6
+ module.exports = {
7
+ process() {
8
+ return {code: 'module.exports = {};'};
9
+ },
10
+ getCacheKey() {
11
+ // The output is always the same.
12
+ return 'cssTransform';
13
+ },
14
+ };
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const camelcase = require('camelcase');
5
+
6
+ // This is a custom Jest transformer turning file imports into filenames.
7
+ // http://facebook.github.io/jest/docs/en/webpack.html
8
+
9
+ module.exports = {
10
+ process(src, filename) {
11
+ const assetFilename = JSON.stringify(path.basename(filename));
12
+
13
+ if (filename.match(/\.svg$/)) {
14
+ // Based on how SVGR generates a component name:
15
+ // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
16
+ const pascalCaseFilename = camelcase(path.parse(filename).name, {
17
+ pascalCase: true,
18
+ });
19
+ const componentName = `Svg${pascalCaseFilename}`;
20
+ return {
21
+ code: `const React = require('react');
22
+ module.exports = {
23
+ __esModule: true,
24
+ default: ${assetFilename},
25
+ ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
26
+ return {
27
+ $$typeof: Symbol.for('react.element'),
28
+ type: 'svg',
29
+ ref: ref,
30
+ key: null,
31
+ props: Object.assign({}, props, {
32
+ children: ${assetFilename}
33
+ })
34
+ };
35
+ }),
36
+ };`
37
+ };
38
+ }
39
+
40
+ return {code: `module.exports = ${assetFilename};`};
41
+ },
42
+ };
@@ -0,0 +1,16 @@
1
+ server {
2
+ listen 80;
3
+ listen 443 ssl;
4
+ ssl_certificate /cert/ssl.crt;
5
+ ssl_certificate_key /cert/ssl.key;
6
+
7
+ server_name localhost;
8
+
9
+ real_ip_header X-Forwarded-For;
10
+ real_ip_recursive on;
11
+
12
+ location / {
13
+ root /usr/share/nginx/html;
14
+ autoindex on;
15
+ }
16
+ }