├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .esdoc.json ├── .eslintignore ├── .eslintrc ├── .flowconfig ├── .github ├── dependabot.yml └── workflows │ ├── chromatic.yml │ ├── ci.yml │ ├── codeql-analysis.yml │ ├── dependabot.yml │ ├── flow-typed.yml │ └── rebase.yml ├── .gitignore ├── .husky └── pre-commit ├── .lintstagedrc.js ├── .mailmap ├── .markdownlintrc ├── .npmpackagejsonlintrc.json ├── .prettierrc ├── .storybook ├── main.js └── preview.js ├── .stylelintrc ├── .yarn └── releases │ └── yarn-1.22.19.cjs ├── .yarnrc.yml ├── CITATION.cff ├── CODE_OF_CONDUCT.md ├── LICENSE.md ├── README.md ├── flow-typed └── npm │ ├── @babel │ └── eslint-parser_vx.x.x.js │ ├── @chromatic-com │ └── storybook_vx.x.x.js │ ├── @michaelmior │ └── js-sql-parser_vx.x.x.js │ ├── @reduxjs │ └── toolkit_v1.x.x.js │ ├── @sebastianwessel │ ├── esdoc-ecmascript-proposal-plugin_vx.x.x.js │ ├── esdoc-flow-type-plugin_vx.x.x.js │ ├── esdoc-jsx-plugin_vx.x.x.js │ ├── esdoc-react-plugin_vx.x.x.js │ ├── esdoc-standard-plugin_vx.x.x.js │ └── esdoc_vx.x.x.js │ ├── @sentry │ ├── browser_vx.x.x.js │ └── cli_vx.x.x.js │ ├── @storybook │ ├── addon-actions_vx.x.x.js │ ├── addon-essentials_vx.x.x.js │ ├── addon-interactions_vx.x.x.js │ ├── addon-links_vx.x.x.js │ ├── builder-webpack4_vx.x.x.js │ ├── builder-webpack5_vx.x.x.js │ ├── manager-webpack4_vx.x.x.js │ ├── manager-webpack5_vx.x.x.js │ ├── node-logger_vx.x.x.js │ ├── preset-create-react-app_vx.x.x.js │ ├── react-webpack5_vx.x.x.js │ ├── react_v6.x.x.js │ ├── react_vx.x.x.js │ └── testing-library_vx.x.x.js │ ├── @testing-library │ ├── jest-dom_vx.x.x.js │ ├── react_v12.x.x.js │ ├── react_v14.x.x.js │ └── react_vx.x.x.js │ ├── @welldone-software │ └── why-did-you-render_vx.x.x.js │ ├── @wojtekmaj │ └── enzyme-adapter-react-17_vx.x.x.js │ ├── bundlewatch_vx.x.x.js │ ├── chromatic_vx.x.x.js │ ├── connected-react-router_vx.x.x.js │ ├── coveralls_vx.x.x.js │ ├── deep-freeze_v0.0.1.js │ ├── enzyme_v3.x.x.js │ ├── eslint-plugin-flowtype_vx.x.x.js │ ├── eslint-plugin-yaml_vx.x.x.js │ ├── fast-equals_vx.x.x.js │ ├── flow-bin_v0.x.x.js │ ├── fromentries_vx.x.x.js │ ├── history_v5.x.x.js │ ├── husky_vx.x.x.js │ ├── jest-each_vx.x.x.js │ ├── jest_v25.x.x.js │ ├── jest_v29.x.x.js │ ├── lint-staged_vx.x.x.js │ ├── lodash_v4.x.x.js │ ├── markdownlint-cli_vx.x.x.js │ ├── npm-package-json-lint-config-default_vx.x.x.js │ ├── npm-package-json-lint_vx.x.x.js │ ├── pkg-ok_vx.x.x.js │ ├── prettier_v1.x.x.js │ ├── prettier_vx.x.x.js │ ├── pretty-quick_vx.x.x.js │ ├── prismjs_vx.x.x.js │ ├── react-cookie_vx.x.x.js │ ├── react-device-detect_vx.x.x.js │ ├── react-dom_v18.x.x.js │ ├── react-ga_vx.x.x.js │ ├── react-joyride_vx.x.x.js │ ├── react-redux_v8.x.x.js │ ├── react-redux_vx.x.x.js │ ├── react-router-dom_v6.x.x.js │ ├── react-router_v5.x.x.js │ ├── react-router_vx.x.x.js │ ├── react-scripts_vx.x.x.js │ ├── react-simple-code-editor_vx.x.x.js │ ├── react-simple-tree-menu_vx.x.x.js │ ├── react-split-pane_vx.x.x.js │ ├── react-table_vx.x.x.js │ ├── react-test-renderer_vx.x.x.js │ ├── redux-mock-store_v1.x.x.js │ ├── redux-thunk_v2.x.x.js │ ├── redux_v4.x.x.js │ ├── rimraf_v2.x.x.js │ ├── source-map-explorer_vx.x.x.js │ ├── storybook_vx.x.x.js │ ├── stylelint-config-standard_vx.x.x.js │ ├── stylelint_vx.x.x.js │ ├── tinyqueue_vx.x.x.js │ ├── typescript_vx.x.x.js │ ├── universal-cookie_vx.x.x.js │ ├── uuid_v8.x.x.js │ ├── uuid_vx.x.x.js │ └── webpack_v5.x.x.js ├── ignore_build.js ├── netlify.toml ├── package.json ├── pnpm-lock.yaml ├── public ├── 200.html ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── browserconfig.xml ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── index.html ├── manifest.json ├── mstile-144x144.png ├── mstile-150x150.png ├── mstile-310x150.png ├── mstile-310x310.png ├── mstile-70x70.png ├── opengraph.png ├── safari-pinned-tab.svg └── site.webmanifest └── src ├── App.js ├── App.test.js ├── BinaryRelOp.stories.js ├── CurrentRelExpr.js ├── CurrentRelExpr.test.js ├── DataContainer.js ├── DataContainer.test.js ├── EditorContainer.js ├── Home.css ├── Home.js ├── MultiTable.css ├── MultiTable.js ├── MultiTable.stories.js ├── MultiTable.test.js ├── RelExpr.css ├── RelExpr.js ├── RelExpr.stories.js ├── RelExpr.test.js ├── RelExprTree.css ├── RelExprTree.js ├── RelExprTree.stories.js ├── RelExprTree.test.js ├── RelOp.js ├── RelOp.test.js ├── Relation.css ├── Relation.js ├── Relation.test.js ├── SourceMultiTable.js ├── SqlEditor.css ├── SqlEditor.js ├── SqlEditor.test.js ├── Table.css ├── Table.js ├── Table.stories.js ├── Table.test.js ├── Tutorial.js ├── Tutorial.test.js ├── UnaryRelOp.stories.js ├── __snapshots__ ├── RelExpr.test.js.snap ├── RelExprTree.test.js.snap └── Tutorial.test.js.snap ├── index.css ├── index.js ├── modules ├── constructRelationalGraph.js ├── constructRelationalGraph.test.js ├── data.js ├── data.test.js ├── joinOrderOptimization.js ├── joinOrderOptimization.test.js ├── relexp.js ├── relexp.test.js └── types.js ├── resources ├── Department.json ├── Doctor.json └── Patient.json ├── setupTests.js ├── store.js ├── store.test.js ├── util.js ├── util.test.js └── wydr.js /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.192.0/containers/javascript-node/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] Node.js version: 16, 14, 12 4 | ARG VARIANT="16-buster" 5 | FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} 6 | 7 | # [Optional] Uncomment this section to install additional OS packages. 8 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 9 | # && apt-get -y install --no-install-recommends 10 | 11 | # [Optional] Uncomment if you want to install an additional version of node using nvm 12 | # ARG EXTRA_NODE_VERSION=10 13 | # RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" 14 | 15 | # [Optional] Uncomment if you want to install more global node modules 16 | # RUN su node -c "npm install -g " 17 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.192.0/containers/javascript-node 3 | { 4 | "name": "Node.js", 5 | "build": { 6 | "dockerfile": "Dockerfile", 7 | // Update 'VARIANT' to pick a Node version: 12, 14, 16 8 | "args": { "VARIANT": "12" } 9 | }, 10 | 11 | // Set *default* container specific settings.json values on container create. 12 | "settings": {}, 13 | 14 | // Add the IDs of extensions you want installed when the container is created. 15 | "extensions": [ 16 | "dbaeumer.vscode-eslint" 17 | ], 18 | 19 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 20 | // "forwardPorts": [], 21 | 22 | // Use 'postCreateCommand' to run commands after the container is created. 23 | "postCreateCommand": "yarn install", 24 | 25 | // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 26 | "remoteUser": "node" 27 | } 28 | -------------------------------------------------------------------------------- /.esdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": "./src", 3 | "destination": "./docs", 4 | "plugins": [ 5 | { 6 | "name": "@sebastianwessel/esdoc-standard-plugin", 7 | "option": { 8 | "coverage": {"enable": true}, 9 | "undocumentIdentifier": {"enable": true}, 10 | "unexportedIdentifier": {"enable": false}, 11 | "test": { 12 | "source": "./src/", 13 | "interfaces": ["describe", "it", "context", "suite", "test"], 14 | "includes": ["(spec|Spec|test|Test)\\.js$"] 15 | } 16 | } 17 | }, 18 | {"name": "@sebastianwessel/esdoc-react-plugin"}, 19 | {"name": "@sebastianwessel/esdoc-jsx-plugin", "option": {"enable": true}}, 20 | {"name": "@sebastianwessel/esdoc-flow-type-plugin", "option": {"enable": true}}, 21 | {"name": "@sebastianwessel/esdoc-ecmascript-proposal-plugin", "option": {"all": true}} 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | # Ignore json files 2 | build/ 3 | flow-typed/ 4 | node_modules/ 5 | storybook-static/ 6 | src/resources/* 7 | !.github 8 | !.travis.yml 9 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@babel/eslint-parser", 3 | "extends": [ 4 | "react-app", 5 | "plugin:flowtype/recommended", 6 | ], 7 | "plugins": [ 8 | "flowtype", 9 | ], 10 | "overrides" : [ 11 | { 12 | "files": ["*.yaml", "*.yml"], 13 | "plugins": ["yaml"], 14 | "extends": ["plugin:yaml/legacy"] 15 | } 16 | ], 17 | "rules": { 18 | "flowtype/space-after-type-colon": "off", 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | /node_modules/@storybook/.* 3 | .*/malformed_package_json/package.json 4 | 5 | [untyped] 6 | 7 | [include] 8 | 9 | [libs] 10 | 11 | [lints] 12 | 13 | [options] 14 | exact_by_default=false 15 | 16 | [strict] 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: '/' 5 | schedule: 6 | interval: daily 7 | time: '10:00' 8 | open-pull-requests-limit: 10 9 | groups: 10 | esdoc: 11 | patterns: 12 | - '@sebastianwessel/esdoc*' 13 | lint: 14 | patterns: 15 | - 'eslint-plugin-*' 16 | - 'lint-staged' 17 | - 'markdownlint-cli' 18 | - 'npm-package-json-lint*' 19 | - 'pkg-ok' 20 | - 'prettier' 21 | - 'stylelint*' 22 | react: 23 | patterns: 24 | - 'react' 25 | - 'react-dom' 26 | - 'react-test-renderer' 27 | react-router: 28 | patterns: 29 | - 'react-router*' 30 | sentry: 31 | patterns: 32 | - '@sentry/*' 33 | storybook: 34 | patterns: 35 | - 'storybook' 36 | - '@storybook/*' 37 | test: 38 | patterns: 39 | - '@wojtekmaj/enzyme-adapter-*' 40 | - 'enzyme' 41 | - 'jest-*' 42 | - 'redux-mock-store' 43 | -------------------------------------------------------------------------------- /.github/workflows/chromatic.yml: -------------------------------------------------------------------------------- 1 | # Workflow name 2 | name: 'Chromatic' 3 | 4 | # Event for the workflow 5 | on: push 6 | 7 | # List of jobs 8 | jobs: 9 | chromatic-deployment: 10 | # Operating System 11 | runs-on: ubuntu-latest 12 | # Job steps 13 | steps: 14 | - run: git config --global core.autocrlf input 15 | - uses: actions/checkout@v3 16 | with: 17 | fetch-depth: 0 18 | 19 | - uses: pnpm/action-setup@v4 20 | - uses: actions/setup-node@v3 21 | with: 22 | node-version: 18 23 | cache: 'pnpm' 24 | 25 | - name: Install dependencies 26 | run: pnpm install 27 | # 👇 Adds Chromatic as a step in the workflow 28 | - name: Publish to Chromatic 29 | uses: chromaui/action@v1 30 | with: 31 | projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} 32 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request] 3 | jobs: 4 | pre_job: 5 | name: Check duplicate 6 | runs-on: ubuntu-latest 7 | outputs: 8 | should_skip: ${{ steps.skip_check.outputs.should_skip }} 9 | steps: 10 | - id: skip_check 11 | uses: fkirc/skip-duplicate-actions@master 12 | with: 13 | cancel_others: true 14 | concurrent_skipping: same_content 15 | do_not_skip: '["pull_request", "schedule", "workflow_dispatch"]' 16 | 17 | build: 18 | name: Test 19 | needs: pre_job 20 | if: ${{ needs.pre_job.outputs.should_skip != 'true' }} 21 | runs-on: ${{ matrix.os }} 22 | strategy: 23 | matrix: 24 | os: [macos-latest, ubuntu-latest, windows-latest] 25 | steps: 26 | - run: git config --global core.autocrlf input 27 | - uses: actions/checkout@v3 28 | with: 29 | fetch-depth: 0 30 | 31 | - uses: pnpm/action-setup@v4 32 | - uses: actions/setup-node@v3 33 | with: 34 | node-version: 18 35 | cache: 'pnpm' 36 | 37 | - run: pnpm install 38 | - run: pnpm run lint 39 | - run: pnpm run flow 40 | - run: pnpm run test --coverage 41 | - run: pnpm run build 42 | - run: pnpm esdoc 43 | 44 | - name: BundleWatch 45 | env: 46 | BUNDLEWATCH_GITHUB_TOKEN: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }} 47 | CI_BRANCH_BASE: main 48 | if: ${{ matrix.os == 'ubuntu-latest' }} 49 | run: pnpm bundlewatch 50 | 51 | - name: Coveralls 52 | env: 53 | COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} 54 | if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/main' }} 55 | run: pnpm run coveralls 56 | shell: bash 57 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "Code scanning - action" 2 | 3 | on: 4 | pull_request: 5 | schedule: 6 | - cron: '0 21 * * 5' 7 | 8 | jobs: 9 | CodeQL-Build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v3 16 | with: 17 | # We must fetch at least the immediate parents so that if this is 18 | # a pull request then we can checkout the head. 19 | fetch-depth: 2 20 | 21 | # If this run was triggered by a pull request event, then checkout 22 | # the head of the pull request instead of the merge commit. 23 | - run: git checkout HEAD^2 24 | if: ${{ github.event_name == 'pull_request' }} 25 | 26 | # Initializes the CodeQL tools for scanning. 27 | - name: Initialize CodeQL 28 | uses: github/codeql-action/init@v1 29 | # Override language selection by uncommenting this and choosing your languages 30 | # with: 31 | # languages: go, javascript, csharp, python, cpp, java 32 | 33 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 34 | # If this step fails, then you should remove it and run the build manually (see below) 35 | - name: Autobuild 36 | uses: github/codeql-action/autobuild@v1 37 | 38 | # ℹ️ Command-line programs to run using the OS shell. 39 | # 📚 https://git.io/JvXDl 40 | 41 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 42 | # and modify them (or add more) to build your code if your project 43 | # uses a compiled language 44 | 45 | #- run: | 46 | # make bootstrap 47 | # make release 48 | 49 | - name: Perform CodeQL Analysis 50 | uses: github/codeql-action/analyze@v1 51 | -------------------------------------------------------------------------------- /.github/workflows/dependabot.yml: -------------------------------------------------------------------------------- 1 | name: Dependabot auto-merge 2 | on: pull_request 3 | 4 | permissions: 5 | contents: write 6 | pull-requests: write 7 | 8 | jobs: 9 | dependabot: 10 | runs-on: ubuntu-latest 11 | if: github.actor == 'dependabot[bot]' 12 | steps: 13 | - name: Dependabot metadata 14 | id: metadata 15 | uses: dependabot/fetch-metadata@v1 16 | with: 17 | github-token: "${{ secrets.GITHUB_TOKEN }}" 18 | - name: Enable auto-merge for Dependabot PRs 19 | if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || (steps.dependabot-metadata.outputs.dependency-type != 'direct:production' && steps.metadata.outputs.update-type == 'version-update:semver-minor') 20 | run: gh pr merge --auto --rebase "$PR_URL" 21 | env: 22 | PR_URL: ${{github.event.pull_request.html_url}} 23 | GH_TOKEN: ${{secrets.GITHUB_TOKEN}} 24 | -------------------------------------------------------------------------------- /.github/workflows/flow-typed.yml: -------------------------------------------------------------------------------- 1 | on: 2 | schedule: 3 | - cron: '0 2 * * 0' # every Sunday at 2am 4 | workflow_dispatch: 5 | name: Flow Typed 6 | jobs: 7 | flow-typed: 8 | name: Flow Typed 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v3 13 | with: 14 | ref: main 15 | 16 | - uses: pnpm/action-setup@v4 17 | - name: Set up node 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: 18 21 | - run: pnpm install --frozen-lockfile 22 | - run: npx flow-typed install 23 | 24 | - name: Create Pull Request 25 | uses: peter-evans/create-pull-request@v5 26 | with: 27 | title: 'Update flow-typed definitions' 28 | branch: flow-typed-update 29 | commit-message: "Update flow-typed definitions" 30 | delete-branch: true 31 | -------------------------------------------------------------------------------- /.github/workflows/rebase.yml: -------------------------------------------------------------------------------- 1 | on: 2 | issue_comment: 3 | types: [created] 4 | name: Automatic Rebase 5 | jobs: 6 | rebase: 7 | name: Rebase 8 | if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: 13 | fetch-depth: 0 14 | - name: Automatic Rebase 15 | uses: cirrus-actions/rebase@1.2 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | # https://github.community/t5/GitHub-Actions/Workflow-is-failing-if-no-job-can-be-ran-due-to-condition/m-p/38186#M3250 19 | always_job: 20 | name: Always run job 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Always run 24 | run: echo "This job is used to prevent the workflow to fail when all other jobs are skipped." 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | 23 | storybook-static/ 24 | docs/ 25 | build-storybook.log 26 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | yarn lint-staged 2 | -------------------------------------------------------------------------------- /.lintstagedrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "*.yml": [ 3 | "eslint" 4 | ], 5 | "src/**/*.{js,json}": [ 6 | "eslint --fix", 7 | "flow focus-check", 8 | "prettier --write" 9 | ], 10 | "src/**/*.css": [ 11 | "stylelint --fix", 12 | "prettier --write" 13 | ], 14 | "package.json": [ 15 | "npmPkgJsonLint -q .", 16 | () => "pkg-ok" 17 | ], 18 | "README.md": [ 19 | "markdownlint -f" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Michael Mior michaelmior 2 | dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> 3 | dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> dependabot-preview[bot] 4 | -------------------------------------------------------------------------------- /.markdownlintrc: -------------------------------------------------------------------------------- 1 | { 2 | "line_length": false, 3 | "html": { 4 | "allowed_elements": ["br"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.npmpackagejsonlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "npm-package-json-lint-config-default", 3 | "rules": { 4 | "no-archive-dependencies": "error", 5 | "no-file-dependencies": "error", 6 | "no-git-dependencies": "error", 7 | "prefer-alphabetical-dependencies": "error", 8 | "prefer-alphabetical-devDependencies": "error", 9 | "prefer-alphabetical-scripts": "error", 10 | "prefer-no-engineStrict": "error", 11 | "require-author": "error", 12 | "require-bugs": "error", 13 | "require-homepage": "error", 14 | "require-scripts": "error" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | bracketSpacing: false 2 | singleQuote: true 3 | trailingComma: es5 4 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | /** @type { import('@storybook/react).StorybookConfig } */ 2 | const config = { 3 | stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], 4 | addons: [ 5 | '@storybook/addon-links', 6 | '@storybook/addon-essentials', 7 | '@storybook/addon-interactions', 8 | '@storybook/preset-create-react-app', 9 | '@chromatic-com/storybook', 10 | ], 11 | framework: { 12 | name: '@storybook/react-webpack5', 13 | options: { 14 | lazyCompilation: true, 15 | }, 16 | }, 17 | }; 18 | export default config; 19 | -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | /** @type { import('@storybook/react').Preview } */ 2 | const preview = { 3 | parameters: { 4 | actions: {argTypesRegex: '^on[A-Z].*'}, 5 | controls: { 6 | matchers: { 7 | color: /(background|color)$/i, 8 | date: /Date$/, 9 | }, 10 | }, 11 | }, 12 | }; 13 | export default preview; 14 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard", 3 | "rules": { 4 | "color-hex-case": "upper", 5 | "selector-class-pattern": "^[a-z][a-zA-Z0-9]+$" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | yarnPath: .yarn/releases/yarn-1.22.19.cjs 2 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # YAML 1.2 2 | --- 3 | version: 1.0.3 4 | authors: 5 | - 6 | affiliation: "Rochester Institute of Technology" 7 | family-names: Mior 8 | given-names: "Michael Joseph" 9 | orcid: "https://orcid.org/0000-0002-4057-8726" 10 | cff-version: "1.0.3" 11 | date-released: 2023-06-23 12 | doi: "10.1145/3596673.3596978" 13 | license: "MIT" 14 | message: "If you use this software, please cite it using these metadata." 15 | repository-code: "https://github.com/dataunitylab/relational-playground" 16 | title: "Relational Playground: Teaching the Duality of Relational Algebra and SQL" 17 | ... 18 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © 2018-present Michael Mior 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the “Software”), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Relational Playground 2 | 3 | [![CI](https://github.com/dataunitylab/relational-playground/actions/workflows/ci.yml/badge.svg)](https://github.com/dataunitylab/relational-playground/actions/workflows/ci.yml) 4 | [![Coverage Status](https://coveralls.io/repos/github/dataunitylab/relational-playground/badge.svg?branch=main)](https://coveralls.io/github/dataunitylab/relational-playground?branch=main) 5 | 6 | [Relational Playground](https://relationalplayground.com/) is developed by the [Data Unity Lab](https://cs.rit.edu/~dataunitylab/) at the Rochester Institute of Technology. 7 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 8 | 9 | ## Available Scripts 10 | 11 | In the project directory, you can run: 12 | 13 | ### `pnpm start` 14 | 15 | Runs the app in the development mode.
16 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 17 | 18 | The page will reload if you make edits.
19 | You will also see any lint errors in the console. 20 | 21 | ### `pnpm test` 22 | 23 | Launches the test runner in the interactive watch mode.
24 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 25 | 26 | ### `pnpm build` 27 | 28 | Builds the app for production to the `build` folder.
29 | It correctly bundles React in production mode and optimizes the build for the best performance. 30 | 31 | The build is minified and the filenames include the hashes.
32 | 33 | ### `pnpm flow` 34 | 35 | Type check all files in the `src` folder using [Flow](https://flow.org/). 36 | This check will also be run before commits. 37 | 38 | ### `pnpm lint` 39 | 40 | Lint all files in `src` using [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/). 41 | Files which have changed are also linted before every commit. 42 | -------------------------------------------------------------------------------- /flow-typed/npm/@babel/eslint-parser_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: c81513856b16f61053c32496bbd0d52f 2 | // flow-typed version: <>/@babel/eslint-parser_v^7.27.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@babel/eslint-parser' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@babel/eslint-parser' { 17 | declare module.exports: any; 18 | } 19 | -------------------------------------------------------------------------------- /flow-typed/npm/@chromatic-com/storybook_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 33920b81d486ea74736fd0340c21d364 2 | // flow-typed version: <>/@chromatic-com/storybook_v^3.2.6/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@chromatic-com/storybook' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@chromatic-com/storybook' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@chromatic-com/storybook/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@chromatic-com/storybook/dist/preset' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@chromatic-com/storybook/preset' { 34 | declare module.exports: any; 35 | } 36 | 37 | // Filename aliases 38 | declare module '@chromatic-com/storybook/dist/index' { 39 | declare module.exports: $Exports<'@chromatic-com/storybook/dist'>; 40 | } 41 | declare module '@chromatic-com/storybook/dist/index.js' { 42 | declare module.exports: $Exports<'@chromatic-com/storybook/dist'>; 43 | } 44 | declare module '@chromatic-com/storybook/dist/preset.js' { 45 | declare module.exports: $Exports<'@chromatic-com/storybook/dist/preset'>; 46 | } 47 | declare module '@chromatic-com/storybook/preset.js' { 48 | declare module.exports: $Exports<'@chromatic-com/storybook/preset'>; 49 | } 50 | -------------------------------------------------------------------------------- /flow-typed/npm/@michaelmior/js-sql-parser_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 92222ed85f282b34cb82ad793921d159 2 | // flow-typed version: <>/@michaelmior/js-sql-parser_v^1.3.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@michaelmior/js-sql-parser' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@michaelmior/js-sql-parser' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@michaelmior/js-sql-parser/dist/parser/sqlParser' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@michaelmior/js-sql-parser/dist/parser/sqlParser.js' { 31 | declare module.exports: $Exports<'@michaelmior/js-sql-parser/dist/parser/sqlParser'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/@sebastianwessel/esdoc-ecmascript-proposal-plugin_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: b957c545d97ddb1a6c99ce87272200ab 2 | // flow-typed version: <>/@sebastianwessel/esdoc-ecmascript-proposal-plugin_v^2.1.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@sebastianwessel/esdoc-ecmascript-proposal-plugin' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@sebastianwessel/esdoc-ecmascript-proposal-plugin' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@sebastianwessel/esdoc-ecmascript-proposal-plugin/src/Plugin' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@sebastianwessel/esdoc-ecmascript-proposal-plugin/src/Plugin.js' { 31 | declare module.exports: $Exports<'@sebastianwessel/esdoc-ecmascript-proposal-plugin/src/Plugin'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/@sebastianwessel/esdoc-flow-type-plugin_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: ae0353acb4766d191a790ad8579d7265 2 | // flow-typed version: <>/@sebastianwessel/esdoc-flow-type-plugin_v^2.1.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@sebastianwessel/esdoc-flow-type-plugin' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@sebastianwessel/esdoc-flow-type-plugin' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@sebastianwessel/esdoc-flow-type-plugin/src/Plugin' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@sebastianwessel/esdoc-flow-type-plugin/src/Plugin.js' { 31 | declare module.exports: $Exports<'@sebastianwessel/esdoc-flow-type-plugin/src/Plugin'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/@sebastianwessel/esdoc-jsx-plugin_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 4285ab4cc19ee471dd12a9bc7abf3320 2 | // flow-typed version: <>/@sebastianwessel/esdoc-jsx-plugin_v^2.1.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@sebastianwessel/esdoc-jsx-plugin' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@sebastianwessel/esdoc-jsx-plugin' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@sebastianwessel/esdoc-jsx-plugin/src/Plugin' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@sebastianwessel/esdoc-jsx-plugin/src/Plugin.js' { 31 | declare module.exports: $Exports<'@sebastianwessel/esdoc-jsx-plugin/src/Plugin'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/@sebastianwessel/esdoc-react-plugin_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: b2c3af1c1a63a67b8c802a9e7b01bb6f 2 | // flow-typed version: <>/@sebastianwessel/esdoc-react-plugin_v^2.1.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@sebastianwessel/esdoc-react-plugin' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@sebastianwessel/esdoc-react-plugin' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@sebastianwessel/esdoc-react-plugin/src/Plugin' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@sebastianwessel/esdoc-react-plugin/src/Plugin.js' { 31 | declare module.exports: $Exports<'@sebastianwessel/esdoc-react-plugin/src/Plugin'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/@sebastianwessel/esdoc-standard-plugin_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 0faebaef29efdeec3411bf3f5ac110b6 2 | // flow-typed version: <>/@sebastianwessel/esdoc-standard-plugin_v^2.1.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@sebastianwessel/esdoc-standard-plugin' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@sebastianwessel/esdoc-standard-plugin' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@sebastianwessel/esdoc-standard-plugin/src/Plugin' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@sebastianwessel/esdoc-standard-plugin/src/Plugin.js' { 31 | declare module.exports: $Exports<'@sebastianwessel/esdoc-standard-plugin/src/Plugin'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/@sentry/cli_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: a488ce225114838af338f85f8c01fd99 2 | // flow-typed version: <>/@sentry/cli_v^2.41.1/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@sentry/cli' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@sentry/cli' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@sentry/cli/js/helper' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@sentry/cli/js' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@sentry/cli/js/logger' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module '@sentry/cli/js/releases' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module '@sentry/cli/js/releases/options/deploys' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module '@sentry/cli/js/releases/options/uploadSourcemaps' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module '@sentry/cli/scripts/install' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module '@sentry/cli/scripts/test-vercel-nft' { 54 | declare module.exports: any; 55 | } 56 | 57 | // Filename aliases 58 | declare module '@sentry/cli/js/helper.js' { 59 | declare module.exports: $Exports<'@sentry/cli/js/helper'>; 60 | } 61 | declare module '@sentry/cli/js/index' { 62 | declare module.exports: $Exports<'@sentry/cli/js'>; 63 | } 64 | declare module '@sentry/cli/js/index.js' { 65 | declare module.exports: $Exports<'@sentry/cli/js'>; 66 | } 67 | declare module '@sentry/cli/js/logger.js' { 68 | declare module.exports: $Exports<'@sentry/cli/js/logger'>; 69 | } 70 | declare module '@sentry/cli/js/releases/index' { 71 | declare module.exports: $Exports<'@sentry/cli/js/releases'>; 72 | } 73 | declare module '@sentry/cli/js/releases/index.js' { 74 | declare module.exports: $Exports<'@sentry/cli/js/releases'>; 75 | } 76 | declare module '@sentry/cli/js/releases/options/deploys.js' { 77 | declare module.exports: $Exports<'@sentry/cli/js/releases/options/deploys'>; 78 | } 79 | declare module '@sentry/cli/js/releases/options/uploadSourcemaps.js' { 80 | declare module.exports: $Exports<'@sentry/cli/js/releases/options/uploadSourcemaps'>; 81 | } 82 | declare module '@sentry/cli/scripts/install.js' { 83 | declare module.exports: $Exports<'@sentry/cli/scripts/install'>; 84 | } 85 | declare module '@sentry/cli/scripts/test-vercel-nft.js' { 86 | declare module.exports: $Exports<'@sentry/cli/scripts/test-vercel-nft'>; 87 | } 88 | -------------------------------------------------------------------------------- /flow-typed/npm/@storybook/addon-actions_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: b56317b516a8194f7e17cccd5c11ebce 2 | // flow-typed version: <>/@storybook/addon-actions_v^8.6.12/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@storybook/addon-actions' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@storybook/addon-actions' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@storybook/addon-actions/dist/decorator' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@storybook/addon-actions/dist' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@storybook/addon-actions/dist/manager' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module '@storybook/addon-actions/dist/preview' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module '@storybook/addon-actions/manager' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module '@storybook/addon-actions/preview' { 46 | declare module.exports: any; 47 | } 48 | 49 | // Filename aliases 50 | declare module '@storybook/addon-actions/dist/decorator.js' { 51 | declare module.exports: $Exports<'@storybook/addon-actions/dist/decorator'>; 52 | } 53 | declare module '@storybook/addon-actions/dist/index' { 54 | declare module.exports: $Exports<'@storybook/addon-actions/dist'>; 55 | } 56 | declare module '@storybook/addon-actions/dist/index.js' { 57 | declare module.exports: $Exports<'@storybook/addon-actions/dist'>; 58 | } 59 | declare module '@storybook/addon-actions/dist/manager.js' { 60 | declare module.exports: $Exports<'@storybook/addon-actions/dist/manager'>; 61 | } 62 | declare module '@storybook/addon-actions/dist/preview.js' { 63 | declare module.exports: $Exports<'@storybook/addon-actions/dist/preview'>; 64 | } 65 | declare module '@storybook/addon-actions/manager.js' { 66 | declare module.exports: $Exports<'@storybook/addon-actions/manager'>; 67 | } 68 | declare module '@storybook/addon-actions/preview.js' { 69 | declare module.exports: $Exports<'@storybook/addon-actions/preview'>; 70 | } 71 | -------------------------------------------------------------------------------- /flow-typed/npm/@storybook/addon-interactions_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: c92651a1ba609674cf9660ebfd2a721a 2 | // flow-typed version: <>/@storybook/addon-interactions_v^8.6.12/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@storybook/addon-interactions' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@storybook/addon-interactions' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@storybook/addon-interactions/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@storybook/addon-interactions/dist/manager' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@storybook/addon-interactions/dist/preset' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module '@storybook/addon-interactions/dist/preview' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module '@storybook/addon-interactions/manager' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module '@storybook/addon-interactions/preset' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module '@storybook/addon-interactions/preview' { 50 | declare module.exports: any; 51 | } 52 | 53 | // Filename aliases 54 | declare module '@storybook/addon-interactions/dist/index' { 55 | declare module.exports: $Exports<'@storybook/addon-interactions/dist'>; 56 | } 57 | declare module '@storybook/addon-interactions/dist/index.js' { 58 | declare module.exports: $Exports<'@storybook/addon-interactions/dist'>; 59 | } 60 | declare module '@storybook/addon-interactions/dist/manager.js' { 61 | declare module.exports: $Exports<'@storybook/addon-interactions/dist/manager'>; 62 | } 63 | declare module '@storybook/addon-interactions/dist/preset.js' { 64 | declare module.exports: $Exports<'@storybook/addon-interactions/dist/preset'>; 65 | } 66 | declare module '@storybook/addon-interactions/dist/preview.js' { 67 | declare module.exports: $Exports<'@storybook/addon-interactions/dist/preview'>; 68 | } 69 | declare module '@storybook/addon-interactions/manager.js' { 70 | declare module.exports: $Exports<'@storybook/addon-interactions/manager'>; 71 | } 72 | declare module '@storybook/addon-interactions/preset.js' { 73 | declare module.exports: $Exports<'@storybook/addon-interactions/preset'>; 74 | } 75 | declare module '@storybook/addon-interactions/preview.js' { 76 | declare module.exports: $Exports<'@storybook/addon-interactions/preview'>; 77 | } 78 | -------------------------------------------------------------------------------- /flow-typed/npm/@storybook/addon-links_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 8432e4d1e30d4ee1cf40c0a688735094 2 | // flow-typed version: <>/@storybook/addon-links_v^8.6.12/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@storybook/addon-links' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@storybook/addon-links' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@storybook/addon-links/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@storybook/addon-links/dist/manager' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@storybook/addon-links/dist/preview' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module '@storybook/addon-links/dist/react' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module '@storybook/addon-links/manager' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module '@storybook/addon-links/preview' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module '@storybook/addon-links/react' { 50 | declare module.exports: any; 51 | } 52 | 53 | // Filename aliases 54 | declare module '@storybook/addon-links/dist/index' { 55 | declare module.exports: $Exports<'@storybook/addon-links/dist'>; 56 | } 57 | declare module '@storybook/addon-links/dist/index.js' { 58 | declare module.exports: $Exports<'@storybook/addon-links/dist'>; 59 | } 60 | declare module '@storybook/addon-links/dist/manager.js' { 61 | declare module.exports: $Exports<'@storybook/addon-links/dist/manager'>; 62 | } 63 | declare module '@storybook/addon-links/dist/preview.js' { 64 | declare module.exports: $Exports<'@storybook/addon-links/dist/preview'>; 65 | } 66 | declare module '@storybook/addon-links/dist/react/index' { 67 | declare module.exports: $Exports<'@storybook/addon-links/dist/react'>; 68 | } 69 | declare module '@storybook/addon-links/dist/react/index.js' { 70 | declare module.exports: $Exports<'@storybook/addon-links/dist/react'>; 71 | } 72 | declare module '@storybook/addon-links/manager.js' { 73 | declare module.exports: $Exports<'@storybook/addon-links/manager'>; 74 | } 75 | declare module '@storybook/addon-links/preview.js' { 76 | declare module.exports: $Exports<'@storybook/addon-links/preview'>; 77 | } 78 | declare module '@storybook/addon-links/react.js' { 79 | declare module.exports: $Exports<'@storybook/addon-links/react'>; 80 | } 81 | -------------------------------------------------------------------------------- /flow-typed/npm/@storybook/node-logger_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 08b710dda2f71befaebad99d5e48541b 2 | // flow-typed version: <>/@storybook/node-logger_v^8.6.12/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@storybook/node-logger' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@storybook/node-logger' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@storybook/node-logger/shim' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@storybook/node-logger/shim.js' { 31 | declare module.exports: $Exports<'@storybook/node-logger/shim'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/@storybook/preset-create-react-app_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 762e9896fc3ea9e82494bbb602f3634b 2 | // flow-typed version: <>/@storybook/preset-create-react-app_v^8.6.12/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@storybook/preset-create-react-app' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@storybook/preset-create-react-app' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@storybook/preset-create-react-app/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@storybook/preset-create-react-app/dist/index' { 31 | declare module.exports: $Exports<'@storybook/preset-create-react-app/dist'>; 32 | } 33 | declare module '@storybook/preset-create-react-app/dist/index.js' { 34 | declare module.exports: $Exports<'@storybook/preset-create-react-app/dist'>; 35 | } 36 | -------------------------------------------------------------------------------- /flow-typed/npm/@storybook/react-webpack5_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1a85260c730ef432e722a46eaa8c4285 2 | // flow-typed version: <>/@storybook/react-webpack5_v^8.6.12/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@storybook/react-webpack5' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@storybook/react-webpack5' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@storybook/react-webpack5/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@storybook/react-webpack5/dist/node' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@storybook/react-webpack5/dist/preset' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module '@storybook/react-webpack5/preset' { 38 | declare module.exports: any; 39 | } 40 | 41 | // Filename aliases 42 | declare module '@storybook/react-webpack5/dist/index' { 43 | declare module.exports: $Exports<'@storybook/react-webpack5/dist'>; 44 | } 45 | declare module '@storybook/react-webpack5/dist/index.js' { 46 | declare module.exports: $Exports<'@storybook/react-webpack5/dist'>; 47 | } 48 | declare module '@storybook/react-webpack5/dist/node/index' { 49 | declare module.exports: $Exports<'@storybook/react-webpack5/dist/node'>; 50 | } 51 | declare module '@storybook/react-webpack5/dist/node/index.js' { 52 | declare module.exports: $Exports<'@storybook/react-webpack5/dist/node'>; 53 | } 54 | declare module '@storybook/react-webpack5/dist/preset.js' { 55 | declare module.exports: $Exports<'@storybook/react-webpack5/dist/preset'>; 56 | } 57 | declare module '@storybook/react-webpack5/preset.js' { 58 | declare module.exports: $Exports<'@storybook/react-webpack5/preset'>; 59 | } 60 | -------------------------------------------------------------------------------- /flow-typed/npm/@storybook/react_v6.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: ffbe262652c2690829aaf72cb827a910 2 | // flow-typed version: 9d326d4ede/@storybook/react_v6.x.x/flow_>=v0.142.x 3 | 4 | type NodeModule = typeof module; 5 | 6 | declare module '@storybook/react' { 7 | declare type Context = {| 8 | +argTypes: { [key: string]: any, ... }, 9 | +args: { [key: string]: any, ... }, 10 | +globals: { [key: string]: any, ... }, 11 | +hooks: { [key: string]: any, ... }, 12 | +id: string, 13 | +kind: string, 14 | +name: string, 15 | +parameters: { [key: string]: any, ... }, 16 | +story: string, 17 | |}; 18 | declare type Renderable = 19 | | string 20 | | number 21 | | React$Element 22 | | Iterable; 23 | declare type RenderCallback = ( 24 | context: Context 25 | ) => Renderable; 26 | declare type RenderFunction = () => Renderable; 27 | 28 | declare type StoryDecorator = ( 29 | story: RenderFunction, 30 | context: Context 31 | ) => Renderable; 32 | 33 | declare type DecoratorParameters = { [key: string]: any, ... }; 34 | 35 | declare interface Story { 36 | +kind: string; 37 | add( 38 | storyName: string, 39 | callback: RenderCallback, 40 | parameters?: DecoratorParameters 41 | ): Story; 42 | addDecorator(decorator: StoryDecorator): Story; 43 | addParameters(parameters: DecoratorParameters): Story; 44 | } 45 | 46 | declare interface StoryObject { 47 | name: string; 48 | render: RenderFunction; 49 | } 50 | 51 | declare interface StoryBucket { 52 | kind: string; 53 | filename: string; 54 | stories: Array; 55 | } 56 | 57 | declare function addDecorator(decorator: StoryDecorator): void; 58 | declare function addParameters(parameters: DecoratorParameters): void; 59 | declare function clearDecorators(): void; 60 | declare function configure(fn: () => void, module: NodeModule): void; 61 | declare function setAddon(addon: { [key: string]: any, ... }): void; 62 | declare function storiesOf(name: string, module: NodeModule): Story; 63 | declare function storiesOf(name: string, module: NodeModule): Story & T; 64 | declare function forceReRender(): void; 65 | 66 | declare function getStorybook(): Array; 67 | } 68 | -------------------------------------------------------------------------------- /flow-typed/npm/@storybook/testing-library_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: bb0d87c376a37e5b7b5a82a74c8bb6c3 2 | // flow-typed version: <>/@storybook/testing-library_v^0.2.2/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@storybook/testing-library' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@storybook/testing-library' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@storybook/testing-library/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module '@storybook/testing-library/dist/index' { 31 | declare module.exports: $Exports<'@storybook/testing-library/dist'>; 32 | } 33 | declare module '@storybook/testing-library/dist/index.js' { 34 | declare module.exports: $Exports<'@storybook/testing-library/dist'>; 35 | } 36 | -------------------------------------------------------------------------------- /flow-typed/npm/@testing-library/jest-dom_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 5a71b115aafded9389fd01835e429e84 2 | // flow-typed version: <>/@testing-library/jest-dom_v^6.6.3/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@testing-library/jest-dom' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@testing-library/jest-dom' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@testing-library/jest-dom/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@testing-library/jest-dom/dist/jest-globals' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@testing-library/jest-dom/dist/matchers-7fb38cd4' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module '@testing-library/jest-dom/dist/matchers' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module '@testing-library/jest-dom/dist/vitest' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module '@testing-library/jest-dom/jest-globals' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module '@testing-library/jest-dom/matchers' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module '@testing-library/jest-dom/vitest' { 54 | declare module.exports: any; 55 | } 56 | 57 | // Filename aliases 58 | declare module '@testing-library/jest-dom/dist/index' { 59 | declare module.exports: $Exports<'@testing-library/jest-dom/dist'>; 60 | } 61 | declare module '@testing-library/jest-dom/dist/index.js' { 62 | declare module.exports: $Exports<'@testing-library/jest-dom/dist'>; 63 | } 64 | declare module '@testing-library/jest-dom/dist/jest-globals.js' { 65 | declare module.exports: $Exports<'@testing-library/jest-dom/dist/jest-globals'>; 66 | } 67 | declare module '@testing-library/jest-dom/dist/matchers-7fb38cd4.js' { 68 | declare module.exports: $Exports<'@testing-library/jest-dom/dist/matchers-7fb38cd4'>; 69 | } 70 | declare module '@testing-library/jest-dom/dist/matchers.js' { 71 | declare module.exports: $Exports<'@testing-library/jest-dom/dist/matchers'>; 72 | } 73 | declare module '@testing-library/jest-dom/dist/vitest.js' { 74 | declare module.exports: $Exports<'@testing-library/jest-dom/dist/vitest'>; 75 | } 76 | declare module '@testing-library/jest-dom/jest-globals.js' { 77 | declare module.exports: $Exports<'@testing-library/jest-dom/jest-globals'>; 78 | } 79 | declare module '@testing-library/jest-dom/matchers.js' { 80 | declare module.exports: $Exports<'@testing-library/jest-dom/matchers'>; 81 | } 82 | declare module '@testing-library/jest-dom/vitest.js' { 83 | declare module.exports: $Exports<'@testing-library/jest-dom/vitest'>; 84 | } 85 | -------------------------------------------------------------------------------- /flow-typed/npm/@welldone-software/why-did-you-render_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f043aec2545683e4301a47e259ca77df 2 | // flow-typed version: <>/@welldone-software/why-did-you-render_v^8.0.3/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@welldone-software/why-did-you-render' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@welldone-software/why-did-you-render' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@welldone-software/why-did-you-render/dist/whyDidYouRender' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@welldone-software/why-did-you-render/jsx-dev-runtime' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@welldone-software/why-did-you-render/jsx-runtime' { 34 | declare module.exports: any; 35 | } 36 | 37 | // Filename aliases 38 | declare module '@welldone-software/why-did-you-render/dist/whyDidYouRender.js' { 39 | declare module.exports: $Exports<'@welldone-software/why-did-you-render/dist/whyDidYouRender'>; 40 | } 41 | declare module '@welldone-software/why-did-you-render/jsx-dev-runtime.js' { 42 | declare module.exports: $Exports<'@welldone-software/why-did-you-render/jsx-dev-runtime'>; 43 | } 44 | declare module '@welldone-software/why-did-you-render/jsx-runtime.js' { 45 | declare module.exports: $Exports<'@welldone-software/why-did-you-render/jsx-runtime'>; 46 | } 47 | -------------------------------------------------------------------------------- /flow-typed/npm/@wojtekmaj/enzyme-adapter-react-17_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: c11edbda101cbb8fb4c87e9694f167bb 2 | // flow-typed version: <>/@wojtekmaj/enzyme-adapter-react-17_v^0.8.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * '@wojtekmaj/enzyme-adapter-react-17' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module '@wojtekmaj/enzyme-adapter-react-17' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module '@wojtekmaj/enzyme-adapter-react-17/build/detectFiberTags' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module '@wojtekmaj/enzyme-adapter-react-17/build/findCurrentFiberUsingSlowPath' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module '@wojtekmaj/enzyme-adapter-react-17/build' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module '@wojtekmaj/enzyme-adapter-react-17/build/ReactSeventeenAdapter' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module '@wojtekmaj/enzyme-adapter-react-17/src/detectFiberTags' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module '@wojtekmaj/enzyme-adapter-react-17/src/findCurrentFiberUsingSlowPath' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module '@wojtekmaj/enzyme-adapter-react-17/src' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module '@wojtekmaj/enzyme-adapter-react-17/src/ReactSeventeenAdapter' { 54 | declare module.exports: any; 55 | } 56 | 57 | // Filename aliases 58 | declare module '@wojtekmaj/enzyme-adapter-react-17/build/detectFiberTags.js' { 59 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/build/detectFiberTags'>; 60 | } 61 | declare module '@wojtekmaj/enzyme-adapter-react-17/build/findCurrentFiberUsingSlowPath.js' { 62 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/build/findCurrentFiberUsingSlowPath'>; 63 | } 64 | declare module '@wojtekmaj/enzyme-adapter-react-17/build/index' { 65 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/build'>; 66 | } 67 | declare module '@wojtekmaj/enzyme-adapter-react-17/build/index.js' { 68 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/build'>; 69 | } 70 | declare module '@wojtekmaj/enzyme-adapter-react-17/build/ReactSeventeenAdapter.js' { 71 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/build/ReactSeventeenAdapter'>; 72 | } 73 | declare module '@wojtekmaj/enzyme-adapter-react-17/src/detectFiberTags.js' { 74 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/src/detectFiberTags'>; 75 | } 76 | declare module '@wojtekmaj/enzyme-adapter-react-17/src/findCurrentFiberUsingSlowPath.js' { 77 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/src/findCurrentFiberUsingSlowPath'>; 78 | } 79 | declare module '@wojtekmaj/enzyme-adapter-react-17/src/index' { 80 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/src'>; 81 | } 82 | declare module '@wojtekmaj/enzyme-adapter-react-17/src/index.js' { 83 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/src'>; 84 | } 85 | declare module '@wojtekmaj/enzyme-adapter-react-17/src/ReactSeventeenAdapter.js' { 86 | declare module.exports: $Exports<'@wojtekmaj/enzyme-adapter-react-17/src/ReactSeventeenAdapter'>; 87 | } 88 | -------------------------------------------------------------------------------- /flow-typed/npm/chromatic_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 88df45dcc5679d6cff23cc5dc24dc2be 2 | // flow-typed version: <>/chromatic_v^6.7.3/flow_v0.184.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'chromatic' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'chromatic' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'chromatic/isChromatic' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'chromatic/isChromatic.js' { 31 | declare module.exports: $Exports<'chromatic/isChromatic'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/coveralls_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 8a3b267a4810e5dab5ce488508500019 2 | // flow-typed version: <>/coveralls_v^3.1.1/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'coveralls' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'coveralls' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'coveralls/bin/coveralls' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'coveralls/lib/convertLcovToCoveralls' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'coveralls/lib/detectLocalGit' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'coveralls/lib/fetchGitData' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'coveralls/lib/getOptions' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'coveralls/lib/handleInput' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'coveralls/lib/logger' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'coveralls/lib/sendToCoveralls' { 54 | declare module.exports: any; 55 | } 56 | 57 | // Filename aliases 58 | declare module 'coveralls/bin/coveralls.js' { 59 | declare module.exports: $Exports<'coveralls/bin/coveralls'>; 60 | } 61 | declare module 'coveralls/index' { 62 | declare module.exports: $Exports<'coveralls'>; 63 | } 64 | declare module 'coveralls/index.js' { 65 | declare module.exports: $Exports<'coveralls'>; 66 | } 67 | declare module 'coveralls/lib/convertLcovToCoveralls.js' { 68 | declare module.exports: $Exports<'coveralls/lib/convertLcovToCoveralls'>; 69 | } 70 | declare module 'coveralls/lib/detectLocalGit.js' { 71 | declare module.exports: $Exports<'coveralls/lib/detectLocalGit'>; 72 | } 73 | declare module 'coveralls/lib/fetchGitData.js' { 74 | declare module.exports: $Exports<'coveralls/lib/fetchGitData'>; 75 | } 76 | declare module 'coveralls/lib/getOptions.js' { 77 | declare module.exports: $Exports<'coveralls/lib/getOptions'>; 78 | } 79 | declare module 'coveralls/lib/handleInput.js' { 80 | declare module.exports: $Exports<'coveralls/lib/handleInput'>; 81 | } 82 | declare module 'coveralls/lib/logger.js' { 83 | declare module.exports: $Exports<'coveralls/lib/logger'>; 84 | } 85 | declare module 'coveralls/lib/sendToCoveralls.js' { 86 | declare module.exports: $Exports<'coveralls/lib/sendToCoveralls'>; 87 | } 88 | -------------------------------------------------------------------------------- /flow-typed/npm/deep-freeze_v0.0.1.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: eb61173a8bf860d5fdf5447b6b1352cc 2 | // flow-typed version: 3793c65651/deep-freeze_v0.0.1/flow_>=v0.104.x 3 | 4 | declare module 'deep-freeze' { 5 | declare type deepFreezeFnType = {| 6 | (a: $ReadOnlyArray): $ReadOnlyArray>, 7 | (a: T[]): $ReadOnlyArray>, 8 | (p: T): T, 9 | (o: T): $ReadOnly< 10 | $ObjMapi(P) => DeepReadOnly<$ElementType>> 11 | >, 12 | (f: T): T, 13 | |}; 14 | 15 | declare export type DeepReadOnly = $Call 16 | 17 | declare module.exports: deepFreezeFnType; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /flow-typed/npm/eslint-plugin-yaml_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 2c97149aa31bfad9d8134af35a3559f8 2 | // flow-typed version: <>/eslint-plugin-yaml_v^1.0.3/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'eslint-plugin-yaml' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'eslint-plugin-yaml' { 17 | declare module.exports: any; 18 | } 19 | -------------------------------------------------------------------------------- /flow-typed/npm/fast-equals_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6e51318a9e0d0681221179f752204fa5 2 | // flow-typed version: <>/fast-equals_v^5.2.2/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'fast-equals' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'fast-equals' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'fast-equals/config/rollup/config.base' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'fast-equals/config/rollup/config.cjs' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'fast-equals/config/rollup/config.esm' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'fast-equals/config/rollup/config.min' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'fast-equals/config/rollup/config.umd' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'fast-equals/config/webpack.config' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'fast-equals/dist/min' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'fast-equals/dist/umd' { 54 | declare module.exports: any; 55 | } 56 | 57 | // Filename aliases 58 | declare module 'fast-equals/config/rollup/config.base.js' { 59 | declare module.exports: $Exports<'fast-equals/config/rollup/config.base'>; 60 | } 61 | declare module 'fast-equals/config/rollup/config.cjs.js' { 62 | declare module.exports: $Exports<'fast-equals/config/rollup/config.cjs'>; 63 | } 64 | declare module 'fast-equals/config/rollup/config.esm.js' { 65 | declare module.exports: $Exports<'fast-equals/config/rollup/config.esm'>; 66 | } 67 | declare module 'fast-equals/config/rollup/config.min.js' { 68 | declare module.exports: $Exports<'fast-equals/config/rollup/config.min'>; 69 | } 70 | declare module 'fast-equals/config/rollup/config.umd.js' { 71 | declare module.exports: $Exports<'fast-equals/config/rollup/config.umd'>; 72 | } 73 | declare module 'fast-equals/config/webpack.config.js' { 74 | declare module.exports: $Exports<'fast-equals/config/webpack.config'>; 75 | } 76 | declare module 'fast-equals/dist/min/index' { 77 | declare module.exports: $Exports<'fast-equals/dist/min'>; 78 | } 79 | declare module 'fast-equals/dist/min/index.js' { 80 | declare module.exports: $Exports<'fast-equals/dist/min'>; 81 | } 82 | declare module 'fast-equals/dist/umd/index' { 83 | declare module.exports: $Exports<'fast-equals/dist/umd'>; 84 | } 85 | declare module 'fast-equals/dist/umd/index.js' { 86 | declare module.exports: $Exports<'fast-equals/dist/umd'>; 87 | } 88 | -------------------------------------------------------------------------------- /flow-typed/npm/flow-bin_v0.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 28fdff7f110e1c75efab63ff205dda30 2 | // flow-typed version: c6154227d1/flow-bin_v0.x.x/flow_>=v0.104.x 3 | 4 | declare module "flow-bin" { 5 | declare module.exports: string; 6 | } 7 | -------------------------------------------------------------------------------- /flow-typed/npm/fromentries_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 94b472f52b4b66482aca97c5e71bffa4 2 | // flow-typed version: <>/fromentries_v^1.3.2/flow_v0.196.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'fromentries' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'fromentries' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | 26 | // Filename aliases 27 | declare module 'fromentries/index' { 28 | declare module.exports: $Exports<'fromentries'>; 29 | } 30 | declare module 'fromentries/index.js' { 31 | declare module.exports: $Exports<'fromentries'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/history_v5.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1a0b3d7b30fa34f656ec3b48ab330fec 2 | // flow-typed version: c097941e54/history_v5.x.x/flow_>=v0.201.x 3 | 4 | declare module 'history' { 5 | declare type Unregister = () => void; 6 | 7 | declare export type Action = 'PUSH' | 'REPLACE' | 'POP'; 8 | 9 | declare export type Location = {| 10 | pathname: string, 11 | search: string, 12 | hash: string, 13 | state: { ... }, 14 | key: string, 15 | |}; 16 | 17 | declare type History = {| 18 | length: number, 19 | location: HistoryLocation, 20 | action: Action, 21 | push: ((path: string, state?: { ... }) => void) & 22 | ((location: Partial) => void), 23 | replace: ((path: string, state?: { ... }) => void) & 24 | ((location: Partial) => void), 25 | go(n: number): void, 26 | back(): void, 27 | forward(): void, 28 | listen(({| location: HistoryLocation, action: Action |}) => void): Unregister, 29 | block( 30 | blocker: (transition: {| 31 | action: Action, 32 | location: HistoryLocation, 33 | retry: () => void, 34 | |}) => void, 35 | ): Unregister, 36 | createHref(location: Partial): string, 37 | |}; 38 | 39 | declare export type BrowserHistory = History<>; 40 | 41 | declare type BrowserHistoryOpts = {| 42 | basename?: string, 43 | forceRefresh?: boolean, 44 | |}; 45 | 46 | declare function createBrowserHistory( 47 | opts?: BrowserHistoryOpts 48 | ): BrowserHistory; 49 | 50 | declare export type MemoryHistory = {| 51 | ...History<>, 52 | index: number, 53 | entries: Array, 54 | canGo(n: number): boolean, 55 | |}; 56 | 57 | declare type MemoryHistoryOpts = {| 58 | initialEntries?: Array, 59 | initialIndex?: number, 60 | |}; 61 | 62 | declare function createMemoryHistory(opts?: MemoryHistoryOpts): MemoryHistory; 63 | 64 | declare export type HashLocation = {| 65 | ...Location, 66 | state: void, 67 | key: void, 68 | |}; 69 | 70 | declare export type HashHistory = History; 71 | 72 | declare type HashHistoryOpts = {| 73 | basename?: string, 74 | |}; 75 | 76 | declare function createHashHistory(opts?: HashHistoryOpts): HashHistory; 77 | 78 | // PathUtils 79 | declare function parsePath(path: string): Location; 80 | 81 | declare function createPath(location: Partial): string; 82 | 83 | // LocationUtils 84 | declare function locationsAreEqual( 85 | a: Partial, 86 | b: Partial 87 | ): boolean; 88 | 89 | declare function createLocation( 90 | path: string | Partial, 91 | state?: { ... }, 92 | key?: string, 93 | currentLocation?: Location 94 | ): Location; 95 | } 96 | -------------------------------------------------------------------------------- /flow-typed/npm/husky_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 0c05e5e5b0487b805e93406057fe4c2c 2 | // flow-typed version: <>/husky_v9/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'husky' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'husky' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'husky/bin' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'husky/bin.js' { 31 | declare module.exports: $Exports<'husky/bin'>; 32 | } 33 | declare module 'husky/index' { 34 | declare module.exports: $Exports<'husky'>; 35 | } 36 | declare module 'husky/index.js' { 37 | declare module.exports: $Exports<'husky'>; 38 | } 39 | -------------------------------------------------------------------------------- /flow-typed/npm/jest-each_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6c6194981073482ea105b8d38ada685a 2 | // flow-typed version: <>/jest-each_v^29.7.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'jest-each' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'jest-each' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'jest-each/build/bind' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'jest-each/build' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'jest-each/build/table/array' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'jest-each/build/table/interpolation' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'jest-each/build/table/template' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'jest-each/build/validation' { 46 | declare module.exports: any; 47 | } 48 | 49 | // Filename aliases 50 | declare module 'jest-each/build/bind.js' { 51 | declare module.exports: $Exports<'jest-each/build/bind'>; 52 | } 53 | declare module 'jest-each/build/index' { 54 | declare module.exports: $Exports<'jest-each/build'>; 55 | } 56 | declare module 'jest-each/build/index.js' { 57 | declare module.exports: $Exports<'jest-each/build'>; 58 | } 59 | declare module 'jest-each/build/table/array.js' { 60 | declare module.exports: $Exports<'jest-each/build/table/array'>; 61 | } 62 | declare module 'jest-each/build/table/interpolation.js' { 63 | declare module.exports: $Exports<'jest-each/build/table/interpolation'>; 64 | } 65 | declare module 'jest-each/build/table/template.js' { 66 | declare module.exports: $Exports<'jest-each/build/table/template'>; 67 | } 68 | declare module 'jest-each/build/validation.js' { 69 | declare module.exports: $Exports<'jest-each/build/validation'>; 70 | } 71 | -------------------------------------------------------------------------------- /flow-typed/npm/markdownlint-cli_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f9539d32dabfcabe6541b82a0a06a12f 2 | // flow-typed version: <>/markdownlint-cli_v^0.43.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'markdownlint-cli' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'markdownlint-cli' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'markdownlint-cli/markdownlint' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'markdownlint-cli/markdownlint.js' { 31 | declare module.exports: $Exports<'markdownlint-cli/markdownlint'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/npm-package-json-lint-config-default_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 0343bc4e08afeee5e9a98c57dfc9bdfc 2 | // flow-typed version: <>/npm-package-json-lint-config-default_v^5.0.0/flow_v0.196.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'npm-package-json-lint-config-default' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'npm-package-json-lint-config-default' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | 26 | // Filename aliases 27 | declare module 'npm-package-json-lint-config-default/index' { 28 | declare module.exports: $Exports<'npm-package-json-lint-config-default'>; 29 | } 30 | declare module 'npm-package-json-lint-config-default/index.js' { 31 | declare module.exports: $Exports<'npm-package-json-lint-config-default'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/pkg-ok_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f7f44437ed93891649a22a3b20d84b8b 2 | // flow-typed version: <>/pkg-ok_v^3.0.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'pkg-ok' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'pkg-ok' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'pkg-ok/dist/bin' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'pkg-ok/dist/errors' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'pkg-ok/dist/fields' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'pkg-ok/dist' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'pkg-ok/dist/pkg' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'pkg-ok/dist/scripts' { 46 | declare module.exports: any; 47 | } 48 | 49 | // Filename aliases 50 | declare module 'pkg-ok/dist/bin.js' { 51 | declare module.exports: $Exports<'pkg-ok/dist/bin'>; 52 | } 53 | declare module 'pkg-ok/dist/errors.js' { 54 | declare module.exports: $Exports<'pkg-ok/dist/errors'>; 55 | } 56 | declare module 'pkg-ok/dist/fields.js' { 57 | declare module.exports: $Exports<'pkg-ok/dist/fields'>; 58 | } 59 | declare module 'pkg-ok/dist/index' { 60 | declare module.exports: $Exports<'pkg-ok/dist'>; 61 | } 62 | declare module 'pkg-ok/dist/index.js' { 63 | declare module.exports: $Exports<'pkg-ok/dist'>; 64 | } 65 | declare module 'pkg-ok/dist/pkg.js' { 66 | declare module.exports: $Exports<'pkg-ok/dist/pkg'>; 67 | } 68 | declare module 'pkg-ok/dist/scripts.js' { 69 | declare module.exports: $Exports<'pkg-ok/dist/scripts'>; 70 | } 71 | -------------------------------------------------------------------------------- /flow-typed/npm/prettier_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 77b842a8581b4190055514ae83ca4251 2 | // flow-typed version: <>/prettier_v^3.4.2/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'prettier' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'prettier' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'prettier/doc' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'prettier/plugins/acorn' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'prettier/plugins/angular' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'prettier/plugins/babel' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'prettier/plugins/estree' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'prettier/plugins/flow' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'prettier/plugins/glimmer' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'prettier/plugins/graphql' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'prettier/plugins/html' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'prettier/plugins/markdown' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'prettier/plugins/meriyah' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'prettier/plugins/postcss' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'prettier/plugins/typescript' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'prettier/plugins/yaml' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'prettier/standalone' { 82 | declare module.exports: any; 83 | } 84 | 85 | // Filename aliases 86 | declare module 'prettier/doc.js' { 87 | declare module.exports: $Exports<'prettier/doc'>; 88 | } 89 | declare module 'prettier/plugins/acorn.js' { 90 | declare module.exports: $Exports<'prettier/plugins/acorn'>; 91 | } 92 | declare module 'prettier/plugins/angular.js' { 93 | declare module.exports: $Exports<'prettier/plugins/angular'>; 94 | } 95 | declare module 'prettier/plugins/babel.js' { 96 | declare module.exports: $Exports<'prettier/plugins/babel'>; 97 | } 98 | declare module 'prettier/plugins/estree.js' { 99 | declare module.exports: $Exports<'prettier/plugins/estree'>; 100 | } 101 | declare module 'prettier/plugins/flow.js' { 102 | declare module.exports: $Exports<'prettier/plugins/flow'>; 103 | } 104 | declare module 'prettier/plugins/glimmer.js' { 105 | declare module.exports: $Exports<'prettier/plugins/glimmer'>; 106 | } 107 | declare module 'prettier/plugins/graphql.js' { 108 | declare module.exports: $Exports<'prettier/plugins/graphql'>; 109 | } 110 | declare module 'prettier/plugins/html.js' { 111 | declare module.exports: $Exports<'prettier/plugins/html'>; 112 | } 113 | declare module 'prettier/plugins/markdown.js' { 114 | declare module.exports: $Exports<'prettier/plugins/markdown'>; 115 | } 116 | declare module 'prettier/plugins/meriyah.js' { 117 | declare module.exports: $Exports<'prettier/plugins/meriyah'>; 118 | } 119 | declare module 'prettier/plugins/postcss.js' { 120 | declare module.exports: $Exports<'prettier/plugins/postcss'>; 121 | } 122 | declare module 'prettier/plugins/typescript.js' { 123 | declare module.exports: $Exports<'prettier/plugins/typescript'>; 124 | } 125 | declare module 'prettier/plugins/yaml.js' { 126 | declare module.exports: $Exports<'prettier/plugins/yaml'>; 127 | } 128 | declare module 'prettier/standalone.js' { 129 | declare module.exports: $Exports<'prettier/standalone'>; 130 | } 131 | -------------------------------------------------------------------------------- /flow-typed/npm/pretty-quick_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 3028498b9380cc6de62440f9f5aa7de5 2 | // flow-typed version: <>/pretty-quick_v^3.1.3/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'pretty-quick' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'pretty-quick' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'pretty-quick/bin/pretty-quick' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'pretty-quick/dist/createIgnorer' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'pretty-quick/dist/createMatcher' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'pretty-quick/dist' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'pretty-quick/dist/isSupportedExtension' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'pretty-quick/dist/processFiles' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'pretty-quick/dist/scms/git' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'pretty-quick/dist/scms/hg' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'pretty-quick/dist/scms' { 58 | declare module.exports: any; 59 | } 60 | 61 | // Filename aliases 62 | declare module 'pretty-quick/bin/pretty-quick.js' { 63 | declare module.exports: $Exports<'pretty-quick/bin/pretty-quick'>; 64 | } 65 | declare module 'pretty-quick/dist/createIgnorer.js' { 66 | declare module.exports: $Exports<'pretty-quick/dist/createIgnorer'>; 67 | } 68 | declare module 'pretty-quick/dist/createMatcher.js' { 69 | declare module.exports: $Exports<'pretty-quick/dist/createMatcher'>; 70 | } 71 | declare module 'pretty-quick/dist/index' { 72 | declare module.exports: $Exports<'pretty-quick/dist'>; 73 | } 74 | declare module 'pretty-quick/dist/index.js' { 75 | declare module.exports: $Exports<'pretty-quick/dist'>; 76 | } 77 | declare module 'pretty-quick/dist/isSupportedExtension.js' { 78 | declare module.exports: $Exports<'pretty-quick/dist/isSupportedExtension'>; 79 | } 80 | declare module 'pretty-quick/dist/processFiles.js' { 81 | declare module.exports: $Exports<'pretty-quick/dist/processFiles'>; 82 | } 83 | declare module 'pretty-quick/dist/scms/git.js' { 84 | declare module.exports: $Exports<'pretty-quick/dist/scms/git'>; 85 | } 86 | declare module 'pretty-quick/dist/scms/hg.js' { 87 | declare module.exports: $Exports<'pretty-quick/dist/scms/hg'>; 88 | } 89 | declare module 'pretty-quick/dist/scms/index' { 90 | declare module.exports: $Exports<'pretty-quick/dist/scms'>; 91 | } 92 | declare module 'pretty-quick/dist/scms/index.js' { 93 | declare module.exports: $Exports<'pretty-quick/dist/scms'>; 94 | } 95 | -------------------------------------------------------------------------------- /flow-typed/npm/react-cookie_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 810dd9a75a6de6e97e7728b9e923fe9e 2 | // flow-typed version: <>/react-cookie_v^7.2.2/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-cookie' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-cookie' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-cookie/cjs' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'react-cookie/umd/reactCookie' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'react-cookie/umd/reactCookie.min' { 34 | declare module.exports: any; 35 | } 36 | 37 | // Filename aliases 38 | declare module 'react-cookie/cjs/index' { 39 | declare module.exports: $Exports<'react-cookie/cjs'>; 40 | } 41 | declare module 'react-cookie/cjs/index.js' { 42 | declare module.exports: $Exports<'react-cookie/cjs'>; 43 | } 44 | declare module 'react-cookie/umd/reactCookie.js' { 45 | declare module.exports: $Exports<'react-cookie/umd/reactCookie'>; 46 | } 47 | declare module 'react-cookie/umd/reactCookie.min.js' { 48 | declare module.exports: $Exports<'react-cookie/umd/reactCookie.min'>; 49 | } 50 | -------------------------------------------------------------------------------- /flow-typed/npm/react-device-detect_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 7aa69ef3ed4db4ec683833cc25a2d601 2 | // flow-typed version: <>/react-device-detect_v^2.2.3/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-device-detect' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-device-detect' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-device-detect/dist/lib' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'react-device-detect/rollup.config' { 30 | declare module.exports: any; 31 | } 32 | 33 | // Filename aliases 34 | declare module 'react-device-detect/dist/lib.js' { 35 | declare module.exports: $Exports<'react-device-detect/dist/lib'>; 36 | } 37 | declare module 'react-device-detect/rollup.config.js' { 38 | declare module.exports: $Exports<'react-device-detect/rollup.config'>; 39 | } 40 | -------------------------------------------------------------------------------- /flow-typed/npm/react-joyride_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 9f955e22f6b5be9b196148ff67463cde 2 | // flow-typed version: <>/react-joyride_v^2.9.3/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-joyride' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-joyride' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-joyride/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'react-joyride/dist/index' { 31 | declare module.exports: $Exports<'react-joyride/dist'>; 32 | } 33 | declare module 'react-joyride/dist/index.js' { 34 | declare module.exports: $Exports<'react-joyride/dist'>; 35 | } 36 | -------------------------------------------------------------------------------- /flow-typed/npm/react-redux_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 2dd7b4cec98cdaea13033c840c526784 2 | // flow-typed version: <>/react-redux_v^9.2.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-redux' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-redux' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-redux/dist/cjs' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'react-redux/dist/react-redux.legacy-esm' { 30 | declare module.exports: any; 31 | } 32 | 33 | // Filename aliases 34 | declare module 'react-redux/dist/cjs/index' { 35 | declare module.exports: $Exports<'react-redux/dist/cjs'>; 36 | } 37 | declare module 'react-redux/dist/cjs/index.js' { 38 | declare module.exports: $Exports<'react-redux/dist/cjs'>; 39 | } 40 | declare module 'react-redux/dist/react-redux.legacy-esm.js' { 41 | declare module.exports: $Exports<'react-redux/dist/react-redux.legacy-esm'>; 42 | } 43 | -------------------------------------------------------------------------------- /flow-typed/npm/react-router_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 80852aa08002a606a2d8ba3cdec013ea 2 | // flow-typed version: <>/react-router_v^6.27.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-router' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-router' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-router/dist' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'react-router/dist/main' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'react-router/dist/react-router.development' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'react-router/dist/react-router.production.min' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'react-router/dist/umd/react-router.development' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'react-router/dist/umd/react-router.production.min' { 46 | declare module.exports: any; 47 | } 48 | 49 | // Filename aliases 50 | declare module 'react-router/dist/index' { 51 | declare module.exports: $Exports<'react-router/dist'>; 52 | } 53 | declare module 'react-router/dist/index.js' { 54 | declare module.exports: $Exports<'react-router/dist'>; 55 | } 56 | declare module 'react-router/dist/main.js' { 57 | declare module.exports: $Exports<'react-router/dist/main'>; 58 | } 59 | declare module 'react-router/dist/react-router.development.js' { 60 | declare module.exports: $Exports<'react-router/dist/react-router.development'>; 61 | } 62 | declare module 'react-router/dist/react-router.production.min.js' { 63 | declare module.exports: $Exports<'react-router/dist/react-router.production.min'>; 64 | } 65 | declare module 'react-router/dist/umd/react-router.development.js' { 66 | declare module.exports: $Exports<'react-router/dist/umd/react-router.development'>; 67 | } 68 | declare module 'react-router/dist/umd/react-router.production.min.js' { 69 | declare module.exports: $Exports<'react-router/dist/umd/react-router.production.min'>; 70 | } 71 | -------------------------------------------------------------------------------- /flow-typed/npm/react-simple-code-editor_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 7dfd3af75afc36b330bfbac4703ad924 2 | // flow-typed version: <>/react-simple-code-editor_v^0.14.1/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-simple-code-editor' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-simple-code-editor' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-simple-code-editor/lib' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'react-simple-code-editor/lib/index' { 31 | declare module.exports: $Exports<'react-simple-code-editor/lib'>; 32 | } 33 | declare module 'react-simple-code-editor/lib/index.js' { 34 | declare module.exports: $Exports<'react-simple-code-editor/lib'>; 35 | } 36 | -------------------------------------------------------------------------------- /flow-typed/npm/react-simple-tree-menu_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: fed86a5a023699c912d372d72fcf99b9 2 | // flow-typed version: <>/react-simple-tree-menu_v^1.1.18/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-simple-tree-menu' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-simple-tree-menu' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-simple-tree-menu/dist/main.cjs' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'react-simple-tree-menu/dist/main.esm' { 30 | declare module.exports: any; 31 | } 32 | 33 | // Filename aliases 34 | declare module 'react-simple-tree-menu/dist/main.cjs.js' { 35 | declare module.exports: $Exports<'react-simple-tree-menu/dist/main.cjs'>; 36 | } 37 | declare module 'react-simple-tree-menu/dist/main.esm.js' { 38 | declare module.exports: $Exports<'react-simple-tree-menu/dist/main.esm'>; 39 | } 40 | -------------------------------------------------------------------------------- /flow-typed/npm/react-split-pane_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 33608be4169d7c338fc12e06d3566f87 2 | // flow-typed version: <>/react-split-pane_v^0.1.92/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-split-pane' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-split-pane' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-split-pane/dist/index.cjs' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'react-split-pane/dist/index.esm' { 30 | declare module.exports: any; 31 | } 32 | 33 | // Filename aliases 34 | declare module 'react-split-pane/dist/index.cjs.js' { 35 | declare module.exports: $Exports<'react-split-pane/dist/index.cjs'>; 36 | } 37 | declare module 'react-split-pane/dist/index.esm.js' { 38 | declare module.exports: $Exports<'react-split-pane/dist/index.esm'>; 39 | } 40 | -------------------------------------------------------------------------------- /flow-typed/npm/react-test-renderer_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: e60f90e6625be5de66b9c58cd389ad68 2 | // flow-typed version: <>/react-test-renderer_v^18.3.1/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'react-test-renderer' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'react-test-renderer' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'react-test-renderer/cjs/react-test-renderer.development' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'react-test-renderer/cjs/react-test-renderer.production.min' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'react-test-renderer/shallow' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'react-test-renderer/umd/react-test-renderer.development' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'react-test-renderer/umd/react-test-renderer.production.min' { 42 | declare module.exports: any; 43 | } 44 | 45 | // Filename aliases 46 | declare module 'react-test-renderer/cjs/react-test-renderer.development.js' { 47 | declare module.exports: $Exports<'react-test-renderer/cjs/react-test-renderer.development'>; 48 | } 49 | declare module 'react-test-renderer/cjs/react-test-renderer.production.min.js' { 50 | declare module.exports: $Exports<'react-test-renderer/cjs/react-test-renderer.production.min'>; 51 | } 52 | declare module 'react-test-renderer/index' { 53 | declare module.exports: $Exports<'react-test-renderer'>; 54 | } 55 | declare module 'react-test-renderer/index.js' { 56 | declare module.exports: $Exports<'react-test-renderer'>; 57 | } 58 | declare module 'react-test-renderer/shallow.js' { 59 | declare module.exports: $Exports<'react-test-renderer/shallow'>; 60 | } 61 | declare module 'react-test-renderer/umd/react-test-renderer.development.js' { 62 | declare module.exports: $Exports<'react-test-renderer/umd/react-test-renderer.development'>; 63 | } 64 | declare module 'react-test-renderer/umd/react-test-renderer.production.min.js' { 65 | declare module.exports: $Exports<'react-test-renderer/umd/react-test-renderer.production.min'>; 66 | } 67 | -------------------------------------------------------------------------------- /flow-typed/npm/redux-mock-store_v1.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 391af34d1983e15b80d2f18fd8273954 2 | // flow-typed version: 032de4a35a/redux-mock-store_v1.x.x/flow_>=v0.104.x 3 | 4 | declare module "redux-mock-store" { 5 | /* 6 | S = State 7 | A = Action 8 | */ 9 | 10 | declare type mockStore = { (state: S): mockStoreWithoutMiddleware, ... }; 11 | declare type DispatchAPI = (action: A) => A; 12 | declare type Dispatch> = DispatchAPI; 13 | declare type mockStoreWithoutMiddleware = { 14 | getState(): S, 15 | getActions(): Array, 16 | dispatch: Dispatch, 17 | clearActions(): void, 18 | subscribe(callback: () => void): () => void, 19 | replaceReducer(nextReducer: Function): void, 20 | ... 21 | }; 22 | 23 | declare type Middleware = any => any => any; 24 | 25 | declare module.exports: (middlewares: ?Array) => mockStore; 26 | } 27 | 28 | // Filename aliases 29 | declare module "redux-mock-store/src/index" { 30 | declare module.exports: $Exports<"redux-mock-store">; 31 | } 32 | declare module "redux-mock-store/src/index.js" { 33 | declare module.exports: $Exports<"redux-mock-store">; 34 | } 35 | -------------------------------------------------------------------------------- /flow-typed/npm/redux-thunk_v2.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 70deb399800b3a0577c45ce8a21434b8 2 | // flow-typed version: c63bca1648/redux-thunk_v2.x.x/flow_>=v0.83.x 3 | 4 | // Copied types from redux so that 5 | // redux-thunk can be used with redux and redux-mock-store. 6 | // 7 | // This should be replaced with imports in the not too distant future once we 8 | // figure out cross dependency imports in flow-typed 9 | declare module '@@redux' { 10 | declare export type DispatchAPI = (action: A) => A; 11 | 12 | declare export type Dispatch = DispatchAPI; 13 | 14 | declare export type MiddlewareAPI> = { 15 | dispatch: D, 16 | getState(): S, 17 | ... 18 | }; 19 | 20 | declare export type Middleware> = ( 21 | api: MiddlewareAPI 22 | ) => (next: D) => D; 23 | } 24 | 25 | declare module 'redux-thunk' { 26 | import type { Middleware } from '@@redux'; 27 | 28 | declare export type Thunk = Middleware & {| 29 | withExtraArgument(arg: $NonMaybeType): Middleware, 30 | |}; 31 | 32 | declare module.exports: Thunk; 33 | } 34 | -------------------------------------------------------------------------------- /flow-typed/npm/redux_v4.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 211ee1952009bc69f9ace7ebc9e3a0d5 2 | // flow-typed version: 9a968c602c/redux_v4.x.x/flow_>=v0.201.x 3 | 4 | declare module 'redux' { 5 | /* 6 | 7 | S = State 8 | A = Action 9 | D = Dispatch 10 | 11 | */ 12 | 13 | declare export type Action = {type: T, ...}; 14 | 15 | declare export type DispatchAPI = (action: A) => A; 16 | 17 | declare export type Dispatch = DispatchAPI; 18 | 19 | declare export type MiddlewareAPI> = { 20 | dispatch: D, 21 | getState(): S, 22 | ... 23 | }; 24 | 25 | declare export type Store> = { 26 | // rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages) 27 | dispatch: D, 28 | getState(): S, 29 | subscribe(listener: () => void): () => void, 30 | replaceReducer(nextReducer: Reducer): void, 31 | ... 32 | }; 33 | 34 | declare export type Reducer = (state: S, action: A) => S; 35 | 36 | declare export type CombinedReducer = ( 37 | state: ($Shape & {...}) | void, 38 | action: A 39 | ) => S; 40 | 41 | declare export type Middleware> = ( 42 | api: MiddlewareAPI 43 | ) => (next: D) => D; 44 | 45 | declare export type StoreCreator> = { 46 | (reducer: Reducer, enhancer?: StoreEnhancer): Store, 47 | ( 48 | reducer: Reducer, 49 | preloadedState: S, 50 | enhancer?: StoreEnhancer 51 | ): Store, 52 | ... 53 | }; 54 | 55 | declare export type StoreEnhancer> = ( 56 | next: StoreCreator 57 | ) => StoreCreator; 58 | 59 | declare export function createStore( 60 | reducer: Reducer, 61 | enhancer?: StoreEnhancer 62 | ): Store; 63 | declare export function createStore( 64 | reducer: Reducer, 65 | preloadedState?: S, 66 | enhancer?: StoreEnhancer 67 | ): Store; 68 | 69 | declare export function legacy_createStore( 70 | reducer: Reducer, 71 | enhancer?: StoreEnhancer 72 | ): Store; 73 | declare export function legacy_createStore( 74 | reducer: Reducer, 75 | preloadedState?: S, 76 | enhancer?: StoreEnhancer 77 | ): Store; 78 | 79 | declare export function applyMiddleware( 80 | ...middlewares: Array> 81 | ): StoreEnhancer; 82 | 83 | declare export type ActionCreator = (...args: Array) => A; 84 | declare export type ActionCreators = { 85 | [key: K]: ActionCreator, 86 | ... 87 | }; 88 | 89 | declare export function bindActionCreators< 90 | A, 91 | C: ActionCreator, 92 | D: DispatchAPI 93 | >( 94 | actionCreator: C, 95 | dispatch: D 96 | ): C; 97 | declare export function bindActionCreators< 98 | A, 99 | K, 100 | C: ActionCreators, 101 | D: DispatchAPI 102 | >( 103 | actionCreators: C, 104 | dispatch: D 105 | ): C; 106 | 107 | declare export function combineReducers( 108 | reducers: O 109 | ): CombinedReducer<$ObjMap(r: Reducer) => S>, A>; 110 | 111 | declare export var compose: $Compose; 112 | } 113 | -------------------------------------------------------------------------------- /flow-typed/npm/rimraf_v2.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 8b21843f43134917177d82a3b993b609 2 | // flow-typed version: c6154227d1/rimraf_v2.x.x/flow_>=v0.104.x 3 | 4 | declare module 'rimraf' { 5 | declare type Options = { 6 | maxBusyTries?: number, 7 | emfileWait?: number, 8 | glob?: boolean, 9 | disableGlob?: boolean, 10 | ... 11 | }; 12 | 13 | declare type Callback = (err: ?Error, path: ?string) => void; 14 | 15 | declare module.exports: { 16 | (f: string, opts?: Options | Callback, callback?: Callback): void, 17 | sync(path: string, opts?: Options): void, 18 | ... 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /flow-typed/npm/source-map-explorer_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f1442f50c30c8e9fc79791b6c4d1d903 2 | // flow-typed version: <>/source-map-explorer_v^2.5.3/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'source-map-explorer' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'source-map-explorer' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'source-map-explorer/bin/cli' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'source-map-explorer/lib/api' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'source-map-explorer/lib/app-error' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'source-map-explorer/lib/coverage' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'source-map-explorer/lib/explore' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'source-map-explorer/lib/helpers' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'source-map-explorer/lib/html' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'source-map-explorer/lib' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'source-map-explorer/lib/output' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'source-map-explorer/lib/vendor/webtreemap' { 62 | declare module.exports: any; 63 | } 64 | 65 | // Filename aliases 66 | declare module 'source-map-explorer/bin/cli.js' { 67 | declare module.exports: $Exports<'source-map-explorer/bin/cli'>; 68 | } 69 | declare module 'source-map-explorer/lib/api.js' { 70 | declare module.exports: $Exports<'source-map-explorer/lib/api'>; 71 | } 72 | declare module 'source-map-explorer/lib/app-error.js' { 73 | declare module.exports: $Exports<'source-map-explorer/lib/app-error'>; 74 | } 75 | declare module 'source-map-explorer/lib/coverage.js' { 76 | declare module.exports: $Exports<'source-map-explorer/lib/coverage'>; 77 | } 78 | declare module 'source-map-explorer/lib/explore.js' { 79 | declare module.exports: $Exports<'source-map-explorer/lib/explore'>; 80 | } 81 | declare module 'source-map-explorer/lib/helpers.js' { 82 | declare module.exports: $Exports<'source-map-explorer/lib/helpers'>; 83 | } 84 | declare module 'source-map-explorer/lib/html.js' { 85 | declare module.exports: $Exports<'source-map-explorer/lib/html'>; 86 | } 87 | declare module 'source-map-explorer/lib/index' { 88 | declare module.exports: $Exports<'source-map-explorer/lib'>; 89 | } 90 | declare module 'source-map-explorer/lib/index.js' { 91 | declare module.exports: $Exports<'source-map-explorer/lib'>; 92 | } 93 | declare module 'source-map-explorer/lib/output.js' { 94 | declare module.exports: $Exports<'source-map-explorer/lib/output'>; 95 | } 96 | declare module 'source-map-explorer/lib/vendor/webtreemap.js' { 97 | declare module.exports: $Exports<'source-map-explorer/lib/vendor/webtreemap'>; 98 | } 99 | -------------------------------------------------------------------------------- /flow-typed/npm/stylelint-config-standard_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 8ad74e20bf2ecef6aaa7d7cf434b4909 2 | // flow-typed version: <>/stylelint-config-standard_v^29.0.0/flow_v0.196.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'stylelint-config-standard' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'stylelint-config-standard' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | 26 | // Filename aliases 27 | declare module 'stylelint-config-standard/index' { 28 | declare module.exports: $Exports<'stylelint-config-standard'>; 29 | } 30 | declare module 'stylelint-config-standard/index.js' { 31 | declare module.exports: $Exports<'stylelint-config-standard'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/stylelint_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 2f61905a8948b062de5a631b8c54e8a5 2 | // flow-typed version: <>/stylelint_v^16.12.0/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'stylelint' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'stylelint' { 17 | declare module.exports: any; 18 | } 19 | -------------------------------------------------------------------------------- /flow-typed/npm/tinyqueue_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: fe97eb461b2e178e51e6f05eb194ce75 2 | // flow-typed version: <>/tinyqueue_v^2.0.3/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'tinyqueue' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'tinyqueue' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'tinyqueue/tinyqueue' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'tinyqueue/tinyqueue.min' { 30 | declare module.exports: any; 31 | } 32 | 33 | // Filename aliases 34 | declare module 'tinyqueue/index' { 35 | declare module.exports: $Exports<'tinyqueue'>; 36 | } 37 | declare module 'tinyqueue/index.js' { 38 | declare module.exports: $Exports<'tinyqueue'>; 39 | } 40 | declare module 'tinyqueue/tinyqueue.js' { 41 | declare module.exports: $Exports<'tinyqueue/tinyqueue'>; 42 | } 43 | declare module 'tinyqueue/tinyqueue.min.js' { 44 | declare module.exports: $Exports<'tinyqueue/tinyqueue.min'>; 45 | } 46 | -------------------------------------------------------------------------------- /flow-typed/npm/typescript_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 2c1c1781fc6b155318a36bba9ef58f5f 2 | // flow-typed version: <>/typescript_v*/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'typescript' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'typescript' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'typescript/lib/_tsc' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'typescript/lib/_tsserver' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'typescript/lib/_typingsInstaller' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'typescript/lib/tsc' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'typescript/lib/tsserver' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'typescript/lib/tsserverlibrary' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'typescript/lib/typescript' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'typescript/lib/typingsInstaller' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'typescript/lib/watchGuard' { 58 | declare module.exports: any; 59 | } 60 | 61 | // Filename aliases 62 | declare module 'typescript/lib/_tsc.js' { 63 | declare module.exports: $Exports<'typescript/lib/_tsc'>; 64 | } 65 | declare module 'typescript/lib/_tsserver.js' { 66 | declare module.exports: $Exports<'typescript/lib/_tsserver'>; 67 | } 68 | declare module 'typescript/lib/_typingsInstaller.js' { 69 | declare module.exports: $Exports<'typescript/lib/_typingsInstaller'>; 70 | } 71 | declare module 'typescript/lib/tsc.js' { 72 | declare module.exports: $Exports<'typescript/lib/tsc'>; 73 | } 74 | declare module 'typescript/lib/tsserver.js' { 75 | declare module.exports: $Exports<'typescript/lib/tsserver'>; 76 | } 77 | declare module 'typescript/lib/tsserverlibrary.js' { 78 | declare module.exports: $Exports<'typescript/lib/tsserverlibrary'>; 79 | } 80 | declare module 'typescript/lib/typescript.js' { 81 | declare module.exports: $Exports<'typescript/lib/typescript'>; 82 | } 83 | declare module 'typescript/lib/typingsInstaller.js' { 84 | declare module.exports: $Exports<'typescript/lib/typingsInstaller'>; 85 | } 86 | declare module 'typescript/lib/watchGuard.js' { 87 | declare module.exports: $Exports<'typescript/lib/watchGuard'>; 88 | } 89 | -------------------------------------------------------------------------------- /flow-typed/npm/universal-cookie_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: ee75f6f484234774d151789ac10f9e4d 2 | // flow-typed version: <>/universal-cookie_v^7.2.2/flow_v0.203.1 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'universal-cookie' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'universal-cookie' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'universal-cookie/cjs' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'universal-cookie/umd/universalCookie' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'universal-cookie/umd/universalCookie.min' { 34 | declare module.exports: any; 35 | } 36 | 37 | // Filename aliases 38 | declare module 'universal-cookie/cjs/index' { 39 | declare module.exports: $Exports<'universal-cookie/cjs'>; 40 | } 41 | declare module 'universal-cookie/cjs/index.js' { 42 | declare module.exports: $Exports<'universal-cookie/cjs'>; 43 | } 44 | declare module 'universal-cookie/umd/universalCookie.js' { 45 | declare module.exports: $Exports<'universal-cookie/umd/universalCookie'>; 46 | } 47 | declare module 'universal-cookie/umd/universalCookie.min.js' { 48 | declare module.exports: $Exports<'universal-cookie/umd/universalCookie.min'>; 49 | } 50 | -------------------------------------------------------------------------------- /flow-typed/npm/uuid_v8.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1b555a8f791762f2a4ee29e1335a175a 2 | // flow-typed version: a40f6e5201/uuid_v8.x.x/flow_>=v0.104.x 3 | 4 | declare module 'uuid' { 5 | // v1 (Timestamp) 6 | declare type V1Options = {| 7 | node?: $ReadOnlyArray, 8 | clockseq?: number, 9 | msecs?: number, 10 | nsecs?: number, 11 | random?: $ReadOnlyArray, 12 | rng?: () => $ReadOnlyArray, 13 | |}; 14 | 15 | declare export function v1(options?: V1Options): string; 16 | 17 | declare export function v1( 18 | options: V1Options | null, 19 | buffer: Array, 20 | offset?: number 21 | ): Array; 22 | 23 | // v3 (Namespace) 24 | declare function v3Impl( 25 | name: string | $ReadOnlyArray, 26 | namespace: string | $ReadOnlyArray 27 | ): string; 28 | 29 | declare function v3Impl( 30 | name: string | $ReadOnlyArray, 31 | namespace: string | $ReadOnlyArray, 32 | buffer: Array, 33 | offset?: number 34 | ): Array; 35 | 36 | declare export var v3: {| 37 | [[call]]: typeof v3Impl, 38 | DNS: string, 39 | URL: string, 40 | |}; 41 | 42 | // v4 (Random) 43 | declare type V4Options = {| 44 | random?: $ReadOnlyArray, 45 | rng?: () => $ReadOnlyArray, 46 | |}; 47 | 48 | declare export function v4(options?: V4Options): string; 49 | 50 | declare export function v4( 51 | options: V4Options | null, 52 | buffer: Array, 53 | offset?: number 54 | ): Array; 55 | 56 | // v5 (Namespace) 57 | declare function v5Impl( 58 | name: string | $ReadOnlyArray, 59 | namespace: string | $ReadOnlyArray 60 | ): string; 61 | 62 | declare function v5Impl( 63 | name: string | $ReadOnlyArray, 64 | namespace: string | $ReadOnlyArray, 65 | buffer: Array, 66 | offset?: number 67 | ): Array; 68 | 69 | declare export var v5: {| 70 | [[call]]: typeof v5Impl, 71 | DNS: string, 72 | URL: string, 73 | |}; 74 | } 75 | -------------------------------------------------------------------------------- /ignore_build.js: -------------------------------------------------------------------------------- 1 | const branch = (process.env.HEAD || ''); 2 | process.exitCode = branch.startsWith('dependabot/') && !branch.startsWith('dependabot/npm_and_yarn/react-') ? 0 : 1; 3 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Build command. 3 | command = "pnpm run netlify-build" 4 | 5 | # Publish diretory 6 | publish = "build/" 7 | 8 | # Ignore deploys for dependabot branches 9 | ignore = "node ignore_build.js" 10 | 11 | [[headers]] 12 | for = "/*" 13 | 14 | [headers.values] 15 | X-Content-Type-Options = "nosniff" 16 | X-Frame-Options = "DENY" 17 | X-XSS-Protection = "1; mode=block" 18 | Strict-Transport-Security = "max-age=63072000; includeSubDomains; preload" 19 | 20 | [[headers]] 21 | for = "/storybook/*" 22 | 23 | [headers.values] 24 | X-Frame-Options = "SAMEORIGIN" 25 | -------------------------------------------------------------------------------- /public/200.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | Relational Playground 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #00aba9 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 16 | 17 | 18 | 23 | 29 | 35 | 36 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 62 | 63 | 67 | 68 | 72 | 73 | 82 | Relational Playground 83 | 84 | 85 | 86 |
87 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Relational Playground", 3 | "name": "Relational Playground", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#00acff", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /public/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/mstile-144x144.png -------------------------------------------------------------------------------- /public/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/mstile-150x150.png -------------------------------------------------------------------------------- /public/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/mstile-310x150.png -------------------------------------------------------------------------------- /public/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/mstile-310x310.png -------------------------------------------------------------------------------- /public/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/mstile-70x70.png -------------------------------------------------------------------------------- /public/opengraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/public/opengraph.png -------------------------------------------------------------------------------- /public/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 26 | 38 | 51 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Relational Playground", 3 | "short_name": "Relational Playground", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Route, Routes} from 'react-router-dom'; 3 | import Home from './Home'; 4 | 5 | /** A container for all routes in the app (currently only one) */ 6 | function App() { 7 | return ( 8 |
9 |
10 | 11 | } /> 12 | 13 |
14 |
15 | ); 16 | } 17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import {MemoryRouter} from 'react-router'; 4 | import {configureStore} from '@reduxjs/toolkit'; 5 | import {Provider} from 'react-redux'; 6 | import {produce} from 'immer'; 7 | import App from './App'; 8 | 9 | /** @test {App} */ 10 | it('renders without crashing', () => { 11 | const div = document.createElement('div'); 12 | const initialState = { 13 | relexp: {expr: {}}, 14 | data: {sourceData: {}}, 15 | }; 16 | const store = configureStore({ 17 | reducer: { 18 | data: produce((state, action) => state, initialState), 19 | relexp: produce((state, action) => state, initialState), 20 | }, 21 | preloadedState: initialState, 22 | }); 23 | ReactDOM.render( 24 | 25 | 26 | 27 | 28 | , 29 | div 30 | ); 31 | ReactDOM.unmountComponentAtNode(div); 32 | }); 33 | -------------------------------------------------------------------------------- /src/BinaryRelOp.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {BinaryRelOp, Product, Join} from './RelOp'; 4 | import Relation from '../src/Relation'; 5 | 6 | const BinaryRelOpStories = { 7 | title: 'BinaryRelOp', 8 | component: BinaryRelOp, 9 | }; 10 | 11 | export default BinaryRelOpStories; 12 | 13 | export const SimpleProduct = () => ( 14 | } 16 | operator={} 17 | right={} 18 | /> 19 | ); 20 | SimpleProduct.storyName = 'a simple product'; 21 | 22 | export const SimpleJoin = ({joinType}) => ( 23 | } 25 | operator={ 26 | 27 | } 28 | right={} 29 | /> 30 | ); 31 | SimpleJoin.storyName = 'a simple join'; 32 | SimpleJoin.args = { 33 | joinType: 'left', 34 | }; 35 | SimpleJoin.argTypes = { 36 | joinType: { 37 | options: ['left', 'right', 'inner'], 38 | control: {type: 'inline-radio'}, 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /src/CurrentRelExpr.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React, {useState} from 'react'; 3 | import {useDispatch, useSelector} from 'react-redux'; 4 | import {changeExpr} from './modules/data'; 5 | import RelExpr from './RelExpr'; 6 | import RelExprTree from './RelExprTree'; 7 | 8 | import type {StatelessFunctionalComponent} from 'react'; 9 | import {disableOptimization, enableOptimization} from './modules/relexp'; 10 | 11 | import type {State} from './modules/relexp'; 12 | 13 | type Props = { 14 | ReactGA: any, 15 | }; 16 | 17 | const CurrentRelExpr: StatelessFunctionalComponent = (props) => { 18 | const dispatch = useDispatch(); 19 | const expr = useSelector<{relexp: State}, _>((state) => state.relexp.expr); 20 | const [showTree, setShowTree] = useState(false); 21 | const optimized = useSelector<{relexp: State}, _>( 22 | (state) => state.relexp.optimized 23 | ); 24 | 25 | function handleTreeInputChange(event: SyntheticInputEvent) { 26 | props.ReactGA.event({ 27 | category: 'Toggle Expression Display', 28 | action: event.target.checked ? 'tree' : 'linear', 29 | }); 30 | setShowTree(event.target.checked); 31 | } 32 | 33 | function handleOptimizeInputChange( 34 | event: SyntheticInputEvent 35 | ) { 36 | if (event.target.checked) { 37 | dispatch(enableOptimization('join')); 38 | } else { 39 | dispatch(disableOptimization()); 40 | } 41 | } 42 | 43 | const relExp = showTree ? ( 44 | dispatch(changeExpr(data, element))} 48 | /> 49 | ) : ( 50 | dispatch(changeExpr(data, element))} 54 | /> 55 | ); 56 | 57 | return ( 58 |
59 |
60 | 68 |
69 |
70 | 78 |
79 | 80 | {/* Relational algebra expression display */} 81 |
{relExp}
82 |
83 | ); 84 | }; 85 | 86 | export default CurrentRelExpr; 87 | -------------------------------------------------------------------------------- /src/CurrentRelExpr.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Provider} from 'react-redux'; 3 | import {mount} from 'enzyme'; 4 | import configureStore from 'redux-mock-store'; 5 | 6 | import CurrentRelExpr from './CurrentRelExpr'; 7 | import RelExpr from './RelExpr'; 8 | import RelExprTree from './RelExprTree'; 9 | 10 | const mockStore = configureStore([]); 11 | 12 | describe('CurrentRelExpr', () => { 13 | let store; 14 | 15 | beforeEach(() => { 16 | store = mockStore({ 17 | data: {expr: {}}, 18 | relexp: { 19 | expr: { 20 | selection: { 21 | arguments: { 22 | select: 'foo', 23 | }, 24 | children: [{relation: 'bar'}], 25 | }, 26 | }, 27 | }, 28 | }); 29 | }); 30 | 31 | /** @test {CurrentRelExpr} */ 32 | it('changes the expression when clicked not relation', () => { 33 | const mockEvent = jest.fn(); 34 | const wrapper = mount( 35 | 36 | 37 | 38 | ); 39 | 40 | // Start with non-tree representation 41 | expect(wrapper.find(RelExpr).length).toBe(2); 42 | expect(wrapper.find(RelExprTree).length).toBe(0); 43 | 44 | // Click the checkbox to toggle the tree view 45 | wrapper 46 | .find('input') 47 | .at(0) 48 | .simulate('change', {target: {checked: true}}); 49 | 50 | // Now only the tree view should display 51 | expect(wrapper.find(RelExpr).length).toBe(0); 52 | expect(wrapper.find(RelExprTree).length).toBe(1); 53 | 54 | // Click the checkbox again to toggle the tree view back 55 | wrapper 56 | .find('input') 57 | .at(0) 58 | .simulate('change', {target: {checked: false}}); 59 | 60 | // Click the checkbox to toggle query optimization 61 | wrapper 62 | .find('input') 63 | .at(1) 64 | .simulate('change', {target: {checked: true}}); 65 | 66 | // Click the checkbox again to toggle query optimization back 67 | wrapper 68 | .find('input') 69 | .at(1) 70 | .simulate('change', {target: {checked: false}}); 71 | 72 | // We should have analytics events for the checkbox 73 | expect(mockEvent.mock.calls.length).toBe(2); 74 | 75 | expect(mockEvent.mock.calls[0][0].category).toBe( 76 | 'Toggle Expression Display' 77 | ); 78 | expect(mockEvent.mock.calls[0][0].action).toBe('tree'); 79 | 80 | expect(mockEvent.mock.calls[1][0].category).toBe( 81 | 'Toggle Expression Display' 82 | ); 83 | expect(mockEvent.mock.calls[1][0].action).toBe('linear'); 84 | }); 85 | }); 86 | -------------------------------------------------------------------------------- /src/DataContainer.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import Table from './Table'; 4 | import {useSelector} from 'react-redux'; 5 | 6 | import type {StatelessFunctionalComponent} from 'react'; 7 | 8 | import type {State} from './modules/data'; 9 | 10 | const DataContainer: StatelessFunctionalComponent<{||}> = () => { 11 | const data = useSelector<{data: State}, _>((state) => state.data); 12 | if (data.current) { 13 | return ( 14 |
15 |

Data for selected expression

16 | 22 | 23 | ); 24 | } else { 25 | return ( 26 |
27 | Select an expression above. 28 |
29 | ); 30 | } 31 | }; 32 | 33 | export default DataContainer; 34 | -------------------------------------------------------------------------------- /src/DataContainer.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Provider} from 'react-redux'; 3 | import {mount} from 'enzyme'; 4 | import {produce} from 'immer'; 5 | import {configureStore} from '@reduxjs/toolkit'; 6 | 7 | import DataContainer from './DataContainer'; 8 | import Table from './Table'; 9 | 10 | describe('DataContainer', () => { 11 | /** @test {DataContainer} */ 12 | it('displays a table with the current data', () => { 13 | const initialState = { 14 | data: { 15 | current: { 16 | name: 'foo', 17 | columns: ['bar', 'baz'], 18 | data: [{bar: 1, baz: 2}], 19 | }, 20 | }, 21 | }; 22 | const mockStore = configureStore({ 23 | reducer: { 24 | data: produce((state, action) => state, initialState), 25 | }, 26 | preloadedState: initialState, 27 | }); 28 | const wrapper = mount( 29 | 30 | 31 | 32 | ); 33 | 34 | const table = wrapper.find(Table).first(); 35 | expect(table).toHaveProp({ 36 | tableName: 'foo', 37 | columns: ['bar', 'baz'], 38 | sortable: false, 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /src/EditorContainer.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import {useDispatch, useSelector} from 'react-redux'; 4 | import {useNavigate} from 'react-router-dom'; 5 | import fromEntries from 'fromentries'; 6 | import SqlEditor from './SqlEditor'; 7 | import {exprFromSql} from './modules/relexp'; 8 | import {resetAction} from './modules/data'; 9 | 10 | import type {StatelessFunctionalComponent} from 'react'; 11 | 12 | import type {State} from './modules/data'; 13 | 14 | type Props = { 15 | ReactGA: any, 16 | }; 17 | 18 | const EditorContainer: StatelessFunctionalComponent = (props) => { 19 | const types = useSelector<{data: State}, _>((state) => 20 | fromEntries( 21 | Object.entries(state.data.sourceData).map(([name, data]) => [ 22 | name, 23 | data != null && typeof data === 'object' ? data.columns : [], 24 | ]) 25 | ) 26 | ); 27 | const dispatch = useDispatch(); 28 | const navigate = useNavigate(); 29 | 30 | return ( 31 | dispatch(exprFromSql(sql, types))} 36 | resetAction={() => dispatch(resetAction())} 37 | types={types} 38 | /> 39 | ); 40 | }; 41 | 42 | export default EditorContainer; 43 | -------------------------------------------------------------------------------- /src/Home.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable */ 2 | .Resizer { 3 | background: #000; 4 | opacity: 0.2; 5 | z-index: 1; 6 | -moz-box-sizing: border-box; 7 | -webkit-box-sizing: border-box; 8 | box-sizing: border-box; 9 | -moz-background-clip: padding; 10 | -webkit-background-clip: padding; 11 | background-clip: padding-box; 12 | } 13 | 14 | .Resizer:hover { 15 | -webkit-transition: all 2s ease; 16 | transition: all 2s ease; 17 | } 18 | 19 | .Resizer.horizontal { 20 | height: 11px; 21 | margin: -5px 0; 22 | border-top: 5px solid rgba(255, 255, 255, 0); 23 | border-bottom: 5px solid rgba(255, 255, 255, 0); 24 | cursor: row-resize; 25 | width: 100%; 26 | } 27 | 28 | .Resizer.horizontal:hover { 29 | border-top: 5px solid rgba(0, 0, 0, 0.5); 30 | border-bottom: 5px solid rgba(0, 0, 0, 0.5); 31 | } 32 | 33 | .Resizer.vertical { 34 | width: 11px; 35 | margin: 0 -5px; 36 | border-left: 5px solid rgba(255, 255, 255, 0); 37 | border-right: 5px solid rgba(255, 255, 255, 0); 38 | cursor: col-resize; 39 | } 40 | 41 | .Resizer.vertical:hover { 42 | border-left: 5px solid rgba(0, 0, 0, 0.5); 43 | border-right: 5px solid rgba(0, 0, 0, 0.5); 44 | } 45 | 46 | .Resizer.disabled { 47 | cursor: not-allowed; 48 | } 49 | 50 | .Resizer.disabled:hover { 51 | border-color: transparent; 52 | } 53 | /* stylelint-enable */ 54 | 55 | .footer { 56 | padding: 20px; 57 | font-size: 0.75em; 58 | } 59 | 60 | .button { 61 | border-radius: 15px; 62 | font-weight: bold; 63 | background-color: lightgray; /* Green */ 64 | border: none; 65 | color: black; 66 | padding: 15px 32px; 67 | text-align: center; 68 | text-decoration: none; 69 | display: inline-block; 70 | margin-top: 20px; 71 | margin-left: 0; 72 | margin-bottom: 20px; 73 | font-size: 1em; 74 | cursor: pointer; 75 | } 76 | 77 | .footer .button { 78 | float: right; 79 | } 80 | 81 | .email { 82 | float: left; 83 | } 84 | 85 | .relExprContainer { 86 | margin-top: 2em; 87 | } 88 | 89 | .relExprContainer .expr { 90 | font-family: 'Fira Code', 'Fira Mono', monospace; 91 | font-display: swap; 92 | margin-top: 20px; 93 | margin-bottom: 20px; 94 | background-color: white; 95 | padding: 8px; 96 | border-radius: 10px; 97 | } 98 | 99 | .relExprContainer .toggle { 100 | float: right; 101 | font-size: 0.75em; 102 | position: relative; 103 | top: -1.75em; 104 | } 105 | 106 | .relExprContainer .toggle input { 107 | vertical-align: middle; 108 | } 109 | 110 | .bottomLeftContainer { 111 | width: 100%; 112 | align-items: stretch; 113 | display: flex; 114 | flex-direction: column; 115 | justify-content: space-between; 116 | } 117 | 118 | .dataContainer { 119 | background-color: white; 120 | border-radius: 10px; 121 | padding: 0; 122 | } 123 | 124 | h2 { 125 | margin-top: 8px; 126 | margin-bottom: 8px; 127 | } 128 | 129 | @media only screen and (max-width: 600px) { 130 | h2 { 131 | padding-left: 24px; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Home.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from 'react'; 3 | import {lazy, useEffect, Suspense} from 'react'; 4 | import CurrentRelExpr from './CurrentRelExpr'; 5 | import DataContainer from './DataContainer'; 6 | import EditorContainer from './EditorContainer'; 7 | import SourceMultiTable from './SourceMultiTable'; 8 | import SplitPane from 'react-split-pane'; 9 | import {BrowserView, MobileOnlyView} from 'react-device-detect'; 10 | import ReactGA from 'react-ga'; 11 | 12 | import './Home.css'; 13 | 14 | import type {StatelessFunctionalComponent} from 'react'; 15 | 16 | const Tutorial = lazy(() => import('./Tutorial')); 17 | 18 | type Props = {}; 19 | 20 | /** Container for all components on the main page */ 21 | const Home: StatelessFunctionalComponent = (props) => { 22 | useEffect(() => { 23 | // If GA is no longer used, remove preconnect from index.html 24 | switch (process.env.NODE_ENV) { 25 | case 'production': 26 | ReactGA.initialize('UA-143847373-2'); 27 | break; 28 | case 'development': 29 | ReactGA.initialize('UA-143847373-1'); 30 | break; 31 | default: 32 | ReactGA.initialize('UA-143847373-1', {testMode: true}); 33 | break; 34 | } 35 | ReactGA.pageview('/'); 36 | }, []); 37 | 38 | let editorContainer = ( 39 |
40 |

Relational Playground

41 |
42 | {/* SQL query input */} 43 | 44 | 45 |
46 |
47 | ); 48 | 49 | let dataContainer = ( 50 |
51 | 52 |
53 | }> 54 | 55 | 56 |

57 | For questions, please email{' '} 58 | mmior@mail.rit.edu 59 |

60 |
61 |
62 | ); 63 | 64 | return ( 65 |
66 | 67 | 68 |
69 | 70 | {editorContainer} 71 | {dataContainer} 72 | 73 |
74 | {/* Input dataset preview */} 75 |
76 | 77 |
78 |
79 |
80 | 81 | 82 |
83 | {editorContainer} 84 | 85 |
86 | {dataContainer} 87 |
88 |
89 | ); 90 | }; 91 | 92 | export default Home; 93 | -------------------------------------------------------------------------------- /src/MultiTable.css: -------------------------------------------------------------------------------- 1 | .tableDiv { 2 | margin-top: 7px; 3 | margin-bottom: 7px; 4 | font-size: 15px; 5 | } 6 | 7 | .browserSelect, 8 | .mobileSelect { 9 | width: 100%; 10 | font-size: 1em; 11 | padding: 0.5em; 12 | } 13 | 14 | .mobileButton { 15 | border-radius: 15px; 16 | font-weight: bold; 17 | background-color: lightgray; /* Green */ 18 | border: none; 19 | color: black; 20 | padding: 15px 32px; 21 | text-align: center; 22 | text-decoration: none; 23 | display: inline-block; 24 | margin-top: 20px; 25 | margin-left: 0; 26 | margin-bottom: 20px; 27 | font-size: 15px; 28 | } 29 | 30 | .sourceTableContainer { 31 | background-color: white; 32 | border-radius: 10px; 33 | padding: 8px; 34 | } 35 | -------------------------------------------------------------------------------- /src/MultiTable.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from 'react'; 3 | import Table from './Table'; 4 | import {BrowserView, MobileOnlyView, isMobileOnly} from 'react-device-detect'; 5 | 6 | import './MultiTable.css'; 7 | 8 | import type {StatelessFunctionalComponent} from 'react'; 9 | import type {Data} from './modules/data'; 10 | 11 | type Props = { 12 | tables: {[string]: Data}, 13 | ReactGA: any, 14 | testIsMobile?: boolean, 15 | }; 16 | 17 | const tableHiddenText = 'Show Table'; 18 | const tableShownText = 'Hide Table'; 19 | 20 | /** Displays more than one table with a dropdown to choose */ 21 | const MultiTable: StatelessFunctionalComponent = (props) => { 22 | const [showTableMobile, setShowTableMobile] = React.useState(false); 23 | const [selected, setSelected] = React.useState(Object.keys(props.tables)[0]); 24 | const [isMobile] = React.useState(isMobileOnly); 25 | const [buttonText, setButtonText] = React.useState(tableHiddenText); 26 | 27 | // TODO: Fix type annotation below 28 | const handleChange = (e: any) => { 29 | if (e.target !== undefined) { 30 | setSelected(e.target.value); 31 | props.ReactGA.event({ 32 | category: 'User Selecting A Table', 33 | action: e.target.value, 34 | }); 35 | } 36 | }; 37 | 38 | function handleButtonPress(): void { 39 | setShowTableMobile(!showTableMobile); 40 | setButtonText( 41 | buttonText === tableShownText ? tableHiddenText : tableShownText 42 | ); 43 | } 44 | 45 | // Render the selected table 46 | let table: React.Node =
Select a table above.
; 47 | if (isMobile) { 48 | if (showTableMobile) { 49 | const data = props.tables[selected]; 50 | table = ( 51 |
56 | ); 57 | } else { 58 | table =
Select a table above.
; 59 | } 60 | 61 | return ( 62 |
63 | 64 |

Source relations

65 | 78 | 79 |
80 | {table} 81 | 84 |
85 |
86 |
87 | ); 88 | } else if (selected) { 89 | const data = props.tables[selected]; 90 | table = ( 91 |
92 | ); 93 | } 94 | 95 | // Render the menu along with the table 96 | return ( 97 |
98 | 99 |

Source relations

100 | 101 | 110 | 111 | {table} 112 |
113 |
114 | ); 115 | }; 116 | 117 | export default MultiTable; 118 | -------------------------------------------------------------------------------- /src/MultiTable.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import MultiTable from '../src/MultiTable'; 4 | 5 | const MultiTableStories = { 6 | title: 'MultiTable', 7 | component: MultiTable, 8 | }; 9 | 10 | export default MultiTableStories; 11 | 12 | export const SeveralSources = () => ( 13 | 33 | ); 34 | SeveralSources.storyName = 'with several sources'; 35 | -------------------------------------------------------------------------------- /src/MultiTable.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {shallow} from 'enzyme'; 3 | import * as reactDeviceDetect from 'react-device-detect'; 4 | import MultiTable from './MultiTable'; 5 | import dataReducer from './modules/data'; 6 | 7 | it('can change tables browser', () => { 8 | const mockEvent = jest.fn(); 9 | 10 | // Fake a reducer call to get the initial state 11 | const data = dataReducer(undefined, {}).sourceData; 12 | 13 | const wrapper = shallow( 14 | 15 | ); 16 | 17 | let browserSelect = wrapper.find('.browserSelect'); 18 | 19 | // Change the table 20 | browserSelect.simulate('change', {target: {value: 'Patient'}}); 21 | 22 | expect(mockEvent.mock.calls.length).toBe(1); 23 | expect(mockEvent.mock.calls[0][0].category).toBe('User Selecting A Table'); 24 | expect(mockEvent.mock.calls[0][0].action).toBe('Patient'); 25 | 26 | expect(wrapper.find('.browserTable').prop('columns')).toBe( 27 | data.Patient.columns 28 | ); 29 | expect(wrapper.find('.browserTable').prop('data')).toBe(data.Patient.data); 30 | }); 31 | 32 | it('can change tables mobile', () => { 33 | const mockEvent = jest.fn(); 34 | // Fake a reducer call to get the initial state 35 | const data = dataReducer(undefined, {}).sourceData; 36 | 37 | reactDeviceDetect.isMobileOnly = true; 38 | const wrapper = shallow( 39 | 40 | ); 41 | 42 | let mobileSelect = wrapper.find('.mobileSelect'); 43 | mobileSelect.simulate('change', {target: {value: 'Patient'}}); 44 | 45 | expect(mockEvent.mock.calls.length).toBe(1); 46 | expect(mockEvent.mock.calls[0][0].category).toBe('User Selecting A Table'); 47 | expect(mockEvent.mock.calls[0][0].action).toBe('Patient'); 48 | 49 | let mobileButton = wrapper.find('.mobileButton'); 50 | mobileButton.simulate('click'); 51 | 52 | expect(wrapper.find('.mobileTable').prop('columns')).toBe( 53 | data.Patient.columns 54 | ); 55 | expect(wrapper.find('.mobileTable').prop('data')).toBe(data.Patient.data); 56 | }); 57 | -------------------------------------------------------------------------------- /src/RelExpr.css: -------------------------------------------------------------------------------- 1 | .RelExpr .clicked, 2 | .RelExpr.clicked { 3 | background: #ff3; 4 | cursor: pointer; 5 | } 6 | 7 | .RelExpr .hovering, 8 | .RelExpr.hovering { 9 | background: #ffffb8; 10 | cursor: pointer; 11 | } 12 | -------------------------------------------------------------------------------- /src/RelExpr.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Provider} from 'react-redux'; 3 | import {produce} from 'immer'; 4 | import {configureStore} from '@reduxjs/toolkit'; 5 | 6 | import RelExpr from './RelExpr'; 7 | 8 | const initialState = {data: {expr: null}}; 9 | const mockStore = configureStore({ 10 | reducer: { 11 | data: produce((state, action) => state, initialState), 12 | }, 13 | preloadedState: initialState, 14 | }); 15 | 16 | const MockedStore = ({children}) => ( 17 | {children} 18 | ); 19 | 20 | const RelExprStories = { 21 | title: 'RelExpr', 22 | component: RelExpr, 23 | decorators: [(story) => {story()}], 24 | }; 25 | 26 | export default RelExprStories; 27 | 28 | export const ComplexExpression = () => ( 29 | undefined} 53 | /> 54 | ); 55 | ComplexExpression.storyName = 'a complex expression'; 56 | -------------------------------------------------------------------------------- /src/RelExprTree.css: -------------------------------------------------------------------------------- 1 | .RelExprTree li { 2 | list-style-type: none; 3 | } 4 | -------------------------------------------------------------------------------- /src/RelExprTree.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import TreeMenu, {ItemComponent} from 'react-simple-tree-menu'; 4 | import {v4 as uuidv4} from 'uuid'; 5 | import { 6 | Projection, 7 | Rename, 8 | Selection, 9 | Except, 10 | Product, 11 | Join, 12 | Intersect, 13 | Union, 14 | } from './RelOp'; 15 | import {exprToString} from './util'; 16 | import {changeExpr} from './modules/data'; 17 | 18 | import '../node_modules/react-simple-tree-menu/dist/main.css'; 19 | import './RelExprTree.css'; 20 | 21 | import type {Node, StatelessFunctionalComponent} from 'react'; 22 | 23 | type Props = { 24 | changeExpr: typeof changeExpr, 25 | expr: {[string]: any}, 26 | ReactGA: any, 27 | }; 28 | 29 | /** A graphical representation of a relational algebra expression */ 30 | const RelExprTree: StatelessFunctionalComponent = (props) => { 31 | /** 32 | * @param expr - a relational algebra expression object to render 33 | * @param keys - an array where all created paths should be saved 34 | * @param path - the path to the current node 35 | * @return a tree structure representing the exppression 36 | */ 37 | const buildTree = ( 38 | expr: {[string]: any}, 39 | keys: Array, 40 | path: Array = [] 41 | ): {} => { 42 | // Don't try to render empty expressions 43 | if (!expr || Object.keys(expr).length === 0) { 44 | return {}; 45 | } 46 | 47 | // Save the constructed path so we can set this open later 48 | const key = uuidv4(); 49 | const newPath = [...path, key]; 50 | keys.push(newPath.join('/')); 51 | 52 | const type = Object.keys(expr)[0]; 53 | switch (type) { 54 | case 'projection': 55 | case 'selection': 56 | case 'rename': 57 | return { 58 | key: key, 59 | expr: expr, 60 | nodes: [buildTree(expr[type].children[0], keys, newPath)], 61 | }; 62 | case 'relation': 63 | return { 64 | key: key, 65 | expr: expr, 66 | }; 67 | case 'except': 68 | case 'intersect': 69 | case 'join': 70 | case 'product': 71 | case 'union': 72 | return { 73 | key: key, 74 | expr: expr, 75 | nodes: [ 76 | buildTree(expr[type].left, keys, newPath), 77 | buildTree(expr[type].right, keys, newPath), 78 | ], 79 | }; 80 | default: 81 | throw new Error('Invalid expression ' + JSON.stringify(expr) + '.'); 82 | } 83 | }; 84 | 85 | const getLabel = (expr: {[string]: any}): Node => { 86 | if (!expr || Object.keys(expr).length === 0) { 87 | return ''; 88 | } 89 | 90 | const type = Object.keys(expr)[0]; 91 | switch (type) { 92 | case 'projection': 93 | return ; 94 | case 'selection': 95 | return ( 96 | 97 | ); 98 | case 'rename': 99 | return ; 100 | case 'relation': 101 | return expr.relation; 102 | case 'join': 103 | return ( 104 | 108 | ); 109 | case 'except': 110 | case 'intersect': 111 | case 'product': 112 | case 'union': 113 | const operator = { 114 | except: , 115 | intersect: , 116 | product: , 117 | union: , 118 | }[type]; 119 | return operator; 120 | default: 121 | throw new Error('Invalid expression ' + JSON.stringify(expr) + '.'); 122 | } 123 | }; 124 | 125 | const keys: Array = []; 126 | const data = [buildTree(props.expr, keys)]; 127 | return ( 128 |
129 | { 135 | props.changeExpr(clickProps.expr, null); 136 | 137 | props.ReactGA.event({ 138 | category: 'User Selecting Relational Algebra Tree', 139 | action: Object.keys(clickProps.expr)[0], 140 | }); 141 | }} 142 | > 143 | {({search, items}) => ( 144 |
145 | {items.map(({key, ...props}) => { 146 | const newProps = {label: getLabel(props.expr)}; 147 | Object.assign(props, newProps); 148 | return ; 149 | })} 150 |
151 | )} 152 |
153 |
154 | ); 155 | }; 156 | 157 | export default RelExprTree; 158 | -------------------------------------------------------------------------------- /src/RelExprTree.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import RelExprTree from './RelExprTree'; 4 | 5 | const RelExprTreeStories = { 6 | title: 'RelExprTree', 7 | component: RelExprTree, 8 | }; 9 | 10 | export default RelExprTreeStories; 11 | 12 | export const ComplexExpression = () => ( 13 | undefined} 37 | /> 38 | ); 39 | ComplexExpression.storyName = 'a complex expression'; 40 | 41 | export const SimpleJoin = ({joinType}) => ( 42 | undefined} 54 | /> 55 | ); 56 | SimpleJoin.storyName = 'a simple join'; 57 | SimpleJoin.args = { 58 | joinType: 'left', 59 | }; 60 | SimpleJoin.argTypes = { 61 | joinType: { 62 | options: ['left', 'right', 'inner'], 63 | control: {type: 'inline-radio'}, 64 | }, 65 | }; 66 | 67 | export const JustARelation = () => ( 68 | undefined} 71 | /> 72 | ); 73 | JustARelation.storyName = 'just a relation'; 74 | -------------------------------------------------------------------------------- /src/RelExprTree.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import renderer from 'react-test-renderer'; 3 | 4 | import RelExprTree from './RelExprTree'; 5 | import {Selection} from './RelOp'; 6 | import {mount} from 'enzyme'; 7 | 8 | /** @test {RelExprTree} */ 9 | it('correctly renders a complex expression', () => { 10 | const expr = { 11 | rename: { 12 | arguments: {rename: {columns: {firstName: 'name'}}}, 13 | children: [ 14 | { 15 | projection: { 16 | arguments: {project: ['firstName', 'lastName']}, 17 | children: [ 18 | { 19 | selection: { 20 | arguments: { 21 | select: {cmp: {lhs: 'salary', op: '$gt', rhs: 130000}}, 22 | }, 23 | children: [{relation: 'Doctor'}], 24 | }, 25 | }, 26 | ], 27 | }, 28 | }, 29 | ], 30 | }, 31 | }; 32 | const tree = renderer 33 | .create() 34 | .toJSON(); 35 | expect(tree).toMatchSnapshot(); 36 | }); 37 | 38 | const condTests = [ 39 | ['$gte', '>='], 40 | ['$gt', '>'], 41 | ['$lt', '<'], 42 | ['$lte', '<='], 43 | ['$ne', '!='], 44 | ['$eq', '='], 45 | ]; 46 | 47 | /** @test {RelExprTree} */ 48 | it.each(condTests)('it correctly renders a %s condition as %s', (op, str) => { 49 | const expr = { 50 | selection: { 51 | arguments: {select: {cmp: {lhs: 'salary', op: op, rhs: 130000}}}, 52 | children: [{relation: 'Doctor'}], 53 | }, 54 | }; 55 | const wrapper = mount(); 56 | expect(wrapper.find(Selection).text()).toContain('salary ' + str + ' 130000'); 57 | }); 58 | 59 | /** @test {RelExprTree} */ 60 | it('produces an error for an invalid expression', () => { 61 | const errorObject = console.error; 62 | console.error = jest.fn(); 63 | 64 | expect(() => { 65 | renderer.create( 66 | 67 | ); 68 | }).toThrow(); 69 | 70 | console.error = errorObject; 71 | }); 72 | 73 | /** @test {RelExprTree} */ 74 | it('doesnt change the expression when clicked and relation', () => { 75 | const mockAction = jest.fn(); 76 | const mockEvent = jest.fn(); 77 | const expr = {relation: 'foo'}; 78 | const wrapper = mount( 79 | 84 | ); 85 | 86 | // Click on the expression 87 | wrapper.simulate('click', {stopPropagation: jest.fn()}); 88 | 89 | // An action changing the expression should fire 90 | // Should not have action attached when type relation 91 | expect(mockAction.mock.calls.length).toBe(0); 92 | 93 | // Don't expect analytics on a relation 94 | expect(mockEvent.mock.calls.length).toBe(0); 95 | }); 96 | 97 | /** @test {RelExprTree} */ 98 | it('changes the expression when clicked not relation', () => { 99 | const mockAction = jest.fn(); 100 | const mockEvent = jest.fn(); 101 | const expr = { 102 | selection: { 103 | arguments: { 104 | select: 'foo', 105 | }, 106 | children: [{relation: 'bar'}], 107 | }, 108 | }; 109 | const wrapper = mount( 110 | 115 | ); 116 | 117 | // Click on the expression 118 | wrapper.find('li').first().simulate('click', {stopPropagation: jest.fn()}); 119 | 120 | // An action changing the expression should fire 121 | expect(mockAction.mock.calls.length).toBe(1); 122 | expect(mockAction.mock.calls[0][0]).toBe(expr); 123 | 124 | // And also an analytics event 125 | expect(mockEvent.mock.calls.length).toBe(1); 126 | expect(mockEvent.mock.calls[0][0].category).toBe( 127 | 'User Selecting Relational Algebra Tree' 128 | ); 129 | expect(mockEvent.mock.calls[0][0].action).toBe('selection'); 130 | }); 131 | -------------------------------------------------------------------------------- /src/RelOp.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | 4 | import type {Element, Node, StatelessFunctionalComponent} from 'react'; 5 | import type {OrderByColumn} from './modules/relexp'; 6 | 7 | type Props = { 8 | children: Node, 9 | }; 10 | 11 | /** Base for all relational algebra operators */ 12 | const RelOp: StatelessFunctionalComponent = (props) => { 13 | return {props.children}; 14 | }; 15 | 16 | export default RelOp; 17 | 18 | type UnaryProps = { 19 | operator: Element, 20 | children: Node, 21 | }; 22 | 23 | const UnaryRelOpInternal: StatelessFunctionalComponent = ( 24 | props 25 | ) => ( 26 | 27 | {props.operator}({props.children}) 28 | 29 | ); 30 | 31 | export const UnaryRelOp: StatelessFunctionalComponent = (props) => ( 32 | 33 | 34 | 35 | ); 36 | 37 | /** Projection relational algebra operator */ 38 | export const Projection: StatelessFunctionalComponent<{ 39 | project: Array, 40 | }> = (props) => ( 41 | 42 | π{props.project.join(',')} 43 | 44 | ); 45 | 46 | /** Rename relational algebra operator */ 47 | export const Rename: StatelessFunctionalComponent<{ 48 | rename: {[string]: any}, 49 | }> = (props) => ( 50 | 51 | ρ 52 | 53 | {/* Loop over all columns to rename and combine them */} 54 | {Object.entries(props.rename.columns) 55 | .map(([o, n]) => { 56 | return o + '/' + ((n: any): string); 57 | }) 58 | .join(',')} 59 | 60 | 61 | ); 62 | 63 | /** Selection relational algebra operator */ 64 | export const Selection: StatelessFunctionalComponent<{select: string}> = ( 65 | props 66 | ) => ( 67 | 68 | σ{props.select} 69 | 70 | ); 71 | 72 | type BinaryProps = { 73 | operator: Element, 74 | left: Node, 75 | right: Node, 76 | }; 77 | 78 | const BinaryRelOpInternal: StatelessFunctionalComponent = ( 79 | props 80 | ) => ( 81 | 82 | {props.left} 83 | {props.operator} 84 | {props.right} 85 | 86 | ); 87 | 88 | export const BinaryRelOp: StatelessFunctionalComponent = ( 89 | props 90 | ) => ( 91 | 92 | 97 | 98 | ); 99 | 100 | export const Except: StatelessFunctionalComponent<{||}> = () => ( 101 | 102 | ); 103 | 104 | export const Intersect: StatelessFunctionalComponent<{||}> = () => ( 105 | 106 | ); 107 | 108 | export const OrderBy: StatelessFunctionalComponent<{ 109 | columns: Array, 110 | relation: Node, 111 | }> = (props) => { 112 | const columnSort = props.columns 113 | .map((c) => c.column_name + (c.ascending ? ' ↑' : ' ↓')) 114 | .join(', '); 115 | return ( 116 | 117 | τ{columnSort} {props.relation} 118 | 119 | ); 120 | }; 121 | 122 | export const Join: StatelessFunctionalComponent<{ 123 | type: string, 124 | condition: string, 125 | left?: Node, 126 | right?: Node, 127 | }> = (props) => { 128 | if (props.type === 'left') { 129 | return ( 130 | 131 | {props.left} ⟕{props.condition} {props.right} 132 | 133 | ); 134 | } else if (props.type === 'right') { 135 | return ( 136 | 137 | {props.left} ⟖{props.condition} {props.right} 138 | 139 | ); 140 | } else { 141 | return ( 142 | 143 | {props.left} ⋈{props.condition} {props.right} 144 | 145 | ); 146 | } 147 | }; 148 | 149 | export const Product: StatelessFunctionalComponent<{||}> = () => ( 150 | × 151 | ); 152 | 153 | export const Union: StatelessFunctionalComponent<{||}> = () => ( 154 | 155 | ); 156 | -------------------------------------------------------------------------------- /src/RelOp.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render} from '@testing-library/react'; 3 | 4 | import { 5 | Projection, 6 | Rename, 7 | Selection, 8 | Except, 9 | Intersect, 10 | Product, 11 | Join, 12 | Union, 13 | } from './RelOp'; 14 | 15 | /** @test {Projection} */ 16 | it('renders a projection', () => { 17 | const {container} = render(); 18 | expect(container).toContainHTML('πfoo,bar'); 19 | }); 20 | 21 | /** @test {Rename} */ 22 | it('renders a Rename', () => { 23 | const {container} = render(); 24 | expect(container).toContainHTML('ρfoo/bar'); 25 | }); 26 | 27 | /** @test {Rename} */ 28 | it('renders a Rename with multiple fields', () => { 29 | const {container} = render( 30 | 31 | ); 32 | expect(container).toContainHTML('ρfoo/bar,baz/quux'); 33 | }); 34 | 35 | /** @test {Selection} */ 36 | it('renders a Selection with single predicate', () => { 37 | const {container} = render(); 38 | expect(container).toContainHTML('σfoo=3'); 39 | }); 40 | 41 | /** @test {Selection} */ 42 | it('renders a Selection with multiple predicates', () => { 43 | const {container} = render(); 44 | expect(container).toContainHTML('σfoo=3 ∧ bar=2'); 45 | }); 46 | 47 | /** @test {Except} */ 48 | it('renders a Except', () => { 49 | const {container} = render(); 50 | expect(container).toContainHTML('−'); 51 | }); 52 | 53 | /** @test {Intersect} */ 54 | it('renders a Intersect', () => { 55 | const {container} = render(); 56 | expect(container).toContainHTML('∩'); 57 | }); 58 | 59 | /** @test {Product} */ 60 | it('renders a Product', () => { 61 | const {container} = render(); 62 | expect(container).toContainHTML('×'); 63 | }); 64 | 65 | /** @test {Join} */ 66 | it('renders an inner Join', () => { 67 | const {container} = render( 68 | 69 | ); 70 | expect(container).toContainHTML('A ⋈foo=3 ∧ bar=2 B'); 71 | }); 72 | 73 | /** @test {Join} */ 74 | it('renders a left outer Join', () => { 75 | const {container} = render( 76 | 77 | ); 78 | expect(container).toContainHTML('A ⟕foo=3 ∧ bar=2 B'); 79 | }); 80 | 81 | /** @test {Join} */ 82 | it('renders a right outer Join', () => { 83 | const {container} = render( 84 | 85 | ); 86 | expect(container).toContainHTML('⟖foo=3 ∧ bar=2'); 87 | }); 88 | 89 | /** @test {Union} */ 90 | it('renders a Union', () => { 91 | const {container} = render(); 92 | expect(container).toContainHTML('∪'); 93 | }); 94 | -------------------------------------------------------------------------------- /src/Relation.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataunitylab/relational-playground/30459e117b8088e978399db0097646413898a1d3/src/Relation.css -------------------------------------------------------------------------------- /src/Relation.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | 4 | import './Relation.css'; 5 | 6 | import type {StatelessFunctionalComponent} from 'react'; 7 | 8 | type Props = { 9 | name: string, 10 | }; 11 | 12 | /** Simple component to display a relation name as part of an expression */ 13 | const Relation: StatelessFunctionalComponent = (props) => ( 14 | 15 | {props.name} 16 | 17 | ); 18 | 19 | export default Relation; 20 | -------------------------------------------------------------------------------- /src/Relation.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render} from '@testing-library/react'; 3 | 4 | import Relation from './Relation'; 5 | 6 | /** @test {Relation} */ 7 | it('renders a simple label', () => { 8 | const {container, getByTestId} = render(); 9 | expect(container).toHaveTextContent('Test'); 10 | 11 | const inner = getByTestId('span'); 12 | expect(inner).toHaveClass('Relation'); 13 | }); 14 | -------------------------------------------------------------------------------- /src/SourceMultiTable.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import {useSelector} from 'react-redux'; 4 | import MultiTable from './MultiTable'; 5 | 6 | import type {StatelessFunctionalComponent} from 'react'; 7 | 8 | import type {State} from './modules/data'; 9 | 10 | type Props = { 11 | ReactGA: any, 12 | }; 13 | 14 | const SourceMultiTable: StatelessFunctionalComponent = (props) => { 15 | const sources = useSelector<{data: State}, _>( 16 | (state) => state.data.sourceData 17 | ); 18 | return ; 19 | }; 20 | 21 | export default SourceMultiTable; 22 | -------------------------------------------------------------------------------- /src/SqlEditor.css: -------------------------------------------------------------------------------- 1 | /* If all Google Fonts are removed, remove preconnect from index.html */ 2 | @import url('https://fonts.googleapis.com/css2?family=Fira+Code&display=swap'); 3 | 4 | h4 { 5 | margin-top: 0; 6 | margin-left: 3px; 7 | margin-bottom: 8px; 8 | } 9 | 10 | .SqlEditor { 11 | background-image: radial-gradient(circle, #f2f2f2, #d9d9d9); 12 | padding: 10px; 13 | border-radius: 8px; 14 | box-sizing: border-box; 15 | margin: auto; 16 | width: 100%; 17 | display: flex; 18 | flex-direction: column; 19 | } 20 | 21 | .editor { 22 | border-radius: 8px; 23 | background-color: white; 24 | } 25 | 26 | .SqlEditor .error { 27 | font-weight: bold; 28 | padding: 0.1em; 29 | } 30 | -------------------------------------------------------------------------------- /src/SqlEditor.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import * as React from 'react'; 3 | import Editor from 'react-simple-code-editor'; 4 | import {highlight, languages} from 'prismjs/components/prism-core'; 5 | import 'prismjs/components/prism-sql'; 6 | import {exprFromSql} from './modules/relexp'; 7 | import {resetAction} from './modules/data'; 8 | import './SqlEditor.css'; 9 | 10 | import 'prismjs/themes/prism.css'; 11 | 12 | import type {Node} from 'react'; 13 | 14 | const parser = require('@michaelmior/js-sql-parser'); 15 | 16 | type Props = { 17 | navigate: any, 18 | defaultText: string, 19 | exprFromSql: typeof exprFromSql, 20 | resetAction: typeof resetAction, 21 | ReactGA: any, 22 | types: {[string]: Array}, 23 | }; 24 | 25 | type State = { 26 | error: string | null, 27 | timeout: any, 28 | query: string, 29 | }; 30 | 31 | /** Editor for SQL queries */ 32 | class SqlEditor extends React.Component { 33 | constructor() { 34 | super(); 35 | // $FlowFixMe[method-unbinding] 36 | (this: any).handleChange = this.handleChange.bind(this); 37 | // $FlowFixMe[method-unbinding] 38 | (this: any).parseQuery = this.parseQuery.bind(this); 39 | this.state = {error: null, timeout: null, query: ''}; 40 | } 41 | 42 | componentDidMount() { 43 | // Parse the initial query when we start 44 | const values = new URL(window.location.toString()).searchParams; 45 | const query = values.get('query'); 46 | 47 | if (query) { 48 | this.parseQuery(query, false); 49 | this.setState({query: query}); 50 | } else { 51 | this.parseQuery(this.props.defaultText, true); 52 | this.setState({query: this.props.defaultText}); 53 | } 54 | } 55 | 56 | /** 57 | * @param text - the query to parse 58 | * @param firstLoad - whether this is the first call when mounted 59 | */ 60 | parseQuery(text: string, firstLoad?: boolean): void { 61 | if (!firstLoad) { 62 | if (this.props.resetAction) { 63 | this.props.resetAction(); 64 | } 65 | this.setState({timeout: null}); 66 | } 67 | try { 68 | const sql = parser.parse(text); 69 | if ( 70 | sql.nodeType === 'Main' && 71 | ['Except', 'Intersect', 'Select', 'Union'].includes(sql.value.type) 72 | ) { 73 | // Record the typed SQL statement 74 | if (!firstLoad) { 75 | this.props.ReactGA.event({ 76 | category: 'User Typing SQL Statement', 77 | action: text, 78 | }); 79 | } 80 | 81 | // Parse the query 82 | this.props.exprFromSql(sql.value, this.props.types); 83 | this.props.navigate('/?query=' + text); 84 | 85 | if (!firstLoad) { 86 | this.setState({error: null}); 87 | } 88 | } else { 89 | // Show an error if we try to parse any unsupported query type 90 | const errMsg = 'Unsupported expression'; 91 | if (!firstLoad) { 92 | this.setState({error: errMsg}); 93 | } 94 | } 95 | } catch (err) { 96 | // Display any error message generated during parsing 97 | if (!firstLoad) { 98 | this.setState({error: err.message}); 99 | } 100 | } 101 | } 102 | 103 | handleChange(text: string): void { 104 | // Cancel any pending query parsing 105 | if (this.state.timeout) { 106 | clearTimeout(this.state.timeout); 107 | } 108 | 109 | // Only parse the query once per second 110 | let handle = setTimeout(() => { 111 | this.parseQuery(text); 112 | }, 1000); 113 | 114 | this.setState({timeout: handle, query: text}); 115 | } 116 | 117 | render(): Node { 118 | // Include any error message if needed 119 | let error: React.Node = ; 120 | if (this.state.error) { 121 | error =
{this.state.error}
; 122 | } 123 | 124 | return ( 125 |
126 | 129 |
130 | highlight(code, languages.sql)} 135 | padding={10} 136 | style={{ 137 | fontDisplay: 'swap', 138 | fontFamily: '"Fira Code", monospace', 139 | }} 140 | textareaId="sqlInput" 141 | /> 142 |
143 |
{error}
144 |
145 | ); 146 | } 147 | } 148 | 149 | export default SqlEditor; 150 | -------------------------------------------------------------------------------- /src/SqlEditor.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {shallow} from 'enzyme'; 3 | 4 | import Editor from 'react-simple-code-editor'; 5 | import SqlEditor from './SqlEditor'; 6 | 7 | it('can parse the initial query', () => { 8 | const types = {foo: ['bar', 'baz']}; 9 | const mockAction = jest.fn(); 10 | const mockEvent = jest.fn(); 11 | const mockResetAction = jest.fn(() => undefined); 12 | 13 | // eslint-disable-next-line no-native-reassign 14 | window = Object.create(window); 15 | 16 | Object.defineProperty(window, 'location', { 17 | value: new URL('http://localhost:3000/'), 18 | }); 19 | 20 | shallow( 21 | 28 | ); 29 | 30 | // A redux action should fire with the parsed query 31 | expect(mockAction.mock.calls.length).toBe(1); 32 | expect(mockAction.mock.calls[0][0].type).toBe('Select'); 33 | expect(mockAction.mock.calls[0][1]).toEqual(types); 34 | 35 | // No events should be recorded 36 | expect(mockEvent.mock.calls.length).toBe(0); 37 | expect(mockResetAction.mock.calls.length).toBe(0); 38 | }); 39 | 40 | it('can parse modified query and fire an event', () => { 41 | jest.useFakeTimers(); 42 | const types = {foo: ['bar', 'baz']}; 43 | const mockAction = jest.fn(() => undefined); 44 | const mockEvent = jest.fn(() => undefined); 45 | const mockResetAction = jest.fn(() => undefined); 46 | const wrapper = shallow( 47 | 54 | ); 55 | 56 | const query = 'SELECT 1 FROM quux'; 57 | 58 | // The valueChange event is specific to this component, 59 | // but triggering it is the easiest way to simulate 60 | // typing to the underlying textarea 61 | wrapper.find(Editor).first().simulate('valueChange', query); 62 | 63 | // No events should be recorded yet 64 | expect(mockEvent.mock.calls.length).toBe(0); 65 | 66 | // The new query should not be parsed yet 67 | expect(mockAction.mock.calls.length).toBe(1); 68 | 69 | jest.runAllTimers(); 70 | 71 | // Now an event should be fire with the new query and an action created 72 | expect(mockEvent.mock.calls.length).toBe(1); 73 | expect(mockResetAction.mock.calls.length).toBe(1); 74 | expect(mockEvent.mock.calls[0][0].category).toBe('User Typing SQL Statement'); 75 | expect(mockEvent.mock.calls[0][0].action).toBe(query); 76 | expect(mockAction.mock.calls.length).toBe(2); 77 | }); 78 | -------------------------------------------------------------------------------- /src/Table.css: -------------------------------------------------------------------------------- 1 | .ReactTable.no-header .rt-thead.-headerGroups { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /src/Table.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react'; 3 | import ReactTable from 'react-table'; 4 | import 'react-table/react-table.css'; 5 | 6 | import './Table.css'; 7 | 8 | import type {StatelessFunctionalComponent} from 'react'; 9 | 10 | type Props = { 11 | tableName?: string, 12 | columns: Array, 13 | data: Array<{[string]: any}>, 14 | sortable?: boolean, 15 | }; 16 | 17 | /** A wrapper for {ReactTable} which sets some default options */ 18 | const Table: StatelessFunctionalComponent = (props) => { 19 | let columns = [ 20 | { 21 | // Define the column with a default accessor to ignore the 22 | // default behaviour of asking nested properties via dots 23 | columns: props.columns.map((c) => ({ 24 | id: c, 25 | Header: () => {c}, 26 | accessor: (d: {[string]: any}) => d[c], 27 | })), 28 | }, 29 | ]; 30 | 31 | return ( 32 | 41 | ); 42 | }; 43 | 44 | export default Table; 45 | -------------------------------------------------------------------------------- /src/Table.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Table from './Table'; 4 | 5 | const TableStories = { 6 | title: 'Table', 7 | component: Table, 8 | }; 9 | 10 | export default TableStories; 11 | 12 | export const WithData = () => ( 13 |
21 | ); 22 | WithData.storyName = 'with some data'; 23 | -------------------------------------------------------------------------------- /src/Table.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {shallow} from 'enzyme'; 3 | import ReactTable from 'react-table'; 4 | 5 | import Table from './Table'; 6 | 7 | /** @test {Table} */ 8 | it('can render a table', () => { 9 | const data = [{bar: 1, baz: 2}]; 10 | const wrapper = shallow( 11 |
12 | ); 13 | const table = wrapper.find(ReactTable).first(); 14 | expect(table).toHaveProp({ 15 | data: data, 16 | sortable: true, 17 | }); 18 | expect(table).toHaveProp('columns'); 19 | }); 20 | 21 | /** @test {Table} */ 22 | it('can disable sorting', () => { 23 | const wrapper = shallow( 24 |
25 | ); 26 | const table = wrapper.find(ReactTable).first(); 27 | expect(table).toHaveProp('sortable', false); 28 | }); 29 | -------------------------------------------------------------------------------- /src/Tutorial.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import Joyride, {STATUS} from 'react-joyride'; 3 | import React, {useState} from 'react'; 4 | import {useCookies} from 'react-cookie'; 5 | 6 | import type {StatelessFunctionalComponent} from 'react'; 7 | 8 | type CallBackProps = { 9 | status: string, 10 | }; 11 | 12 | const redoText = 'Redo tutorial'; 13 | const stepStyle = {tooltipContainer: {textAlign: 'left'}}; 14 | 15 | /** Container for all components of the tutorial */ 16 | const Tutorial: StatelessFunctionalComponent<{}> = (props) => { 17 | let initialText, shouldRun; 18 | const [cookies, setCookie] = useCookies(['tutorial']); 19 | if (cookies.tutorial === undefined) { 20 | initialText = 'Tutorial'; 21 | shouldRun = true; 22 | setCookie('tutorial', 'true', {path: '/', sameSite: 'strict'}); 23 | } else { 24 | initialText = redoText; 25 | shouldRun = false; 26 | } 27 | 28 | const [buttonText, setButtonText] = useState(initialText); 29 | const [runTutorial, setRunTutorial] = useState(shouldRun); 30 | 31 | const handleClickStart = (e: SyntheticMouseEvent) => { 32 | e.preventDefault(); 33 | setRunTutorial(true); 34 | }; 35 | 36 | const handleJoyrideCallback = (data: CallBackProps) => { 37 | const {status} = data; 38 | const finishedStatuses: string[] = [STATUS.FINISHED, STATUS.SKIPPED]; 39 | 40 | if (finishedStatuses.includes(status)) { 41 | setButtonText(redoText); 42 | setRunTutorial(false); 43 | } 44 | }; 45 | 46 | const steps = [ 47 | { 48 | content:

Welcome to Relational Playground!

, 49 | locale: {skip: Skip tutorial}, 50 | placement: 'center', 51 | target: 'body', 52 | }, 53 | { 54 | content: ( 55 |
56 |

Enter SQL queries here

57 |

58 | Note that not all SQL queries are supported (e.g. aggregation, 59 | arithmetic, and function calls). 60 |

61 |
62 | ), 63 | spotlightPadding: 4, 64 | target: '.SqlEditor', 65 | styles: stepStyle, 66 | }, 67 | { 68 | content: ( 69 |
70 |

Source relations are displayed here

, 71 |

Any of these relations can be used in your SQL queries.

72 |
73 | ), 74 | spotlightPadding: 4, 75 | target: '.sourceTableContainer', 76 | styles: stepStyle, 77 | }, 78 | { 79 | content: ( 80 |
81 |

Relational algebra expressions

82 |

83 | The expression is generated from the SQL queries entered above. The 84 | expression will automatically be updated based on the query. You can 85 | select any subexpression to view the data the relation contains 86 | below. 87 |

88 |
89 | ), 90 | spotlightPadding: 4, 91 | target: '.relExprContainer', 92 | styles: stepStyle, 93 | }, 94 | { 95 | content: ( 96 |
97 |

Relation algebra expressions data

98 |

99 | When you select an expression above, the data contained in that 100 | expression will be displayed here. You can select the top-level 101 | expression to see the final results of the query or any intermediate 102 | expression to see what relations result from each step. 103 |

104 |
105 | ), 106 | spotlightPadding: 4, 107 | target: '.dataContainer', 108 | styles: stepStyle, 109 | }, 110 | { 111 | content: ( 112 |
113 |

Tree view

114 |

115 | Toggling this checkbox will enable a tree view for relational 116 | algebra expressions. You can switch back to a linear view by 117 | unchecking the box. 118 |

119 |
120 | ), 121 | spotlightPadding: 4, 122 | target: '.relExprContainer .toggle', 123 | styles: stepStyle, 124 | }, 125 | ]; 126 | 127 | return ( 128 |
129 | 143 | 146 |
147 | ); 148 | }; 149 | 150 | export default Tutorial; 151 | -------------------------------------------------------------------------------- /src/Tutorial.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Tutorial from './Tutorial'; 3 | import Cookies from 'universal-cookie/cjs'; 4 | import {shallow} from 'enzyme'; 5 | import JoyrideTooltipContainer from 'react-joyride'; 6 | 7 | /** @test {Tutorial} */ 8 | it('correctly renders tutorial given no cookie', () => { 9 | let cookies = new Cookies(); 10 | const wrapper = shallow(); 11 | let tooltip = wrapper.find(JoyrideTooltipContainer); 12 | 13 | // expect(tooltip).toBeDefined(); 14 | expect(tooltip).toMatchSnapshot(); 15 | }); 16 | 17 | /** @test {Tutorial} */ 18 | it('cookie exists, no tutorial', () => { 19 | let cookies = new Cookies(); 20 | cookies.set('tutorial', 'true', {path: '/'}); 21 | 22 | const wrapper = shallow(); 23 | let button = wrapper.find('.button').text(); 24 | 25 | expect(button).toContain('Redo tutorial'); 26 | }); 27 | -------------------------------------------------------------------------------- /src/UnaryRelOp.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {Projection, Rename, Selection, UnaryRelOp} from './RelOp'; 4 | import Relation from './Relation'; 5 | 6 | const UnaryRelOpStories = { 7 | title: 'UnaryRelOp', 8 | component: UnaryRelOp, 9 | }; 10 | 11 | export default UnaryRelOpStories; 12 | 13 | export const SimpleProjection = () => ( 14 | }> 15 | 16 | 17 | ); 18 | SimpleProjection.storyName = 'a simple projection'; 19 | 20 | export const SimpleSelection = () => ( 21 | 100K'} />}> 22 | 23 | 24 | ); 25 | SimpleSelection.storyName = 'a simple selection'; 26 | 27 | export const SimpleRename = () => ( 28 | }> 29 | 30 | 31 | ); 32 | SimpleRename.storyName = 'a simple rename'; 33 | 34 | export const NestedOperations = () => ( 35 | }> 36 | }> 37 | 100K'} />}> 38 | 39 | 40 | 41 | 42 | ); 43 | NestedOperations.storyName = 'nested operations'; 44 | -------------------------------------------------------------------------------- /src/__snapshots__/RelExpr.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`RelExpr correctly renders a complex expression 1`] = ` 4 | 15 | 16 | 17 | 18 | 19 | ρ 20 | 21 | firstName/name 22 | 23 | 24 | ( 25 | 36 | 37 | 38 | 39 | 40 | π 41 | 42 | firstName,lastName 43 | 44 | 45 | ( 46 | 57 | 58 | 59 | 60 | 61 | σ 62 | 63 | salary > 130000 64 | 65 | 66 | ( 67 | 75 | 79 | Doctor 80 | 81 | 82 | ) 83 | 84 | 85 | 86 | 87 | ) 88 | 89 | 90 | 91 | 92 | ) 93 | 94 | 95 | 96 | 97 | `; 98 | -------------------------------------------------------------------------------- /src/__snapshots__/RelExprTree.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`correctly renders a complex expression 1`] = ` 4 |
7 |
8 |
  • 19 |
    23 |
    28 | - 29 |
    30 |
    31 | 32 | ρ 33 | 34 | firstName/name 35 | 36 | 37 |
  • 38 |
  • 49 |
    53 |
    58 | - 59 |
    60 |
    61 | 62 | π 63 | 64 | firstName,lastName 65 | 66 | 67 |
  • 68 |
  • 79 |
    83 |
    88 | - 89 |
    90 |
    91 | 92 | σ 93 | 94 | salary > 130000 95 | 96 | 97 |
  • 98 |
  • 109 | Doctor 110 |
  • 111 |
    112 |
    113 | `; 114 | -------------------------------------------------------------------------------- /src/__snapshots__/Tutorial.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`correctly renders tutorial given no cookie 1`] = ` 4 | 26 | Welcome to Relational Playground! 27 | , 28 | "locale": Object { 29 | "skip": 32 | Skip tutorial 33 | , 34 | }, 35 | "placement": "center", 36 | "target": "body", 37 | }, 38 | Object { 39 | "content":
    40 |

    41 | Enter SQL queries here 42 |

    43 |

    44 | Note that not all SQL queries are supported (e.g. aggregation, arithmetic, and function calls). 45 |

    46 |
    , 47 | "spotlightPadding": 4, 48 | "styles": Object { 49 | "tooltipContainer": Object { 50 | "textAlign": "left", 51 | }, 52 | }, 53 | "target": ".SqlEditor", 54 | }, 55 | Object { 56 | "content":
    57 |

    58 | Source relations are displayed here 59 |

    60 | , 61 |

    62 | Any of these relations can be used in your SQL queries. 63 |

    64 |
    , 65 | "spotlightPadding": 4, 66 | "styles": Object { 67 | "tooltipContainer": Object { 68 | "textAlign": "left", 69 | }, 70 | }, 71 | "target": ".sourceTableContainer", 72 | }, 73 | Object { 74 | "content":
    75 |

    76 | Relational algebra expressions 77 |

    78 |

    79 | The expression is generated from the SQL queries entered above. The expression will automatically be updated based on the query. You can select any subexpression to view the data the relation contains below. 80 |

    81 |
    , 82 | "spotlightPadding": 4, 83 | "styles": Object { 84 | "tooltipContainer": Object { 85 | "textAlign": "left", 86 | }, 87 | }, 88 | "target": ".relExprContainer", 89 | }, 90 | Object { 91 | "content":
    92 |

    93 | Relation algebra expressions data 94 |

    95 |

    96 | When you select an expression above, the data contained in that expression will be displayed here. You can select the top-level expression to see the final results of the query or any intermediate expression to see what relations result from each step. 97 |

    98 |
    , 99 | "spotlightPadding": 4, 100 | "styles": Object { 101 | "tooltipContainer": Object { 102 | "textAlign": "left", 103 | }, 104 | }, 105 | "target": ".dataContainer", 106 | }, 107 | Object { 108 | "content":
    109 |

    110 | Tree view 111 |

    112 |

    113 | Toggling this checkbox will enable a tree view for relational algebra expressions. You can switch back to a linear view by unchecking the box. 114 |

    115 |
    , 116 | "spotlightPadding": 4, 117 | "styles": Object { 118 | "tooltipContainer": Object { 119 | "textAlign": "left", 120 | }, 121 | }, 122 | "target": ".relExprContainer .toggle", 123 | }, 124 | ] 125 | } 126 | styles={ 127 | Object { 128 | "options": Object { 129 | "zIndex": 10000, 130 | }, 131 | } 132 | } 133 | /> 134 | `; 135 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, 5 | Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 6 | font-display: swap; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 13 | monospace; 14 | font-display: swap; 15 | } 16 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import './wydr'; 3 | 4 | import {BrowserRouter} from 'react-router-dom'; 5 | import {Provider} from 'react-redux'; 6 | import React from 'react'; 7 | import ReactDOM from 'react-dom'; 8 | import * as Sentry from '@sentry/browser'; 9 | import './index.css'; 10 | import store from './store'; 11 | import App from './App'; 12 | 13 | let sentryConfig = { 14 | dsn: 'https://496d372d00a24c57af7967ac2ff5dacd@sentry.io/2445886', 15 | environment: process.env.NODE_ENV, 16 | release: (null: ?string), 17 | }; 18 | 19 | if (process.env.REACT_APP_GIT_SHA) { 20 | sentryConfig.release = 21 | 'relational-playground@' + process.env.REACT_APP_GIT_SHA; 22 | } 23 | Sentry.init(sentryConfig); 24 | 25 | ReactDOM.render( 26 | 27 | 28 |
    29 | 30 |
    31 |
    32 |
    , 33 | ((document.getElementById('root'): any): HTMLElement) 34 | ); 35 | -------------------------------------------------------------------------------- /src/modules/types.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | export type Expression = {[key: string]: any}; 4 | 5 | export type JoinCondition = {[key: string]: any}; 6 | 7 | export type SelectionCondition = {[key: string]: any}; 8 | 9 | export type Graph = { 10 | [key: string]: { 11 | edges: {[key: string]: Array}, 12 | selections: Array, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /src/resources/Department.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Department", 3 | "columns": ["id", "name"], 4 | "data": [ 5 | { 6 | "id": 1, 7 | "name": "Cardiology" 8 | }, 9 | { 10 | "id": 2, 11 | "name": "Neurology" 12 | }, 13 | { 14 | "id": 3, 15 | "name": "Orthopedics" 16 | }, 17 | { 18 | "id": 4, 19 | "name": "Dermatology" 20 | }, 21 | { 22 | "id": 5, 23 | "name": "Gastroenterology" 24 | }, 25 | { 26 | "id": 6, 27 | "name": "Urology" 28 | }, 29 | { 30 | "id": 7, 31 | "name": "Nephrology" 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | import 'jest-enzyme'; 3 | import {configure} from 'enzyme'; 4 | import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; 5 | 6 | configure({adapter: new Adapter()}); 7 | 8 | if (window.document) { 9 | window.document.createRange = () => ({ 10 | setStart: () => {}, 11 | setEnd: () => {}, 12 | commonAncestorContainer: { 13 | nodeName: 'BODY', 14 | ownerDocument: document, 15 | }, 16 | getBoundingClientRect: () => ({top: 0, right: 0, bottom: 0, left: 0}), 17 | getClientRects: () => [], 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import {configureStore} from '@reduxjs/toolkit'; 3 | import {connectRouter, routerMiddleware} from 'connected-react-router'; 4 | import {createBrowserHistory} from 'history'; 5 | 6 | import data from './modules/data'; 7 | import relexp from './modules/relexp'; 8 | 9 | import type {BrowserHistory} from 'history'; 10 | import type {Action, Store} from '@reduxjs/toolkit'; 11 | 12 | export const history: BrowserHistory = createBrowserHistory(); 13 | 14 | const store: Store<{}, Action<{}>> = configureStore({ 15 | reducer: { 16 | router: connectRouter(history), 17 | 18 | data, 19 | relexp, 20 | }, 21 | middleware: [routerMiddleware(history)], 22 | }); 23 | 24 | export default store; 25 | -------------------------------------------------------------------------------- /src/store.test.js: -------------------------------------------------------------------------------- 1 | const OLD_ENV = process.env; 2 | 3 | beforeEach(() => { 4 | jest.resetModules(); // this is important - it clears the cache 5 | process.env = {...OLD_ENV}; 6 | delete process.env.NODE_ENV; 7 | }); 8 | 9 | it('has a valid initial state', () => { 10 | const store = require('./store').default; 11 | const initialState = store.getState(); 12 | expect(initialState).toHaveProperty('data'); 13 | expect(initialState).toHaveProperty('relexp'); 14 | expect(initialState).toHaveProperty('router'); 15 | }); 16 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | /** 4 | * @param expr - an object representing an expression 5 | * @param top - whether this is a top-level expression - to avoid unneccessary () 6 | * @return a string representing a query condition 7 | */ 8 | export function exprToString( 9 | expr: {[string]: any}, 10 | top: boolean = true 11 | ): string { 12 | const strExpr = exprToStringInner(expr, top); 13 | 14 | // Removes unneccessary () from inner expressions within and(s) and or(s) 15 | if (strExpr[0] === '(' && strExpr[strExpr.length - 1] === ')') { 16 | return strExpr.substring(1, strExpr.length - 1); 17 | } else { 18 | return strExpr; 19 | } 20 | } 21 | 22 | /** 23 | * @param expr - an object representing an expression 24 | * @param top - whether this is a top-level expression - to avoid unneccessary () 25 | * @return a string representing a query condition 26 | */ 27 | function exprToStringInner(expr: {[string]: any}, top: boolean = true): string { 28 | // We have reached a simple value 29 | if (typeof expr !== 'object') { 30 | return expr.toString(); 31 | } 32 | 33 | const opMap = { 34 | $gte: '>=', 35 | $gt: '>', 36 | $lt: '<', 37 | $lte: '<=', 38 | $ne: '!=', 39 | $eq: '=', 40 | }; 41 | 42 | const type = Object.keys(expr)[0]; 43 | let exprString; 44 | switch (type) { 45 | case 'cmp': 46 | exprString = expr.cmp.lhs + ' ' + opMap[expr.cmp.op] + ' ' + expr.cmp.rhs; 47 | break; 48 | 49 | case 'and': 50 | exprString = 51 | '(' + 52 | expr.and.clauses.map((c) => exprToString(c, false)).join(' ∧ ') + 53 | ')'; 54 | break; 55 | 56 | case 'or': 57 | exprString = 58 | '(' + 59 | expr.or.clauses.map((c) => exprToString(c, false)).join(' ∨ ') + 60 | ')'; 61 | break; 62 | 63 | case 'not': 64 | exprString = '¬(' + exprToString(expr.not.clause, false) + ')'; 65 | break; 66 | 67 | default: 68 | throw new Error('Unhandled expression object'); 69 | } 70 | 71 | // Parenthesize if we're not at the top level 72 | if (top) { 73 | return exprString; 74 | } else { 75 | return '(' + exprString + ')'; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/util.test.js: -------------------------------------------------------------------------------- 1 | import {exprToString} from './util'; 2 | 3 | /** @test {and} */ 4 | it('renders an and', () => { 5 | const container = exprToString( 6 | { 7 | and: { 8 | clauses: [ 9 | {cmp: {lhs: 'bar', op: '$gt', rhs: '1'}}, 10 | {cmp: {lhs: 'baz', op: '$lt', rhs: '3'}}, 11 | ], 12 | }, 13 | }, 14 | true 15 | ); 16 | expect(container).toContain('bar > 1 ∧ baz < 3'); 17 | }); 18 | 19 | /** @test {or} */ 20 | it('renders an or', () => { 21 | const container = exprToString( 22 | { 23 | or: { 24 | clauses: [ 25 | {cmp: {lhs: 'bar', op: '$gte', rhs: '1'}}, 26 | {cmp: {lhs: 'baz', op: '$lte', rhs: '3'}}, 27 | ], 28 | }, 29 | }, 30 | true 31 | ); 32 | expect(container).toContain('bar >= 1 ∨ baz <= 3'); 33 | }); 34 | 35 | /** @test {or} */ 36 | it('renders a not', () => { 37 | const container = exprToString( 38 | { 39 | not: { 40 | clause: {cmp: {lhs: 'bar', op: '$eq', rhs: '1'}}, 41 | }, 42 | }, 43 | true 44 | ); 45 | expect(container).toContain('¬(bar = 1)'); 46 | }); 47 | -------------------------------------------------------------------------------- /src/wydr.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | if (process.env.NODE_ENV === 'development') { 4 | const whyDidYouRender = require('@welldone-software/why-did-you-render'); 5 | whyDidYouRender(React, { 6 | trackAllPureComponents: true, 7 | }); 8 | } 9 | --------------------------------------------------------------------------------