[
  {
    "path": ".eslintrc",
    "content": "{\n  \"env\": {\n    \"browser\": true,\n    \"es6\": true,\n    \"node\": true\n  },\n  \"settings\": {\n    \"pragma\": \"React\",\n    \"version\": \"detect\"\n  },\n  \"extends\": [\n    \"eslint:recommended\",\n    \"plugin:react/recommended\",\n    \"plugin:@typescript-eslint/eslint-recommended\",\n    \"plugin:@typescript-eslint/recommended\",\n    \"airbnb-typescript\"\n  ],\n  \"globals\": {\n    \"Atomics\": \"readonly\",\n    \"SharedArrayBuffer\": \"readonly\"\n  },\n  \"parser\": \"@typescript-eslint/parser\",\n  \"parserOptions\": {\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    },\n    \"ecmaVersion\": 2018,\n    \"sourceType\": \"module\",\n    \"project\": \"./tsconfig.eslint.json\"\n  },\n  \"plugins\": [\"react\", \"@typescript-eslint\"],\n  \"rules\": {\n    \"@typescript-eslint/explicit-function-return-type\": \"off\",\n    \"@typescript-eslint/no-use-before-define\": \"off\",\n    \"@typescript-eslint/no-var-requires\": \"off\",\n    \"@typescript-eslint/interface-name-prefix\": \"off\",\n    \"@typescript-eslint/no-this-alias\": \"off\",\n    \"@typescript-eslint/no-explicit-any\": \"off\",\n    \"react/prop-types\": \"off\",\n    \"react/jsx-props-no-spreading\": \"off\",\n    \"react/destructuring-assignment\": \"off\",\n    \"react/display-name\": \"off\",\n    \"import/no-extraneous-dependencies\": \"off\",\n    \"import/no-unresolved\": \"off\",\n    \"no-async-promise-executor\": \"off\",\n    \"no-console\": \"off\",\n    \"no-param-reassign\": \"off\",\n    \"no-underscore-dangle\": \"off\",\n    \"global-require\": \"off\",\n    \"arrow-body-style\": \"off\",\n    \"implicit-arrow-linebreak\": \"off\",\n    \"object-curly-newline\": \"off\",\n    \"lines-between-class-members\": \"off\",\n    \"function-paren-newline\": \"off\",\n    \"linebreak-style\": \"off\",\n    \"operator-linebreak\": \"off\",\n    \"jsx-quotes\": \"off\",\n    \"no-prototype-builtins\": \"off\",\n    \"consistent-return\": \"off\",\n    \"max-len\": [\"warn\", { \"code\": 120 }]\n  }\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: If you found a bug in Direflow, please file a bug report\ntitle: ''\nlabels: 'Bug'\nassignees: 'Silind'\n\n---\n\n**Describe the bug**  \nA clear and concise description of what the bug is.\n\n**To reproduce**  \nSteps to reproduce the behavior:\n1. Install '...'\n2. Open '....'\n3. Build '....'\n4. See error\n\n**Expected behavior**  \nA clear and concise description of what you expected to happen.\n\n**Package Manager:**  \nTo install Direflow, I used... (npm / yarn / something else)\n\n**Screenshots**  \nIf applicable, add screenshots to help explain your problem.\n\n**Additional context**  \nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for Direflow\ntitle: ''\nlabels: 'Enhancement'\nassignees: 'Silind'\n\n---\n\n**Is your feature request related to a problem? Please describe.**  \nA clear and concise description of what the problem is.\n\n**Describe the solution you'd like**  \nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**  \nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**  \nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "**What does this pull request introduce? Please describe**  \nA clear and concise description of what this pull requests includes.\nPlease add a reference to the related issue, if relevant.\n\n**How did you verify that your changes work as expected? Please describe**  \nPlease describe your methods of testing your changes.\n\n**Example**  \nPlease describe how we can try out your changes  \n1. Create a new '...'\n2. Build with '...'\n3. See '...'\n\n**Screenshots**  \nIf applicable, add screenshots to demonstrate your changes.\n\n**Version**  \nWhich version is your changes included in?  \n  \nDid you remember to update the version of Direflow as explained here:  \nhttps://github.com/Silind-Software/direflow/blob/master/CONTRIBUTING.md#version"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: build\n\non:\n  push:\n    branches:\n    - master\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v1\n    - uses: actions/setup-node@v1\n      with:\n        node-version: 12.x\n        registry-url: 'https://registry.npmjs.org'\n    \n    - name: Prepare\n      run: |\n        sudo apt-get install lsof\n        npm install codecov -g\n\n    - name: Install\n      run: |\n        npm run clean:all\n        npm run install:all\n\n    - name: Codecov\n      run: codecov -t ${{ secrets.CODECOV_TOKEN }}\n\n    - name: Build\n      run: |\n        npm run build:all\n\n    - name: Test\n      run: |\n        npm run test\n\n    - name: Integration Test\n      run: |\n        npm run cypress:test\n\n    - name: Create version patch\n      run: npm run update-version patch\n\n    - name: Publish direflow-cli to NPM\n      run: npm publish\n      env:\n        NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}\n  \n    - name: Publish direflow-component to NPM\n      run: |\n        cd packages/direflow-component\n        npm publish\n      env:\n        NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}\n  \n    - name: Publish direflow-scripts to NPM\n      run: |\n        cd packages/direflow-scripts\n        npm publish\n      env:\n        NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: test\n\non: [pull_request]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v1\n    - uses: actions/setup-node@v1\n      with:\n        node-version: 12.x\n        browser: chrome\n    \n    - name: Prepare\n      run: |\n        sudo apt-get install lsof\n\n    - name: Install\n      run: |\n        npm run clean:all\n        npm run install:all\n        \n    - name: Build\n      run: |\n        npm run build:all\n\n    - name: Test\n      run: |\n        npm run test\n\n    - name: Integration Test\n      run: |\n        npm run cypress:test\n"
  },
  {
    "path": ".gitignore",
    "content": "# Project setup specifics\n\ndist\nbuild\nyarn.lock\nconfig-overrides.js\nconfig-overrides.d.ts\ntsconfig.lib.json\n\n# Cypress\ncypress/fixtures\ncypress/plugins\ncypress/screenshots\n\n# User-specific stuff\n.idea/**/workspace.xml\n.idea/**/tasks.xml\n.idea/**/usage.statistics.xml\n.idea/**/dictionaries\n.idea/**/shelf\n\n# Generated files\n.idea/**/contentModel.xml\n\n# Sensitive or high-churn files\n.idea/**/dataSources/\n.idea/**/dataSources.ids\n.idea/**/dataSources.local.xml\n.idea/**/sqlDataSources.xml\n.idea/**/dynamic.xml\n.idea/**/uiDesigner.xml\n.idea/**/dbnavigator.xml\n\n# Gradle\n.idea/**/gradle.xml\n.idea/**/libraries\n\n# CMake\ncmake-build-*/\n\n# Mongo Explorer plugin\n.idea/**/mongoSettings.xml\n\n# File-based project format\n*.iws\n\n# IntelliJ\nout/\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Cursive Clojure plugin\n.idea/replstate.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n\n# Editor-based Rest Client\n.idea/httpRequests\n\n# Android studio 3.1+ serialized cache file\n.idea/caches/build_file_checksums.ser\n\n.idea/\n\n# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023\n\n*.iml\nmodules.xml\n.idea/misc.xml\n*.ipr\n\n# Sonarlint plugin\n.idea/sonarlint\n\n### Node ###\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n### OSX ###\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n### VisualStudioCode ###\n.vscode\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n\n### VisualStudioCode Patch ###\n# Ignore all local history of files\n.history\n\n### WebStorm+all ###\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff\n\n# Generated files\n\n# Sensitive or high-churn files\n\n# Gradle\n\n# Gradle and Maven with auto-import\n# When using Gradle or Maven with auto-import, you should exclude module files,\n# since they will be recreated, and may cause churn.  Uncomment if using\n# auto-import.\n# .idea/modules.xml\n# .idea/*.iml\n# .idea/modules\n# *.iml\n# *.ipr\n\n# CMake\n\n# Mongo Explorer plugin\n\n# File-based project format\n\n# IntelliJ\n\n# mpeltonen/sbt-idea plugin\n\n# JIRA plugin\n\n# Cursive Clojure plugin\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\n\n# Editor-based Rest Client\n\n# Android studio 3.1+ serialized cache file\n\n### WebStorm+all Patch ###\n# Ignores the whole .idea folder and all .iml files\n# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360\n\n\n# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023\n\n\n# Sonarlint plugin\n\n### Windows ###\n# Windows thumbnail cache files\nThumbs.db\nThumbs.db:encryptable\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\n[Dd]esktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n# End of https://www.gitignore.io/api/osx,node,windows,webstorm+all,intellij+all,visualstudiocode"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to make participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\nadvances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing or otherwise, unacceptable behavior may be\nreported by contacting the project team at contact@silind.com. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality concerning the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at [https://contributor-covenant.org/version/1/4][version]\n\n[homepage]: https://contributor-covenant.org\n[version]: https://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\n## Issues\nIn the case of a bug report, a suggestions, or if you just need help, please feel very free to open an issue.\n\nFor general issues, please use the following labels:\n- Something is not working as intended: `Bug`\n- Need help with something: `Help wanted`\n- Have a question: `Question`\n- Have a suggestion or want to request a feature: `Enhancement`\n- Does the question regard direflow-component: `Direflow Component`\n- Does the question regard direflow-cli: `Direflow CLI`\n\n## Pull request\nPull requests are really welcome!\n\n### Version\nWhen doing a pull request, please make sure to include an new version in your PR.\nThere are multiple packages that needs to be in sync, so in order to update the version of Direflow, please use the script:\n```console\nnpm run update-version <new-version>\n```\n\nIn order to create a version patch, use the command:\n```console\nnpm run update-version patch\n```\n\n## Developing on Direflow\nStart by making a fork of the direflow repository, and clone it down.\n\n### Install\nNow cd into the project folder and run the command:\n```console\nnpm run install:all\n```\nThis command will install the project, the packages and all peer dependencies.\n\n### Link\nIn order to test your changes locally, you want to link the project using the command:\n```console\nnpm link\n```\n\nNow, in order to make sure all version-references are pointed to your local version of the project, use the command:\n```console\nnpm run update-version link\n```\n\n_NB: To do all of this in one command, you can use:_\n```console\nnpm run setup-local\n```\n\n### Build\nAfter applying your changes, build the project using the command:\n```console\nnpm run build:full\n```\n\nNow, test that the project is working by using the command:\n```console\ndireflow -v\n```\n\nThis should give you the latest version with a '-link' appended:\n```console\n  Current version of direflow-cli:\n  3.4.3-link\n```\nIn this way you know that the command `direflow` is using your local setup.\n\nNow, test your new functionality.\n> Note: After you have build the project using build:full, you may want to run install:all again before continuing to develop.\n\n### Commit the changes\nBefore committing your new changes, remember to change the version using the command:\n```console\nnpm run update-version <new-version>\n```\n\n### Create the PR\nCreate a branch for your changes called '_feature/name-of-the-changes_'.\nMake a PR into the **development** branch on the direflow repository.\n\n## Updating the docs\nIf you introduced user-facing changes, please update the [direflow-docs](https://github.com/Silind-Software/direflow-docs) accordingly.\n\n## Additional resources\nCheck out the [Direflow Wiki](https://github.com/Silind-Software/direflow/wiki). Here you can find guides and know-how that will help you developing on Direflow.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2020 Silind Ltd\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<span align=\"center\">\n\n  [![](https://silind-s3.s3.eu-west-2.amazonaws.com/direflow/gh-banner.png)](https://direflow.io/)\n\n</span>\n\n<span align=\"right\">\n\n  [![NPM Version](https://img.shields.io/npm/v/direflow-cli)](https://www.npmjs.com/package/direflow-cli)\n  [![Github License](https://img.shields.io/github/license/Silind-Software/direflow)](https://github.com/Silind-Software/direflow/blob/master/LICENSE)\n  ![Build Status](https://github.com/Silind-Software/direflow/workflows/build/badge.svg)\n  ![Code Coverage](https://img.shields.io/codecov/c/github/Silind-Software/direflow)\n\n</span>\n\n# [direflow.io](https://direflow.io/)\n\n#### Set up a React App and build it as a Web Component\n> This setup is based on [*react-scripts*](https://www.npmjs.com/package/react-scripts) from [*create-react-app*](https://create-react-app.dev/docs/getting-started)  \n> A walkthrough of the principles used in this setup, can be read [in this article](https://itnext.io/react-and-web-components-3e0fca98a593)\n\n## Get started\n\nStart by downloading the cli:\n```console\nnpm i -g direflow-cli\n```\n\n### Create a new Direflow Component\n```console\ndireflow create\n```\n\nThis will bootstrap a new Direflow Component for you.\nNow use the following commands:\n```console\ncd <project-folder>\nnpm install\nnpm start\n```\n\nYour Direflow Component will start running on `localhost:3000` and your browser opens a new window  \n\n<p align=\"center\">\n<img src=\"https://silind-s3.s3.eu-west-2.amazonaws.com/direflow/direflow-component-new-base.png\" />\n</p>\n\n#### See full documentation on [direflow.io](https://direflow.io)\n"
  },
  {
    "path": "bin/direflow",
    "content": "#!/usr/bin/env node\n\nrequire = require('esm')(module);\nconst cli = require('../dist/cli');\ncli.default();\n"
  },
  {
    "path": "cli/checkForUpdate.ts",
    "content": "import chalk from 'chalk';\nimport { execSync } from 'child_process';\nimport { updateAvailable } from './messages';\n\nconst checkForUpdates = () => {\n  const rootPackage = require('../package.json');\n  const buffer = execSync('npm view direflow-cli version');\n  const currentVersion = buffer.toString('utf8');\n\n  if (rootPackage.version.trim() !== currentVersion.trim()) {\n    return chalk.white(updateAvailable(rootPackage.version.trim(), currentVersion.trim()));\n  }\n\n  return '';\n};\n\nexport default checkForUpdates;\n"
  },
  {
    "path": "cli/cli.ts",
    "content": "import { program, Command } from 'commander';\nimport chalk from 'chalk';\nimport headline from './headline';\nimport { createDireflowSetup } from './create';\nimport checkForUpdates from './checkForUpdate';\nimport { showVersion } from './messages';\n\ntype TOptions =\n  | 'small'\n  | 'js'\n  | 'ts'\n  | 'tslint'\n  | 'eslint'\n  | 'npm';\n\ntype TParsed = Command & { [key in TOptions]?: true } & { desc: string };\n\nexport default function cli() {\n  program\n    .command('create [project-name]')\n    .alias('c')\n    .description('Create a new Direflow Setup')\n    .option('-d, --desc <description>', 'Choose description for your project')\n    .option('--js', 'Choose JavaScript Direflow template')\n    .option('--ts', 'Choose TypeScript Direflow template')\n    .option('--tslint', 'Use TSLint for TypeScript template')\n    .option('--eslint', 'Use ESLint for TypeScript template')\n    .option('--npm', 'Make the project an NPM module')\n    .action(handleAction);\n\n  program\n    .description(chalk.magenta(headline))\n    .version(showVersion())\n    .helpOption('-h, --help', 'Show how to use direflow-cli')\n    .option('-v, --version', 'Show the current version');\n\n  const [, , simpleArg] = process.argv;\n\n  if (!simpleArg) {\n    return program.help();\n  }\n\n  if (['-v', '--version'].includes(simpleArg)) {\n    console.log(checkForUpdates());\n  }\n\n  program.parse(process.argv);\n}\n\nasync function handleAction(name: string | undefined, parsed: TParsed) {\n  const { js, ts, tslint, eslint, npm, desc: description } = parsed;\n\n  let language: 'js' | 'ts' | undefined;\n  let linter: 'eslint' | 'tslint' | undefined;\n\n  if (js) {\n    language = 'js';\n  } else if (ts) {\n    language = 'ts';\n  }\n\n  if (eslint) {\n    linter = 'eslint';\n  } else if (tslint) {\n    linter = 'tslint';\n  }\n\n  await createDireflowSetup({\n    name,\n    linter,\n    language,\n    description,\n    npmModule: !!npm,\n  }).catch((err) => {\n    console.log('');\n    console.log(chalk.red('Unfortunately, something went wrong creating your Direflow Component'));\n    console.log(err);\n    console.log('');\n  });\n}\n"
  },
  {
    "path": "cli/create.ts",
    "content": "import fs from 'fs';\nimport chalk from 'chalk';\nimport { chooseName, chooseDescription, chooseLanguage, chooseLinter, isNpmModule } from './questions';\nimport copyTemplate from './helpers/copyTemplate';\nimport { getNameFormats, createDefaultName } from './helpers/nameFormat';\nimport isDireflowSetup from './helpers/detectDireflowSetup';\nimport { writeProjectNames } from './helpers/writeNames';\nimport { moreInfoMessage, componentFinishedMessage } from './messages';\n\ninterface ISetupPresets {\n  name?: string;\n  description?: string;\n  language?: 'js' | 'ts';\n  linter?: 'eslint' | 'tslint';\n  npmModule?: boolean;\n}\n\nexport async function createDireflowSetup(preset: ISetupPresets = {}): Promise<void> {\n  if (isDireflowSetup()) {\n    console.log(\n      chalk.red('You are trying to create a new Direflow Setup inside an existing Direflow Setup.'),\n    );\n    return;\n  }\n\n  if (!preset.name) {\n    const { name } = await chooseName();\n    preset.name = name;\n  }\n\n  if (!preset.description) {\n    const { description } = await chooseDescription();\n    preset.description = description;\n  }\n\n  if (!preset.language) {\n    const { language } = await chooseLanguage();\n    preset.language = language;\n  }\n\n  if (!preset.linter) {\n    const { linter } = await chooseLinter(preset.language);\n    preset.linter = linter;\n  }\n\n  if (!preset.npmModule) {\n    const { npmModule } = await isNpmModule();\n    preset.npmModule = npmModule;\n  }\n\n  const { name, description, language, linter, npmModule } = preset;\n\n  const componentName = createDefaultName(name);\n  const projectName = componentName;\n\n  if (fs.existsSync(projectName)) {\n    console.log(chalk.red(`The directory '${projectName}' already exists at the current location`));\n    return;\n  }\n\n  const projectDirectoryPath = await copyTemplate({\n    language,\n    projectName,\n  });\n\n  await writeProjectNames({\n    linter,\n    projectDirectoryPath,\n    description,\n    npmModule,\n    names: getNameFormats(componentName),\n    type: 'direflow-component',\n  });\n\n  console.log(chalk.greenBright(componentFinishedMessage(projectName)));\n  console.log(chalk.blueBright(moreInfoMessage));\n}\n\nexport default createDireflowSetup;\n"
  },
  {
    "path": "cli/headline.ts",
    "content": "const headline = `\n  ██████╗ ██╗██████╗ ███████╗███████╗██╗      ██████╗ ██╗    ██╗\n  ██╔══██╗██║██╔══██╗██╔════╝██╔════╝██║     ██╔═══██╗██║    ██║\n  ██║  ██║██║██████╔╝█████╗  █████╗  ██║     ██║   ██║██║ █╗ ██║\n  ██║  ██║██║██╔══██╗██╔══╝  ██╔══╝  ██║     ██║   ██║██║███╗██║\n  ██████╔╝██║██║  ██║███████╗██║     ███████╗╚██████╔╝╚███╔███╔╝\n  ╚═════╝ ╚═╝╚═╝  ╚═╝╚══════╝╚═╝     ╚══════╝ ╚═════╝  ╚══╝╚══╝`;\n\nexport default headline;\n"
  },
  {
    "path": "cli/helpers/copyTemplate.ts",
    "content": "import { resolve } from 'path';\nimport fs from 'fs';\nimport ncp from 'ncp';\nimport { ITemplateOption } from '../types/TemplateOption';\n\nconst copyTemplate = async (options: ITemplateOption): Promise<string> => {\n  const currentDirectory = process.cwd();\n  const templateDirectory = resolve(__dirname, `../../templates/${options.language}`);\n\n  const projectDirectory: string = await new Promise((projectResolve, reject) => {\n    const projectDir = `${currentDirectory}/${options.projectName}`;\n    fs.mkdir(projectDir, (err: any) => {\n      if (err) {\n        console.log(err);\n        reject(new Error(`Could not create directory: ${projectDir}`));\n      }\n\n      projectResolve(projectDir);\n    });\n  });\n\n  await new Promise((ncpResolve, reject) => {\n    ncp.ncp(templateDirectory, projectDirectory, (err) => {\n      if (err) {\n        console.log(err);\n        reject(new Error('Could not copy template files'));\n      }\n\n      ncpResolve(true);\n    });\n  });\n\n  await new Promise((renameResolve, reject) => {\n    fs.rename(\n      `${projectDirectory}/src/direflow-components/direflow-component`,\n      `${projectDirectory}/src/direflow-components/${options.projectName}`,\n      (err) => {\n        if (err) {\n          console.log(err);\n          reject(new Error('Could not rename component folder'));\n        }\n\n        renameResolve(true);\n      },\n    );\n  });\n\n  return projectDirectory;\n};\n\nexport default copyTemplate;\n"
  },
  {
    "path": "cli/helpers/detectDireflowSetup.ts",
    "content": "import fs from 'fs';\n\nconst isDireflowSetup = (currentDirectory = process.cwd()): boolean => {\n  return fs.existsSync(`${currentDirectory}/direflow-webpack.js`);\n};\n\nexport default isDireflowSetup;\n"
  },
  {
    "path": "cli/helpers/nameFormat.ts",
    "content": "import to from 'to-case';\nimport { INames } from '../types/Names';\n\nexport const getNameFormats = (name: string): INames => {\n  return {\n    title: to.title(name),\n    pascal: to.pascal(name),\n    snake: to.slug(name),\n  };\n};\n\nexport const createDefaultName = (name: string) => {\n  const snakeName = to.slug(name);\n\n  if (!snakeName.includes('-')) {\n    return `${snakeName}-component`;\n  }\n\n  return snakeName;\n};\n"
  },
  {
    "path": "cli/helpers/writeNames.ts",
    "content": "import fs from 'fs';\nimport handelbars from 'handlebars';\nimport path from 'path';\nimport { INames } from '../types/Names';\n\nconst packageJson = require('../../package.json');\n\nconst { version } = packageJson;\n\ninterface IWriteNameOptions {\n  projectDirectoryPath: string;\n  linter: 'eslint' | 'tslint';\n  packageVersion?: string;\n  description: string;\n  npmModule: boolean;\n  names: INames;\n  type: string;\n}\n\ntype TWriteNameExtendable = Required<Pick<IWriteNameOptions,\n| 'names'\n| 'type'\n| 'packageVersion'\n| 'npmModule'\n>>;\n\ninterface IHandelbarData extends TWriteNameExtendable {\n  defaultDescription: string;\n  eslint: boolean;\n  tslint: boolean;\n}\n\nexport async function writeProjectNames({\n  type, names, description, linter, npmModule,\n  projectDirectoryPath,\n  packageVersion = version,\n}: IWriteNameOptions): Promise<void> {\n  const projectDirectory = fs.readdirSync(projectDirectoryPath);\n  const defaultDescription = description || 'This project is created using Direflow';\n\n  const writeNames = projectDirectory.map(async (dirElement: string) => {\n    const filePath = path.join(projectDirectoryPath, dirElement);\n\n    if (fs.statSync(filePath).isDirectory()) {\n      return writeProjectNames({\n        names, description, type, linter, npmModule, projectDirectoryPath: filePath,\n      });\n    }\n\n    if (linter !== 'tslint') {\n      if (filePath.endsWith('tslint.json')) {\n        return fs.unlinkSync(filePath);\n      }\n    }\n\n    if (linter !== 'eslint') {\n      if (filePath.endsWith('.eslintrc')) {\n        return fs.unlinkSync(filePath);\n      }\n    }\n\n    return changeNameInfile(filePath, {\n      names,\n      defaultDescription,\n      type,\n      packageVersion,\n      npmModule,\n      eslint: linter === 'eslint',\n      tslint: linter === 'tslint',\n    });\n  });\n\n  await Promise.all(writeNames).catch(() => console.log('Failed to write files'));\n}\n\nasync function changeNameInfile(filePath: string, data: IHandelbarData): Promise<void> {\n  const changedFile = await new Promise((resolve, reject) => {\n    fs.readFile(filePath, 'utf-8', (err, content) => {\n      if (err) {\n        reject(false);\n      }\n\n      const template = handelbars.compile(content);\n      const changed = template(data);\n\n      resolve(changed);\n    });\n  });\n\n  await new Promise((resolve, reject) => {\n    if ( typeof changedFile == 'string' ) {\n      fs.writeFile(filePath, changedFile, 'utf-8', (err) => {\n        if (err) {\n          reject();\n        }\n\n        resolve(true);\n      });\n    }\n  });\n}\n\nexport default writeProjectNames;\n"
  },
  {
    "path": "cli/messages.ts",
    "content": "import chalk from 'chalk';\nimport boxen from 'boxen';\n\nexport const componentFinishedMessage = (componentName: string) => `\n\n  Your Direflow Component is ready!\n  To get started:\n\n    cd ${componentName}\n    npm install\n    npm start\n\n  The Direflow Component will be running at: ${chalk.magenta('localhost:3000')}\n`;\n\nexport const moreInfoMessage = `\n  To learn more about Direflow, visit:\n  https://direflow.io\n`;\n\nexport const updateAvailable = (currentVersion: string, newVersion: string) => {\n  const content = `There is a new version of direflow-cli available: ${chalk.greenBright(newVersion)}.\nYou are currently running direflow-cli version: ${chalk.blueBright(currentVersion)}.\nRun '${chalk.magenta('npm i -g direflow-cli')}' to get the latest version.`;\n\n  return boxen(content, { padding: 1, align: 'center', margin: 1 });\n};\n\nexport const showVersion = () => {\n  const packageJson = require('../package.json');\n  return `Current version of direflow-cli:\n  ${packageJson.version}\n  `;\n};\n"
  },
  {
    "path": "cli/questions.ts",
    "content": "import inquirer from 'inquirer';\nimport { IQuestionOption } from './types/QuestionOption';\nimport { ILanguageOption } from './types/LangageOption';\n\nexport async function chooseLanguage(): Promise<ILanguageOption> {\n  console.log('');\n  return inquirer.prompt([\n    {\n      type: 'list',\n      name: 'language',\n      message: 'Which language do you want to use?',\n      choices: [\n        {\n          value: 'js',\n          name: 'JavaScript',\n        },\n        {\n          value: 'ts',\n          name: 'TypeScript',\n        },\n      ],\n    },\n  ]);\n}\n\nexport async function chooseLinter(language: 'js' | 'ts'): Promise<{ linter: 'eslint' | 'tslint' }> {\n  if (language === 'js') {\n    return {\n      linter: 'eslint',\n    };\n  }\n\n  console.log('');\n  return inquirer.prompt([\n    {\n      type: 'list',\n      name: 'linter',\n      message: 'Which linter do you want to use?',\n      choices: [\n        {\n          value: 'eslint',\n          name: 'ESLint',\n        },\n        {\n          value: 'tslint',\n          name: 'TSLint',\n        },\n      ],\n    },\n  ]);\n}\n\nexport async function isNpmModule(): Promise<{ npmModule: boolean }> {\n  console.log('');\n  return inquirer.prompt([\n    {\n      type: 'list',\n      name: 'npmModule',\n      message: 'Do you want this to be an NPM module?',\n      choices: [\n        {\n          value: true,\n          name: 'Yes',\n        },\n        {\n          value: false,\n          name: 'No',\n        },\n      ],\n    },\n  ]);\n}\n\nexport async function chooseName(): Promise<IQuestionOption> {\n  console.log('');\n  return inquirer.prompt([\n    {\n      type: 'input',\n      name: 'name',\n      message: 'Choose a name for your Direflow Setup:',\n      validate: (value: string) => {\n        const pass = /^[a-zA-Z0-9-_]+$/.test(value);\n\n        if (pass) {\n          return true;\n        }\n\n        return 'Please enter a valid name';\n      },\n    },\n  ]);\n}\n\nexport async function chooseDescription(): Promise<IQuestionOption> {\n  console.log('');\n  return inquirer.prompt([\n    {\n      type: 'input',\n      name: 'description',\n      message: 'Give your Direflow Setup a description (optional)',\n    },\n  ]);\n}\n"
  },
  {
    "path": "cli/types/Command.ts",
    "content": "export interface ICommand {\n  [arg: string]: string;\n}\n"
  },
  {
    "path": "cli/types/LangageOption.ts",
    "content": "export interface ILanguageOption {\n  language: 'js' | 'ts';\n}\n"
  },
  {
    "path": "cli/types/Names.ts",
    "content": "export interface INames {\n  title: string;\n  pascal: string;\n  snake: string;\n}\n"
  },
  {
    "path": "cli/types/QuestionOption.ts",
    "content": "export interface IQuestionOption {\n  name: string;\n  description: string;\n}\n"
  },
  {
    "path": "cli/types/TemplateOption.ts",
    "content": "export interface ITemplateOption {\n  projectName: string;\n  language: 'ts' | 'js';\n}\n"
  },
  {
    "path": "cypress/integration/basic_tests.ts",
    "content": "describe('Running basic component', () => {\n  before(() => {\n    cy.visit('/');\n  });\n\n  it('should contain a custom element', () => {\n    cy.get('basic-test').should('exist');\n  });\n\n  it('should have default componentTitle', () => {\n    cy.shadowGet('basic-test')\n      .shadowFind('.app')\n      .shadowFind('.header-title')\n      .shadowContains('Test Setup');\n  });\n\n  it('should have default sampleList items', () => {\n    cy.shadowGet('basic-test')\n      .shadowFind('.app')\n      .shadowFind('div')\n      .shadowEq(1)\n      .shadowFind('.sample-text')\n      .shadowEq(0)\n      .shadowContains('Item 1');\n\n    cy.shadowGet('basic-test')\n      .shadowFind('.app')\n      .shadowFind('div')\n      .shadowEq(1)\n      .shadowFind('.sample-text')\n      .shadowEq(1)\n      .shadowContains('Item 2');\n\n    cy.shadowGet('basic-test')\n      .shadowFind('.app')\n      .shadowFind('div')\n      .shadowEq(1)\n      .shadowFind('.sample-text')\n      .shadowEq(2)\n      .shadowContains('Item 3');\n  });\n});\n"
  },
  {
    "path": "cypress/integration/event_tests.ts",
    "content": "describe('Delegating events', () => {\n  let eventHasFired = false;\n\n  const fireEvent = () => {\n    eventHasFired = true;\n  };\n\n  before(() => {\n    cy.visit('/');\n    cy.shadowGet('props-test').then((element) => {\n      const [component] = element;\n      component.addEventListener('test-click-event', fireEvent);\n    });\n  });\n\n  it('should contain a custom element', () => {\n    cy.get('event-test').should('exist');\n  });\n\n  it('should not have fired event', () => {\n    expect(eventHasFired).to.equal(false);\n  });\n\n  it('should fire event', () => {\n    cy.shadowGet('props-test')\n      .shadowFind('.app')\n      .shadowFind('.button')\n      .shadowClick().then(() => {\n        expect(eventHasFired).to.equal(true);\n      });\n  });\n});\n"
  },
  {
    "path": "cypress/integration/external_loader_test.ts",
    "content": "describe('Applying external resources', () => {\n  before(() => {\n    cy.visit('/');\n  });\n\n  it('should contain a custom element', () => {\n    cy.get('external-loader-test').should('exist');\n  });\n\n  it('should have script tag in head', () => {\n    cy.get('head script[src=\"https://code.jquery.com/jquery-3.3.1.slim.min.js\"]').should('exist');\n  });\n\n  it('should have async script tag in head', () => {\n    cy.get(\n      'head script[src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js\"]',\n    ).should('have.attr', 'async');\n  });\n\n  it('should contain external styles', () => {\n    cy.shadowGet('external-loader-test')\n      .shadowFind('#direflow_external-sources')\n      .then((elem) => {\n        const [element] = elem;\n        const [link] = element.children;\n        expect(link.href).to.equal(\n          'https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css',\n        );\n      });\n  });\n});\n"
  },
  {
    "path": "cypress/integration/material_ui_test.ts",
    "content": "describe('Applying external resources', () => {\n  before(() => {\n    cy.visit('/');\n  });\n\n  it('should contain a custom element', () => {\n    cy.get('material-ui-test').should('exist');\n  });\n\n  it('should contain styles', () => {\n    cy.shadowGet('material-ui-test')\n      .shadowFind('#direflow_material-ui-styles')\n      .then((elem) => {\n        const [element] = elem;\n        expect(element).not.to.be.undefined;\n      });\n  });\n\n  it('should style button correctly', () => {\n    cy.shadowGet('material-ui-test')\n      .shadowFind('#material-ui-button')\n      .then((elem) => {\n        const [element] = elem;\n        const bgColor = window.getComputedStyle(element, null).getPropertyValue('background-color');\n        expect(bgColor).to.equal('rgb(63, 81, 181)');\n      });\n  });\n});\n"
  },
  {
    "path": "cypress/integration/props_tests.ts",
    "content": "describe('Using properties and attributes', () => {\n  before(() => {\n    cy.visit('/');\n  });\n\n  const assertSampleList = (id, assertions) => {\n    cy.shadowGet(id)\n      .shadowFind('.app')\n      .shadowFind('div')\n      .shadowEq(1)\n      .shadowFind('.sample-text')\n      .shadowEq(0)\n      .shadowContains(assertions[0]);\n\n    cy.shadowGet(id)\n      .shadowFind('.app')\n      .shadowFind('div')\n      .shadowEq(1)\n      .shadowFind('.sample-text')\n      .shadowEq(1)\n      .shadowContains(assertions[1]);\n\n    cy.shadowGet(id)\n      .shadowFind('.app')\n      .shadowFind('div')\n      .shadowEq(1)\n      .shadowFind('.sample-text')\n      .shadowEq(2)\n      .shadowContains(assertions[2]);\n  };\n\n  it('should contain a custom element', () => {\n    cy.get('#props-test-1').should('exist');\n  });\n\n  it('should have default componentTitle', () => {\n    cy.shadowGet('#props-test-1')\n      .shadowFind('.app')\n      .shadowFind('.header-title')\n      .shadowContains('Props Title');\n  });\n\n  it('should contain a custom element', () => {\n    cy.get('#props-test-1').should('exist');\n  });\n\n  it('setting componentTitle property should update componentTitle', () => {\n    cy.shadowGet('#props-test-1').then((element) => {\n      const [component] = element;\n      component.componentTitle = 'Update Title';\n\n      cy.shadowGet('#props-test-1')\n        .shadowFind('.app')\n        .shadowFind('.header-title')\n        .shadowContains('Update Title');\n    });\n  });\n\n  it('setting componenttitle attribute should update componentTitle', () => {\n    cy.shadowGet('#props-test-1').then((element) => {\n      const [component] = element;\n      component.setAttribute('componenttitle', 'Any');\n\n      cy.shadowGet('#props-test-1')\n        .shadowFind('.app')\n        .shadowFind('.header-title')\n        .shadowContains('Any');\n    });\n  });\n\n  it('should update componentTitle with delay', () => {\n    cy.shadowGet('#props-test-1')\n      .shadowFind('.app')\n      .shadowFind('.header-title')\n      .shadowContains('Any');\n\n    cy.wait(500);\n\n    cy.shadowGet('#props-test-1').then((element) => {\n      const [component] = element;\n      component.componentTitle = 'Delay Title';\n\n      cy.shadowGet('#props-test-1')\n        .shadowFind('.app')\n        .shadowFind('.header-title')\n        .shadowContains('Delay Title');\n    });\n  });\n\n  it('should update sampleList items', () => {\n    cy.shadowGet('#props-test-1').then((element) => {\n      const [component] = element;\n      const samples = ['New Item 1', 'New Item 2', 'New Item 3'];\n      component.sampleList = samples;\n\n      assertSampleList('#props-test-1', samples);\n    });\n  });\n\n  it('should update sampleList items with delay', () => {\n    const currentSamples = ['New Item 1', 'New Item 2', 'New Item 3'];\n    assertSampleList('#props-test-1', currentSamples);\n\n    cy.wait(500);\n\n    cy.shadowGet('#props-test-1').then((element) => {\n      const [component] = element;\n      const newSamples = ['Delayed Item 1', 'Delayed Item 2', 'Delayed Item 3'];\n      component.sampleList = newSamples;\n\n      assertSampleList('#props-test-1', newSamples);\n    });\n  });\n\n  it('should update based on falsy value', () => {\n    cy.shadowGet('#props-test-1')\n      .shadowFind('.app')\n      .shadowFind('.header-title')\n      .shadowContains('Delay Title');\n\n    cy.shadowGet('#props-test-1').then((element) => {\n      const [component] = element;\n      component.showTitle = false;\n\n      cy.shadowGet('#props-test-1')\n        .shadowFind('.app')\n        .shadowFind('.header-title')\n        .shadowContains('no-title');\n    });\n  });\n\n  it('should update based on attribute without value', () => {\n    cy.shadowGet('#props-test-2')\n      .shadowFind('.app')\n      .shadowFind('.hidden')\n      .shadowContains('SHOW HIDDEN');\n  });\n\n  it('should treat attribute value \"false\" as boolean', () => {\n    cy.shadowGet('#props-test-3')\n      .shadowFind('.app')\n      .shadowFind('.header-title')\n      .shadowContains('no-title');\n  });\n\n  it('should parse attribute with JSON content', () => {\n    assertSampleList('#props-test-4', ['test-1', 'test-2', 'test-3']);\n  });\n});\n"
  },
  {
    "path": "cypress/integration/slot_tests.ts",
    "content": "describe('Running basic component without Shadow DOM', () => {\n  before(() => {\n    cy.visit('/');\n  });\n\n  it('should contain a custom element', () => {\n    cy.get('slot-test').should('exist');\n  });\n\n  it('should contain a slotted element', () => {\n    cy.shadowGet('slot-test')\n      .shadowFind('.app')\n      .shadowFind('.slotted-elements')\n      .shadowFind('slot')\n      .shadowEq(0)\n      .then((element) => {\n        const [slotted] = element[0].assignedNodes();\n        expect(slotted).contain('Slot Item 1');\n      });\n  });\n\n  it('should dynamically inject a slotted element', () => {\n    cy.shadowGet('slot-test').then((element) => {\n      const [component] = element;\n\n      const newSlotted = document.createElement('div');\n      newSlotted.innerHTML = 'Slot Item 2';\n      newSlotted.slot = 'slotted-item-2';\n\n      component.appendChild(newSlotted);\n\n      cy.shadowGet('slot-test')\n        .shadowFind('.app')\n        .shadowFind('.slotted-elements')\n        .shadowFind('slot')\n        .shadowEq(1)\n        .then((element) => {\n          const [slotted] = element[0].assignedNodes();\n          expect(slotted).contain('Slot Item 2');\n        });\n    });\n  });\n});\n"
  },
  {
    "path": "cypress/integration/styled_components_test.ts",
    "content": "describe('Applying external resources', () => {\n  before(() => {\n    cy.visit('/');\n  });\n\n  it('should contain a custom element', () => {\n    cy.get('styled-components-test').should('exist');\n  });\n\n  it('should contain styles', () => {\n    cy.shadowGet('styled-components-test')\n      .shadowFind('#direflow_styled-components-styles')\n      .then((elem) => {\n        const [element] = elem;\n        const [style] = element.children;\n        expect(style.getAttribute('data-styled')).to.equal('active');\n      });\n  });\n\n  it('should style button correctly', () => {\n    cy.shadowGet('styled-components-test')\n      .shadowFind('#styled-component-button')\n      .then((elem) => {\n        const [element] = elem;\n        const bgColor = window.getComputedStyle(element, null).getPropertyValue('background-color');\n        expect(bgColor).to.equal('rgb(255, 0, 0)');\n      });\n  });\n});\n"
  },
  {
    "path": "cypress/support/commands.js",
    "content": "import 'cypress-shadow-dom';\n"
  },
  {
    "path": "cypress/support/index.js",
    "content": "import './commands';\n"
  },
  {
    "path": "cypress/test-setup/direflow-config.json",
    "content": "{\n  \"build\": {\n    \"filename\": \"direflowBundle.js\"\n  }\n}\n"
  },
  {
    "path": "cypress/test-setup/direflow-webpack.js",
    "content": "const { webpackConfig } = require('direflow-scripts');\nconst { aliasWebpack } = require(\"react-app-alias\");\n\n/**\n * Webpack configuration for Direflow Component\n * Additional webpack plugins / overrides can be provided here\n */\nmodule.exports = (config, env) => {\n  let useWebpackConfig = {\n    ...webpackConfig(config, env),\n    // Add your own webpack config here (optional)\n  };\n  useWebpackConfig = aliasWebpack({})(useWebpackConfig);\n  return useWebpackConfig;\n};\n"
  },
  {
    "path": "cypress/test-setup/jsconfig.json",
    "content": "{\n  \"extends\": \"./jsconfig.paths.json\",\n  \"compilerOptions\": {\n    \"strict\": true,\n    \"target\": \"es5\",\n    \"lib\": [\"es5\", \"dom\"],\n    \"types\": [\"cypress\", \"cypress-shadow-dom\", \"node\"],\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"skipLibCheck\": true,\n    \"noEmit\": false\n  },\n  \"include\": [\"**/*.js\"]\n}\n"
  },
  {
    "path": "cypress/test-setup/jsconfig.paths.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \"src\",\n    \"paths\": {\n      \"react\": [\"./node_modules/react\"],\n      \"react-dom\": [\"./node_modules/react-dom\"],\n      \"styled-components\": [\"./node_modules/styled-components\"],\n      \"@material-ui\": [\"./node_modules/@material-ui\"]\n    }\n  }\n}\n"
  },
  {
    "path": "cypress/test-setup/package.json",
    "content": "{\n  \"name\": \"test-setup\",\n  \"description\": \"This project is created using Direflow\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"start\": \"PORT=5000 direflow-scripts start\",\n    \"build\": \"direflow-scripts build && cp ./public/index.css ./build && cp ./public/index_prod.html ./build/index.html\",\n    \"serve\": \"serve ./build -l 5000\"\n  },\n  \"dependencies\": {\n    \"@material-ui/core\": \"^4.9.7\",\n    \"direflow-component\": \"../../packages/direflow-component\",\n    \"direflow-scripts\": \"../../packages/direflow-scripts\",\n    \"eslint-plugin-react-hooks\": \"^4.5.0\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-lib-adler32\": \"^1.0.3\",\n    \"react-scripts\": \"^4.0.3\",\n    \"serve\": \"^13.0.2\",\n    \"styled-components\": \"^5.0.1\",\n    \"webfontloader\": \"^1.6.28\"\n  },\n  \"devDependencies\": {\n    \"eslint-plugin-node\": \"^11.1.0\",\n    \"eslint-plugin-promise\": \"^6.0.0\",\n    \"eslint-plugin-react\": \"^7.30.0\",\n    \"jest-environment-jsdom-fourteen\": \"^1.0.1\",\n    \"react-app-alias\": \"^2.2.2\",\n    \"react-app-rewired\": \"^2.2.1\",\n    \"react-test-renderer\": \"17.0.2\",\n    \"to-string-loader\": \"^1.2.0\",\n    \"webpack-cli\": \"^4.9.2\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"react-app\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"jest\": {\n    \"setupFilesAfterEnv\": [\n      \"direflow-scripts/direflow-jest.config.js\"\n    ]\n  },\n  \"config-overrides-path\": \"direflow-webpack.js\"\n}\n"
  },
  {
    "path": "cypress/test-setup/public/index.css",
    "content": "body {\n  padding: 0;\n  margin: 0;\n  width: 100vw;\n  padding-top: 150px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background-color: #F6FAFA;\n}"
  },
  {
    "path": "cypress/test-setup/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <title>Test Setup</title>\n  </head>\n  <body>\n    <basic-test></basic-test>\n    <props-test id=\"props-test-1\" componentTitle=\"Props Title\"></props-test>\n    <props-test id=\"props-test-2\" componentTitle=\"Props Title\" showHidden ></props-test>\n    <props-test id=\"props-test-3\" componentTitle=\"Props Title\" showTitle=\"false\" ></props-test>\n    <props-test id=\"props-test-4\" componentTitle=\"Props Title\" sampleList=\"['test-1', 'test-2', 'test-3']\"></props-test>\n    <event-test></event-test>\n    <slot-test componentTitle=\"Props Title\">\n      <div slot=\"slotted-item-1\">Slot Item 1</div>\n    </slot-test>\n    <external-loader-test></external-loader-test>\n    <styled-components-test></styled-components-test>\n    <material-ui-test></material-ui-test>\n  </body>\n</html>\n"
  },
  {
    "path": "cypress/test-setup/public/index_prod.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <title>Test Setup</title>\n    <script src=\"./direflowBundle.js\"></script>\n  </head>\n  <body>\n    <basic-test></basic-test>\n    <props-test id=\"props-test-1\" componentTitle=\"Props Title\"></props-test>\n    <props-test id=\"props-test-2\" componentTitle=\"Props Title\" showHidden ></props-test>\n    <props-test id=\"props-test-3\" componentTitle=\"Props Title\" showTitle=\"false\" ></props-test>\n    <props-test id=\"props-test-4\" componentTitle=\"Props Title\" sampleList=\"['test-1', 'test-2', 'test-3']\"></props-test>\n    <event-test></event-test>\n    <slot-test componentTitle=\"Props Title\">\n      <div slot=\"slotted-item-1\">Slot Item 1</div>\n    </slot-test>\n    <external-loader-test></external-loader-test>\n    <styled-components-test></styled-components-test>\n    <material-ui-test></material-ui-test>\n  </body>\n</html>\n"
  },
  {
    "path": "cypress/test-setup/src/component-exports.js",
    "content": "/**\n * In this file you can export components that will\n * be build as a pure React component library.\n * \n * Using the command `npm run build:lib` will\n * produce a folder `lib` with your React components.\n *\n * If you're not using a React component library,\n * this file can be safely deleted.\n */\n\nimport App from './direflow-components/test-setup/App';\n\nexport { \n  App \n};\n"
  },
  {
    "path": "cypress/test-setup/src/direflow-components/test-setup/App.css",
    "content": ".app {\n  width: 400px;\n  height: 575px;\n  padding: 30px 60px;\n  box-sizing: border-box;\n  background-color: white;\n  box-shadow: 0 4px 14px 4px #375c821c;\n  font-family: 'Noto Sans JP', sans-serif;\n  border-bottom: 5px solid #cad5e6;\n}\n\n.top {\n  width: 100%;\n  height: 50%;\n  border-bottom: 2px solid #7998c7;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n.bottom {\n  width: 100%;\n  height: 50%;\n  border-top: 2px solid #7998c7;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-around;\n  align-items: center;\n}\n\n.header-image {\n  width: 165px;\n  height: 165px;\n  background: url('https://silind-s3.s3.eu-west-2.amazonaws.com/direflow/logo.svg');\n  background-size: contain;\n}\n\n.header-title {\n  font-size: 34px;\n  color: #5781C2;\n  font-family: 'Advent Pro', sans-serif;\n}\n\n.sample-text {\n  font-family: 'Noto Sans JP', sans-serif;\n  font-size: 16px;\n  color: #666;\n  text-align: center;\n}\n\n.button {\n  width: 150px;\n  height: 45px;\n  font-family: 'Noto Sans JP', sans-serif;\n  font-size: 20px;\n  font-weight: bold;\n  background-color: #5781C2;\n  color: white;\n  box-shadow: 2px 2px 5px #16314d98;\n  outline: none;\n  border: 0;\n  cursor: pointer;\n  transition: 0.3s;\n}\n\n.button:hover {\n  box-shadow: 4px 4px 8px #16314d63;\n  background-color: #40558f;\n}\n"
  },
  {
    "path": "cypress/test-setup/src/direflow-components/test-setup/App.js",
    "content": "import React from 'react';\nimport { Styled, EventConsumer } from 'direflow-component';\nimport styles from './App.css';\n\nconst App = (props) => {\n  const handleClick = (dispatch) => {\n    const event = new Event('test-click-event');\n    dispatch(event);\n  };\n\n  const renderSampleList = props.sampleList.map((sample) => (\n    <div key={sample} className='sample-text'>\n      {sample}\n    </div>\n  ));\n\n  const title = props.showTitle ? props.componentTitle : 'no-title';\n  const hidden = props.showHidden ? 'SHOW HIDDEN' : null;\n\n  return (\n    <Styled styles={styles}>\n      <div className='app'>\n        <div className='header-title'>{title}</div>\n        <div>{renderSampleList}</div>\n        <div className='slotted-elements'>\n          <slot name='slotted-item-1' />\n          <slot name='slotted-item-2' />\n        </div>\n        <div className='hidden'>{hidden}</div>\n        <EventConsumer>\n          {(dispatch) => (\n            <button className='button' onClick={() => handleClick(dispatch)}>\n              Click\n            </button>\n          )}\n        </EventConsumer>\n      </div>\n    </Styled>\n  );\n};\n\nApp.defaultProps = {\n  componentTitle: 'Test Setup',\n  showTitle: true,\n  showHidden: false,\n  sampleList: ['Item 1', 'Item 2', 'Item 3'],\n};\n\nexport default App;\n"
  },
  {
    "path": "cypress/test-setup/src/direflow-components/test-setup/MaterialUI.js",
    "content": "import React from 'react';\nimport Button from '@material-ui/core/Button';\n\nconst MaterialUI = () => {\n  return (\n    <Button id='material-ui-button' variant='contained' color='primary'>\n      My Material UI Button\n    </Button>\n  );\n};\n\nexport default MaterialUI;\n"
  },
  {
    "path": "cypress/test-setup/src/direflow-components/test-setup/StyledComponent.js",
    "content": "import React from 'react';\nimport styled from 'styled-components';\n\nconst RedButton = styled.div`\n  width: 100px;\n  height: 50px;\n  background-color: red;\n`;\n\nconst StyledComponent = () => {\n  return <RedButton id='styled-component-button'>Styled Component Button</RedButton>;\n};\n\nexport default StyledComponent;\n"
  },
  {
    "path": "cypress/test-setup/src/direflow-components/test-setup/index.js",
    "content": "import { DireflowComponent } from 'direflow-component';\nimport App from './App';\nimport StyledComponent from './StyledComponent';\nimport MaterialUI from './MaterialUI';\n\nDireflowComponent.createAll([\n  {\n    component: App,\n    configuration: {\n      tagname: 'basic-test',\n    },\n  },\n  {\n    component: App,\n    configuration: {\n      tagname: 'props-test',\n    },\n  },\n  {\n    component: App,\n    configuration: {\n      tagname: 'event-test',\n    },\n  },\n  {\n    component: App,\n    configuration: {\n      tagname: 'slot-test',\n    },\n  },\n  {\n    component: App,\n    configuration: {\n      tagname: 'external-loader-test',\n    },\n    plugins: [\n      {\n        name: 'external-loader',\n        options: {\n          paths: [\n            'https://code.jquery.com/jquery-3.3.1.slim.min.js',\n            'https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css',\n            {\n              src: 'https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js',\n              async: true,\n            },\n          ],\n        },\n      },\n    ],\n  },\n  {\n    component: StyledComponent,\n    configuration: {\n      tagname: 'styled-components-test',\n    },\n    plugins: [\n      {\n        name: 'styled-components',\n      },\n    ],\n  },\n  {\n    component: MaterialUI,\n    configuration: {\n      tagname: 'material-ui-test',\n    },\n    plugins: [\n      {\n        name: 'material-ui',\n      },\n    ],\n  },\n]);\n"
  },
  {
    "path": "cypress/test-setup/src/direflow-components/test-setup/test/App.test.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport renderer from 'react-test-renderer';\nimport App from '../App';\n\nconst reactProps = {\n  componentTitle: 'Component Test',\n  sampleList: ['Mock', 'Test', 'Data'],\n};\n\nit('renders without crashing', () => {\n  const div = document.createElement('div');\n  ReactDOM.render(<App {...reactProps} />, div);\n  ReactDOM.unmountComponentAtNode(div);\n});\n\nit('matches snapshot as expected', () => {\n  const renderTree = renderer.create(<App {...reactProps} />).toJSON();\n  expect(renderTree).toMatchSnapshot();\n});\n"
  },
  {
    "path": "cypress/test-setup/src/index.js",
    "content": "/**\n * This is the entry file of the Direflow setup.\n *\n * You can add any additional functionality here.\n * For example, this is a good place to hook into your\n * Web Component once it's mounted on the DOM.\n *\n * !This file cannot be removed.\n * It can be left blank if not needed.\n */\n"
  },
  {
    "path": "cypress/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"strict\": true,\n    \"baseUrl\": \"../node_modules\",\n    \"target\": \"es5\",\n    \"lib\": [\"es5\", \"dom\"],\n    \"types\": [\"cypress\", \"cypress-shadow-dom\", \"node\"],\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"skipLibCheck\": true,\n    \"noEmit\": false\n  },\n  \"include\": [\"**/*.ts\"]\n}\n"
  },
  {
    "path": "cypress.json",
    "content": "{\n  \"baseUrl\": \"http://localhost:5000\",\n  \"video\": false\n}\n"
  },
  {
    "path": "declarations.d.ts",
    "content": "declare module 'to-case';\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"direflow-cli\",\n  \"version\": \"4.0.0\",\n  \"description\": \"Official CLI for Direflow\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"test\": \"jest\",\n    \"update-version\": \"node scripts/node/updateVersion.js\",\n    \"setup-local\": \"./scripts/bash/setupLocal.sh\",\n    \"clean:all\": \"node ./scripts/node/cleanupAll.js\",\n    \"install:all\": \"node ./scripts/node/installAll.js\",\n    \"build:all\": \"node ./scripts/node/buildAll.js && npm run install:all -- --no-deps\",\n    \"build:full\": \"npm run clean:all && npm run install:all && npm run build:all && npm run clean:all -- --modules\",\n    \"cypress:open\": \"cypress open\",\n    \"cypress:run\": \"cypress run\",\n    \"cypress:test\": \"./scripts/bash/startIntegrationTest.sh\"\n  },\n  \"bin\": {\n    \"direflow\": \"bin/direflow\"\n  },\n  \"files\": [\n    \"bin/*\",\n    \"dist/*\",\n    \"templates/*\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:Silind-Software/direflow.git\"\n  },\n  \"keywords\": [\n    \"cli\",\n    \"widget\",\n    \"web component\",\n    \"react\",\n    \"typescript\"\n  ],\n  \"author\": \"Silind Software\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://direflow.io\",\n  \"dependencies\": {\n    \"boxen\": \"^6.2.1\",\n    \"chalk\": \"4.1.2\",\n    \"commander\": \"^9.3.0\",\n    \"deepmerge\": \"^4.2.2\",\n    \"esm\": \"^3.2.25\",\n    \"handlebars\": \"^4.7.7\",\n    \"inquirer\": \"^8.2.4\",\n    \"mkdirp\": \"^1.0.4\",\n    \"ncp\": \"^2.0.0\",\n    \"rimraf\": \"^3.0.2\",\n    \"to-case\": \"^2.0.0\"\n  },\n  \"devDependencies\": {\n    \"@types/inquirer\": \"^8.2.1\",\n    \"@types/jest\": \"^28.1.0\",\n    \"@types/jsdom\": \"^16.2.14\",\n    \"@types/mkdirp\": \"^1.0.2\",\n    \"@types/mock-fs\": \"^4.13.1\",\n    \"@types/ncp\": \"^2.0.5\",\n    \"@types/node\": \"^17.0.39\",\n    \"@types/rimraf\": \"^3.0.2\",\n    \"@types/webpack\": \"^5.28.0\",\n    \"@typescript-eslint/eslint-plugin\": \"^5.27.0\",\n    \"@typescript-eslint/parser\": \"^5.27.0\",\n    \"cypress\": \"9.5.0\",\n    \"cypress-shadow-dom\": \"^1.3.0\",\n    \"eslint\": \"^8.17.0\",\n    \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n    \"eslint-plugin-import\": \"^2.26.0\",\n    \"eslint-plugin-jsx-a11y\": \"^6.5.1\",\n    \"eslint-plugin-node\": \"^11.1.0\",\n    \"eslint-plugin-promise\": \"^6.0.0\",\n    \"eslint-plugin-react\": \"^7.30.0\",\n    \"eslint-plugin-react-hooks\": \"^4.5.0\",\n    \"jest\": \"^28.1.0\",\n    \"jsdom\": \"^19.0.0\",\n    \"memfs\": \"^3.4.7\",\n    \"prettier\": \"^2.6.2\",\n    \"start-server-and-test\": \"^1.14.0\",\n    \"ts-jest\": \"^28.0.4\",\n    \"typescript\": \"^4.7.3\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"react-app\"\n  },\n  \"jest\": {\n    \"roots\": [\n      \"<rootDir>/\"\n    ],\n    \"moduleFileExtensions\": [\n      \"ts\",\n      \"js\",\n      \"tsx\"\n    ],\n    \"transform\": {\n      \"^.+\\\\.(ts|tsx)$\": \"ts-jest\"\n    },\n    \"testMatch\": [\n      \"**/**/*.test.(ts|tsx)\"\n    ],\n    \"testPathIgnorePatterns\": [\n      \"<rootDir>/templates\",\n      \"<rootDir>/packages\",\n      \"<rootDir>/cypress\"\n    ],\n    \"collectCoverage\": true\n  }\n}\n"
  },
  {
    "path": "packages/direflow-component/README.md",
    "content": "# direflow-component\n### This package includes configurations and scripts used by [Direflow](https://direflow.io)\n\n:warning: This package is not meant to be used on its own, but as a part of [Direflow](https://direflow.io).  \n\nPlease refer to the official webpage in order to get started."
  },
  {
    "path": "packages/direflow-component/declarations.d.ts",
    "content": "declare module 'react-lib-adler32';\n\ndeclare module '*.css' {\n  const classes: { readonly [key: string]: string };\n  export default classes;\n}\n\ndeclare module '*.svg' {\n  const content: any;\n  export default content;\n}\n"
  },
  {
    "path": "packages/direflow-component/package.json",
    "content": "{\n  \"name\": \"direflow-component\",\n  \"version\": \"4.0.0\",\n  \"description\": \"Create Web Components using React\",\n  \"main\": \"dist/index.js\",\n  \"author\": \"Silind Software\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"build\": \"tsc\"\n  },\n  \"files\": [\n    \"dist\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:Silind-Software/direflow.git\"\n  },\n  \"homepage\": \"https://direflow.io\",\n  \"dependencies\": {\n    \"chalk\": \"4.1.2\",\n    \"lodash\": \"^4.17.21\",\n    \"react-lib-adler32\": \"^1.0.3\",\n    \"sass\": \"^1.52.2\",\n    \"webfontloader\": \"^1.6.28\"\n  },\n  \"devDependencies\": {\n    \"@types/lodash\": \"^4.14.182\",\n    \"@types/react\": \"17.0.2\",\n    \"@types/react-dom\": \"^17.0.2\",\n    \"@types/webfontloader\": \"^1.6.34\",\n    \"typescript\": \"^4.7.3\"\n  },\n  \"peerDependencies\": {\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\"\n  }\n}"
  },
  {
    "path": "packages/direflow-component/src/DireflowComponent.tsx",
    "content": "import WebComponentFactory from './WebComponentFactory';\nimport { IDireflowComponent } from './types/DireflowConfig';\nimport { DireflowElement } from './types/DireflowElement';\nimport includePolyfills from './helpers/polyfillHandler';\nimport DireflowPromiseAlike from './types/DireflowPromiseAlike';\n\nlet _resolve: Function;\n\nconst callback = (element: HTMLElement) => {\n  _resolve?.(element as DireflowElement);\n};\n\nclass DireflowComponent {\n  /**\n   * Create muliple Direflow Components\n   * @param App React Component\n   */\n  public static createAll(componentConfigs: IDireflowComponent[]): Array<DireflowPromiseAlike> {\n    return componentConfigs.map(DireflowComponent.create);\n  }\n\n  /**\n   * Create Direflow Component\n   * @param App React Component\n   */\n  public static create(componentConfig: IDireflowComponent): DireflowPromiseAlike {\n    const { component } = componentConfig;\n    const plugins = component.plugins || componentConfig.plugins;\n    const configuration = component.configuration || componentConfig.configuration;\n\n    if (!component) {\n      throw Error('Root component has not been set');\n    }\n\n    if (!configuration) {\n      throw Error('No configuration found');\n    }\n\n    const componentProperties = {\n      ...componentConfig?.properties,\n      ...component.properties,\n      ...component.defaultProps,\n    };\n\n    const tagName = configuration.tagname || 'direflow-component';\n    const shadow = configuration.useShadow !== undefined ? configuration.useShadow : true;\n    const anonymousSlot = configuration.useAnonymousSlot !== undefined ? configuration.useAnonymousSlot : false;\n\n    (async () => {\n      /**\n       * TODO: This part should be removed in next minor version\n       */\n      await Promise.all([includePolyfills({ usesShadow: !!shadow }, plugins)]);\n\n      const WebComponent = new WebComponentFactory(\n        componentProperties,\n        component,\n        shadow,\n        anonymousSlot,\n        plugins,\n        callback,\n      ).create();\n\n      customElements.define(tagName, WebComponent);\n    })();\n\n    return {\n      then: async (resolve?: (element: HTMLElement) => void) => {\n        if (resolve) {\n          _resolve = resolve;\n        }\n      },\n    };\n  }\n}\n\nexport default DireflowComponent;\n"
  },
  {
    "path": "packages/direflow-component/src/WebComponentFactory.tsx",
    "content": "/* eslint-disable class-methods-use-this */\n/* eslint-disable max-classes-per-file */\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport _ from 'lodash';\nimport createProxyRoot from './helpers/proxyRoot';\nimport { IDireflowPlugin } from './types/DireflowConfig';\nimport { EventProvider } from './components/EventContext';\nimport { PluginRegistrator } from './types/PluginRegistrator';\nimport registeredPlugins from './plugins/plugins';\nimport getSerialized from './helpers/getSerialized';\n\nclass WebComponentFactory {\n  constructor(\n    private componentProperties: { [key: string]: unknown },\n    private rootComponent: React.FC<any> | React.ComponentClass<any, any>,\n    private shadow?: boolean,\n    private anonymousSlot?: boolean,\n    private plugins?: IDireflowPlugin[],\n    private connectCallback?: (element: HTMLElement) => void,\n  ) {\n    this.reflectPropertiesToAttributes();\n  }\n\n  private componentAttributes: { [key: string]: {\n    property: string;\n    value: unknown;\n  }; } = {};\n\n  /**\n   * All properties with primitive values are added to attributes.\n   */\n  private reflectPropertiesToAttributes() {\n    Object.entries(this.componentProperties).forEach(([key, value]) => {\n      if (typeof value !== 'number' && typeof value !== 'string' && typeof value !== 'boolean') {\n        return;\n      }\n\n      this.componentAttributes[key.toLowerCase()] = {\n        property: key,\n        value,\n      };\n    });\n  }\n\n  /**\n   * Create new class that will serve as the Web Component.\n   */\n  public create() {\n    const factory = this;\n\n    return class WebComponent extends HTMLElement {\n      public initialProperties = _.cloneDeep(factory.componentProperties);\n      public properties: { [key: string]: unknown } = {};\n      public hasConnected = false;\n\n      constructor() {\n        super();\n        this.transferInitialProperties();\n        this.subscribeToProperties();\n      }\n\n      /**\n       * Observe attributes for changes.\n       * Part of the Web Component Standard.\n       */\n      public static get observedAttributes() {\n        return Object.keys(factory.componentAttributes);\n      }\n\n      /**\n       * Web Component gets mounted on the DOM.\n       */\n      public connectedCallback() {\n        this.mountReactApp({ initial: true });\n        this.hasConnected = true;\n        factory.connectCallback?.(this);\n      }\n\n      /**\n       * When an attribute is changed, this callback function is called.\n       * @param name name of the attribute\n       * @param oldValue value before change\n       * @param newValue value after change\n       */\n      public attributeChangedCallback(name: string, oldValue: string, newValue: string) {\n        if (!this.hasConnected) {\n          return;\n        }\n\n        if (oldValue === newValue) {\n          return;\n        }\n\n        if (!factory.componentAttributes.hasOwnProperty(name)) {\n          return;\n        }\n\n        const propertyName = factory.componentAttributes[name].property;\n        this.properties[propertyName] = getSerialized(newValue);\n        this.mountReactApp();\n      }\n\n      /**\n       * When a property is changed, this callback function is called.\n       * @param name name of the property\n       * @param oldValue value before change\n       * @param newValue value after change\n       */\n      public propertyChangedCallback(name: string, oldValue: unknown, newValue: unknown) {\n        if (!this.hasConnected) {\n          return;\n        }\n\n        if (oldValue === newValue) {\n          return;\n        }\n\n        this.properties[name] = newValue;\n        this.mountReactApp();\n      }\n\n      /**\n       * Web Component gets unmounted from the DOM.\n       */\n      public disconnectedCallback() {\n        ReactDOM.unmountComponentAtNode(this);\n      }\n\n      /**\n       * Setup getters and setters for all properties.\n       * Here we ensure that the 'propertyChangedCallback' will get invoked\n       * when a property changes.\n       */\n      public subscribeToProperties() {\n        const propertyMap = {} as PropertyDescriptorMap;\n        Object.keys(this.initialProperties).forEach((key: string) => {\n          propertyMap[key] = {\n            configurable: true,\n            enumerable: true,\n\n            get: (): unknown => {\n              const currentValue = this.properties.hasOwnProperty(key)\n                ? this.properties[key]\n                : _.get(this.initialProperties, key);\n\n              return currentValue;\n            },\n\n            set: (newValue: unknown) => {\n              const oldValue = this.properties.hasOwnProperty(key)\n                ? this.properties[key]\n                : _.get(this.initialProperties, key);\n\n              this.propertyChangedCallback(key, oldValue, newValue);\n            },\n          };\n        });\n\n        Object.defineProperties(this, propertyMap);\n      }\n\n      /**\n       * Syncronize all properties and attributes\n       */\n      public syncronizePropertiesAndAttributes() {\n        Object.keys(this.initialProperties).forEach((key: string) => {\n          if (this.properties.hasOwnProperty(key)) {\n            return;\n          }\n\n          if (this.getAttribute(key) !== null) {\n            this.properties[key] = getSerialized(this.getAttribute(key) as string);\n            return;\n          }\n\n          this.properties[key] = _.get(this.initialProperties, key);\n        });\n      }\n\n      /**\n       * Transfer initial properties from the custom element.\n       */\n      public transferInitialProperties() {\n        Object.keys(this.initialProperties).forEach((key: string) => {\n          if (this.hasOwnProperty(key)) {\n            this.properties[key] = this[key as keyof WebComponent];\n          }\n        });\n      }\n\n      /**\n       * Apply plugins\n       */\n      public applyPlugins(application: JSX.Element): [JSX.Element, Element[]] {\n        const shadowChildren: Element[] = [];\n\n        const applicationWithPlugins = registeredPlugins.reduce(\n          (app: JSX.Element, currentPlugin: PluginRegistrator) => {\n            const pluginResult = currentPlugin(this, factory.plugins, app);\n\n            if (!pluginResult) {\n              return app;\n            }\n\n            const [wrapper, shadowChild] = pluginResult;\n\n            if (shadowChild) {\n              shadowChildren.push(shadowChild);\n            }\n\n            return wrapper;\n          },\n          application,\n        );\n\n        return [applicationWithPlugins, shadowChildren];\n      }\n\n      /**\n       * Generate react props based on properties and attributes.\n       */\n      public reactProps(): { [key: string]: unknown } {\n        this.syncronizePropertiesAndAttributes();\n        return this.properties;\n      }\n\n      /**\n       * Mount React App onto the Web Component\n       */\n      public mountReactApp(options?: { initial: boolean }) {\n        const anonymousSlot = factory.anonymousSlot ? React.createElement('slot') : undefined;\n        const application = (\n          <EventProvider value={this.eventDispatcher}>\n            {React.createElement(factory.rootComponent, this.reactProps(), anonymousSlot)}\n          </EventProvider>\n        );\n\n        const [applicationWithPlugins, shadowChildren] = this.applyPlugins(application);\n\n        if (!factory.shadow) {\n          ReactDOM.render(applicationWithPlugins, this);\n          return;\n        }\n\n        let currentChildren: Node[] | undefined;\n\n        if (options?.initial) {\n          currentChildren = Array.from(this.children).map((child: Node) => child.cloneNode(true));\n        }\n\n        const root = createProxyRoot(this, shadowChildren);\n        ReactDOM.render(<root.open>{applicationWithPlugins}</root.open>, this);\n\n        if (currentChildren) {\n          currentChildren.forEach((child: Node) => this.append(child));\n        }\n      }\n\n      /**\n       * Dispatch an event from the Web Component\n       */\n      public eventDispatcher = (event: Event) => {\n        this.dispatchEvent(event);\n      };\n    };\n  }\n}\n\nexport default WebComponentFactory;\n"
  },
  {
    "path": "packages/direflow-component/src/components/EventContext.tsx",
    "content": "import { createContext } from 'react';\n\nconst EventContext = createContext<Function>(() => { /* Initially return nothing */ });\nexport const EventProvider = EventContext.Provider;\nexport const EventConsumer = EventContext.Consumer;\nexport { EventContext };\n"
  },
  {
    "path": "packages/direflow-component/src/components/Styled.tsx",
    "content": "import React, { FC, Component, ReactNode, ComponentClass, CSSProperties } from 'react';\nimport Style from '../helpers/styleInjector';\n\ntype TStyles = string | string[] | CSSProperties | CSSProperties[];\n\ninterface IStyled {\n  styles: TStyles;\n  scoped?: boolean;\n  children: ReactNode | ReactNode[];\n}\n\nconst Styled: FC<IStyled> = (props): JSX.Element => {\n  let styles;\n\n  if (typeof props.styles === 'string') {\n    styles = (props.styles as CSSProperties).toString();\n  } else {\n    styles = (props.styles as CSSProperties[]).reduce(\n      (acc: CSSProperties, current: CSSProperties) => `${acc} ${current}` as CSSProperties,\n    );\n  }\n\n  return (\n    <Style scoped={props.scoped}>\n      {styles}\n      {props.children}\n    </Style>\n  );\n};\n\nconst withStyles = (styles: TStyles) => <P, S>(WrappedComponent: ComponentClass<P, S> | FC<P>) => {\n  // eslint-disable-next-line react/prefer-stateless-function\n  return class extends Component<P, S> {\n    public render(): JSX.Element {\n      return (\n        <Styled styles={styles}>\n          <div>\n            <WrappedComponent {...(this.props as P)} />\n          </div>\n        </Styled>\n      );\n    }\n  };\n};\n\nexport { withStyles, Styled };\n"
  },
  {
    "path": "packages/direflow-component/src/decorators/DireflowConfiguration.ts",
    "content": "import { IDireflowComponent } from '../types/DireflowConfig';\n\nfunction DireflowConfiguration(config: Partial<IDireflowComponent>) {\n  return <T extends React.ComponentClass<any, any>>(\n    constructor: T & Partial<IDireflowComponent>,\n  ) => {\n    const decoratedConstructor = constructor;\n\n    decoratedConstructor.configuration = config.configuration;\n    decoratedConstructor.properties = config.properties;\n    decoratedConstructor.plugins = config.plugins;\n\n    return decoratedConstructor;\n  };\n}\n\nexport default DireflowConfiguration;\n"
  },
  {
    "path": "packages/direflow-component/src/helpers/asyncScriptLoader.ts",
    "content": "type TBundle = { script: Element; hasLoaded: boolean };\ndeclare global {\n  interface Window {\n    wcPolyfillsLoaded: TBundle[];\n    reactBundleLoaded: TBundle[];\n  }\n}\n\nconst asyncScriptLoader = (src: string, bundleListKey: 'wcPolyfillsLoaded' | 'reactBundleLoaded'): Promise<void> => {\n  return new Promise((resolve, reject) => {\n    const script = document.createElement('script');\n    script.async = true;\n    script.src = src;\n\n    if (!window[bundleListKey]) {\n      window[bundleListKey] = [];\n    }\n\n    const existingPolyfill = window[bundleListKey].find((loadedScript) => {\n      return loadedScript.script.isEqualNode(script);\n    });\n\n    if (existingPolyfill) {\n      if (existingPolyfill.hasLoaded) {\n        resolve();\n      }\n\n      existingPolyfill.script.addEventListener('load', () => resolve());\n      return;\n    }\n\n    const scriptEntry = {\n      script,\n      hasLoaded: false,\n    };\n\n    window[bundleListKey].push(scriptEntry);\n\n    script.addEventListener('load', () => {\n      scriptEntry.hasLoaded = true;\n      resolve();\n    });\n\n    script.addEventListener('error', () => reject(new Error('Polyfill failed to load')));\n\n    document.head.appendChild(script);\n  });\n};\n\nexport default asyncScriptLoader;\n"
  },
  {
    "path": "packages/direflow-component/src/helpers/domControllers.ts",
    "content": "export const injectIntoShadowRoot = (webComponent: HTMLElement, element: Element): void => {\n  const elementToPrepend = webComponent.shadowRoot || webComponent;\n\n  if (existsIdenticalElement(element, elementToPrepend)) {\n    return;\n  }\n\n  elementToPrepend.prepend(element);\n};\n\nexport const injectIntoHead = (element: Element) => {\n  if (existsIdenticalElement(element, document.head)) {\n    return;\n  }\n\n  document.head.append(element);\n};\n\nexport const stripStyleFromHead = (styleId: string) => {\n  const allChildren = document.head.children;\n  const style = Array.from(allChildren).find((child) => child.id === styleId);\n\n  if (style) {\n    document.head.removeChild(style);\n  }\n};\n\nexport const existsIdenticalElement = (element: Element, host: Element | ShadowRoot): boolean => {\n  const allChildren = host.children;\n  const exists = Array.from(allChildren).some((child) => element.isEqualNode(child));\n  return exists;\n};\n"
  },
  {
    "path": "packages/direflow-component/src/helpers/getSerialized.ts",
    "content": "const getSerialized = (data: string) => {\n  if (data === '') {\n    return true;\n  }\n\n  if (data === 'true' || data === 'false') {\n    return data === 'true';\n  }\n\n  try {\n    const parsed = JSON.parse(data.replace(/'/g, '\"'));\n    return parsed;\n  } catch (error) {\n    return data;\n  }\n};\n\nexport default getSerialized;\n"
  },
  {
    "path": "packages/direflow-component/src/helpers/polyfillHandler.ts",
    "content": "import { IDireflowPlugin } from '../types/DireflowConfig';\nimport asyncScriptLoader from './asyncScriptLoader';\n\ntype TWcPolyfillsLoaded = Array<{ script: Element; hasLoaded: boolean }>;\ndeclare global {\n  interface Window {\n    wcPolyfillsLoaded: TWcPolyfillsLoaded;\n  }\n}\n\nlet didIncludeOnce = false;\n\nconst DEFAULT_SD = 'https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.4.1/bundles/webcomponents-sd.js';\nconst DEFAULT_CE = 'https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.4.1/bundles/webcomponents-ce.js';\nconst DEFAULT_AD = 'https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.4.1/custom-elements-es5-adapter.js';\n\nconst includePolyfills = async (\n  options: { usesShadow: boolean },\n  plugins: IDireflowPlugin[] | undefined,\n) => {\n  if (didIncludeOnce) {\n    return;\n  }\n  const scriptsList = [];\n\n  let useSD = '';\n  let useCE = '';\n  let useAD = '';\n\n  const polyfillLoaderPlugin = plugins?.find((plugin) => plugin.name === 'polyfill-loader');\n\n  if (polyfillLoaderPlugin) {\n    console.warn(\n      'polyfill-loader plugin is deprecated. Use direflow-config.json instead.' + '\\n' +\n      'See more: https://direflow.io/configuration',\n    );\n  }\n\n  const polyfillSD = process.env.DIREFLOW_SD ?? polyfillLoaderPlugin?.options?.use.sd;\n  const polyfillCE = process.env.DIREFLOW_CE ?? polyfillLoaderPlugin?.options?.use.ce;\n  const polyfillAdapter = process.env.DIREFLOW_ADAPTER ?? polyfillLoaderPlugin?.options?.use.adapter;\n\n  const disableSD = polyfillSD === false;\n  const disableCE = polyfillCE === false;\n  const disableAD = polyfillAdapter === false;\n\n  if (polyfillSD) {\n    useSD = typeof polyfillSD === 'string'\n      ? polyfillSD\n      : DEFAULT_SD;\n  }\n\n  if (polyfillCE) {\n    useCE = typeof polyfillCE === 'string'\n      ? polyfillCE\n      : DEFAULT_CE;\n  }\n\n  if (polyfillAdapter) {\n    useAD = typeof polyfillAdapter === 'string'\n      ? polyfillAdapter\n      : DEFAULT_AD;\n  }\n\n  if (options.usesShadow && !disableSD) {\n    scriptsList.push(asyncScriptLoader(useSD || DEFAULT_SD, 'wcPolyfillsLoaded'));\n  }\n\n  if (!disableCE) {\n    scriptsList.push(asyncScriptLoader(useCE || DEFAULT_CE, 'wcPolyfillsLoaded'));\n  }\n\n  if (!disableAD) {\n    scriptsList.push(asyncScriptLoader(useAD || DEFAULT_AD, 'wcPolyfillsLoaded'));\n  }\n\n  try {\n    await Promise.all(scriptsList);\n    didIncludeOnce = true;\n  } catch (error) {\n    console.error(error);\n  }\n};\n\nexport default includePolyfills;\n"
  },
  {
    "path": "packages/direflow-component/src/helpers/proxyRoot.tsx",
    "content": "import React, { FC } from 'react';\nimport { createPortal } from 'react-dom';\n\ninterface IPortal {\n  targetElement: ShadowRoot;\n  children: React.ReactNode;\n}\n\ninterface IShadowComponent {\n  children: React.ReactNode | React.ReactNode[];\n}\n\ninterface IComponentOptions {\n  webComponent: Element;\n  mode: 'open' | 'closed';\n  shadowChildren: Element[];\n}\n\nconst Portal: FC<IPortal> = (props) => {\n  const targetElement = (props.targetElement as unknown) as Element;\n  return createPortal(props.children, targetElement);\n};\n\nconst createProxyComponent = (options: IComponentOptions) => {\n  const ShadowRoot: FC<IShadowComponent> = (props) => {\n    const shadowedRoot = options.webComponent.shadowRoot\n      || options.webComponent.attachShadow({ mode: options.mode });\n\n    options.shadowChildren.forEach((child) => {\n      shadowedRoot.appendChild(child);\n    });\n\n    return <Portal targetElement={shadowedRoot}>{props.children}</Portal>;\n  };\n\n  return ShadowRoot;\n};\n\nconst componentMap = new WeakMap<Element, React.FC<IShadowComponent>>();\n\nconst createProxyRoot = (\n  webComponent: Element,\n  shadowChildren: Element[],\n): { [key in 'open' | 'closed']: React.FC<IShadowComponent> } => {\n  return new Proxy<any>(\n    { open: null, closed: null },\n    {\n      get(_: unknown, mode: 'open' | 'closed') {\n        if (componentMap.get(webComponent)) {\n          return componentMap.get(webComponent);\n        }\n\n        const proxyComponent = createProxyComponent({ webComponent, mode, shadowChildren });\n        componentMap.set(webComponent, proxyComponent);\n        return proxyComponent;\n      },\n    },\n  );\n};\n\nexport default createProxyRoot;\n"
  },
  {
    "path": "packages/direflow-component/src/helpers/registerPlugin.ts",
    "content": "import { IDireflowPlugin } from '../types/DireflowConfig';\nimport { PluginRegistrator } from '../types/PluginRegistrator';\n\nconst registerPlugin = (registrator: PluginRegistrator) => {\n  return (\n    element: HTMLElement,\n    plugins: IDireflowPlugin[] | undefined,\n    app?: JSX.Element,\n  ) => registrator(element, plugins, app);\n};\n\nexport default registerPlugin;\n"
  },
  {
    "path": "packages/direflow-component/src/helpers/styleInjector.tsx",
    "content": "import React, { Component, cloneElement, isValidElement } from 'react';\nimport adler32 from 'react-lib-adler32';\n\nconst isDevEnv = process.env.NODE_ENV !== 'production';\n\ninterface IProps {\n  scoped?: boolean;\n}\n\nclass Style extends Component<IProps> {\n  private scopeClassNameCache: { [key: string]: string } = {};\n  private scopedCSSTextCache: { [key: string]: string } = {};\n  private scoped = this.props.scoped !== undefined ? this.props.scoped : true;\n  private pepper = '';\n\n  getStyleString = () => {\n    if (this.props.children instanceof Array) {\n      const styleString = this.props.children.filter(\n        (child) => !isValidElement(child) && typeof child === 'string',\n      );\n\n      if (styleString.length > 1) {\n        throw new Error(`Multiple style objects as direct descedents of a\n        Style component are not supported (${styleString.length} style objects detected):\n\n        ${styleString[0]}\n        `);\n      }\n\n      return styleString[0];\n    }\n\n    if (typeof this.props.children === 'string' && !isValidElement(this.props.children)) {\n      return this.props.children;\n    }\n\n    return null;\n  };\n\n  getRootElement = () => {\n    if (this.props.children instanceof Array) {\n      const rootElement = this.props.children.filter((child) => isValidElement(child));\n\n      if (isDevEnv) {\n        if (rootElement.length > 1) {\n          console.log(rootElement);\n          throw new Error(`Adjacent JSX elements must be wrapped in an enclosing tag \n          (${rootElement.length} root elements detected)`);\n        }\n\n        if (\n          typeof rootElement[0] !== 'undefined' &&\n          this.isVoidElement((rootElement[0] as any).type)\n        ) {\n          throw new Error(`Self-closing void elements like ${(rootElement as any).type} must be \n          wrapped in an enclosing tag. Reactive Style must be able to nest a style element inside of the \n          root element and void element content models never \n          allow it to have contents under any circumstances.`);\n        }\n      }\n\n      return rootElement[0];\n    }\n\n    if (isValidElement(this.props.children)) {\n      return this.props.children;\n    }\n\n    return null;\n  };\n\n  getRootSelectors = (rootElement: any) => {\n    const rootSelectors = [];\n\n    if (rootElement.props.id) {\n      rootSelectors.push(`#${rootElement.props.id}`);\n    }\n\n    if (rootElement.props.className) {\n      rootElement.props.className\n        .trim()\n        .split(/\\s+/g)\n        .forEach((className: string) => rootSelectors.push(className));\n    }\n\n    if (!rootSelectors.length && typeof rootElement.type !== 'function') {\n      rootSelectors.push(rootElement.type);\n    }\n\n    return rootSelectors;\n  };\n\n  processCSSText = (styleString: any, scopeClassName?: string, rootSelectors?: any[]) => {\n    return styleString\n      .replace(/\\s*\\/\\/(?![^(]*\\)).*|\\s*\\/\\*.*\\*\\//g, '')\n      .replace(/\\s\\s+/g, ' ')\n      .split('}')\n      .map((fragment: any) => {\n        const isDeclarationBodyPattern = /.*:.*;/g;\n        const isLastItemDeclarationBodyPattern = /.*:.*(;|$|\\s+)/g;\n        const isAtRulePattern = /\\s*@/g;\n        const isKeyframeOffsetPattern = /\\s*(([0-9][0-9]?|100)\\s*%)|\\s*(to|from)\\s*$/g;\n\n        return fragment\n          .split('{')\n          .map((statement: any, i: number, arr: any[]) => {\n            if (!statement.trim().length) {\n              return '';\n            }\n\n            const isDeclarationBodyItemWithOptionalSemicolon =\n              arr.length - 1 === i && statement.match(isLastItemDeclarationBodyPattern);\n            if (\n              statement.match(isDeclarationBodyPattern) ||\n              isDeclarationBodyItemWithOptionalSemicolon\n            ) {\n              return this.escapeTextContentForBrowser(statement);\n            }\n\n            const selector = statement;\n\n            if (scopeClassName && !/:target/gi.test(selector)) {\n              if (!selector.match(isAtRulePattern) && !selector.match(isKeyframeOffsetPattern)) {\n                return this.scopeSelector(scopeClassName, selector, rootSelectors);\n              }\n\n              return selector;\n            }\n\n            return selector;\n          })\n          .join('{\\n');\n      })\n      .join('}\\n');\n  };\n\n  escaper = (match: any) => {\n    const ESCAPE_LOOKUP: { [key: string]: string } = {\n      '>': '&gt;',\n      '<': '&lt;',\n    };\n\n    return ESCAPE_LOOKUP[match];\n  };\n\n  escapeTextContentForBrowser = (text: string) => {\n    const ESCAPE_REGEX = /[><]/g;\n    return `${text}`.replace(ESCAPE_REGEX, this.escaper);\n  };\n\n  scopeSelector = (scopeClassName: string, selector: string, rootSelectors?: any[]) => {\n    const scopedSelector: string[] = [];\n\n    const groupOfSelectorsPattern = /,(?![^(|[]*\\)|\\])/g;\n\n    const selectors = selector.split(groupOfSelectorsPattern);\n\n    selectors.forEach((selectorElement) => {\n      let containsSelector;\n      let unionSelector;\n\n      if (\n        rootSelectors?.length &&\n        rootSelectors.some((rootSelector) => selectorElement.match(rootSelector))\n      ) {\n        unionSelector = selectorElement;\n\n        const escapedRootSelectors = rootSelectors?.map((rootSelector) =>\n          rootSelector.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&'),\n        );\n\n        unionSelector = unionSelector.replace(\n          new RegExp(`(${escapedRootSelectors?.join('|')})`),\n          `$1${scopeClassName}`,\n        );\n\n        containsSelector = this.scoped ? `${scopeClassName} ${selectorElement}` : selectorElement;\n        scopedSelector.push(unionSelector, containsSelector);\n      } else {\n        containsSelector = this.scoped ? `${scopeClassName} ${selectorElement}` : selectorElement;\n        scopedSelector.push(containsSelector);\n      }\n    });\n\n    if (!this.scoped && scopedSelector.length > 1) {\n      return scopedSelector[1];\n    }\n\n    return scopedSelector.join(', ');\n  };\n\n  getScopeClassName = (styleString: any, rootElement: any) => {\n    let hash = styleString;\n\n    if (rootElement) {\n      this.pepper = '';\n      this.traverseObjectToGeneratePepper(rootElement);\n      hash += this.pepper;\n    }\n\n    return (isDevEnv ? 'scope-' : 's') + adler32(hash);\n  };\n\n  traverseObjectToGeneratePepper = (obj: any, depth = 0) => {\n    if (depth > 32 || this.pepper.length > 10000) return;\n\n    Object.keys(obj).forEach((prop) => {\n      const isPropReactInternal = /^[_$]|type|ref|^value$/.test(prop);\n\n      if (!!obj[prop] && typeof obj[prop] === 'object' && !isPropReactInternal) {\n        this.traverseObjectToGeneratePepper(obj[prop], depth + 1);\n      } else if (!!obj[prop] && !isPropReactInternal && typeof obj[prop] !== 'function') {\n        this.pepper += obj[prop];\n      }\n    });\n  };\n\n  isVoidElement = (type: string) =>\n    [\n      'area',\n      'base',\n      'br',\n      'col',\n      'command',\n      'embed',\n      'hr',\n      'img',\n      'input',\n      'keygen',\n      'link',\n      'meta',\n      'param',\n      'source',\n      'track',\n      'wbr',\n    ].some((voidType) => type === voidType);\n\n  createStyleElement = (cssText: string, scopeClassName: string) => {\n    return (\n      <style\n        id='direflow_styles'\n        type='text/css'\n        key={scopeClassName}\n        // eslint-disable-next-line react/no-danger\n        dangerouslySetInnerHTML={{ __html: cssText || '' }}\n      />\n    );\n  };\n\n  getNewChildrenForCloneElement = (\n    cssText: string,\n    rootElement: JSX.Element,\n    scopeClassName: string,\n  ) => {\n    return [this.createStyleElement(cssText, scopeClassName)].concat(rootElement.props.children);\n  };\n\n  render() {\n    const styleString = this.getStyleString();\n    const rootElement: any = this.getRootElement();\n\n    if (!styleString && rootElement) {\n      return rootElement.props.children;\n    }\n\n    if (styleString && !rootElement) {\n      return this.createStyleElement(\n        this.processCSSText(styleString),\n        this.getScopeClassName(styleString, rootElement),\n      );\n    }\n\n    const rootElementId = rootElement.props.id ? rootElement.props.id : '';\n    const rootElementClassNames = rootElement.props.className\n      ? `${rootElement.props.className} `\n      : '';\n\n    let scopeClassName;\n    let scopedCSSText;\n    const scopeClassNameAddress = rootElementClassNames + rootElementId + styleString;\n\n    if (this.scopeClassNameCache[scopeClassNameAddress]) {\n      scopeClassName = this.scopeClassNameCache[scopeClassNameAddress];\n      scopedCSSText = this.scopedCSSTextCache[scopeClassName];\n    } else {\n      scopeClassName = this.getScopeClassName(styleString, rootElement);\n      scopedCSSText = this.processCSSText(\n        styleString,\n        `.${scopeClassName}`,\n        this.getRootSelectors(rootElement),\n      );\n\n      this.scopeClassNameCache[scopeClassNameAddress] = scopeClassName;\n      this.scopedCSSTextCache[scopeClassName] = scopedCSSText;\n    }\n\n    const className = this.scoped\n      ? `${rootElementClassNames}${scopeClassName}`\n      : rootElementClassNames;\n\n    return cloneElement(\n      rootElement,\n      {\n        ...rootElement.props,\n        className: className.trim(),\n      },\n      this.getNewChildrenForCloneElement(scopedCSSText, rootElement, scopeClassName),\n    );\n  }\n}\n\nexport default Style;\n"
  },
  {
    "path": "packages/direflow-component/src/hooks/useExternalSource.ts",
    "content": "import { useState, useEffect } from 'react';\n\ntype TSource = {\n  [key: string]: {\n    state: 'loading' | 'completed';\n    callback?: Function | null;\n  };\n};\n\ndeclare global {\n  interface Window {\n    externalSourcesLoaded: TSource;\n  }\n}\n\n/**\n * Hook into an external source given a path\n * Returns whether the source is loaded or not\n * @param source\n */\nconst useExternalSource = (source: string) => {\n  const [hasLoaded, setHasLoaded] = useState(false);\n\n  useEffect(() => {\n    if (window.externalSourcesLoaded[source].state === 'completed') {\n      setHasLoaded(true);\n      return;\n    }\n\n    window.externalSourcesLoaded[source].callback = () => {\n      setHasLoaded(true);\n    };\n  }, []);\n\n  return hasLoaded;\n};\n\nexport default useExternalSource;\n"
  },
  {
    "path": "packages/direflow-component/src/index.ts",
    "content": "import DireflowComponent from './DireflowComponent';\nimport DireflowConfiguration from './decorators/DireflowConfiguration';\n\nimport useExternalSource from './hooks/useExternalSource';\n\nexport { Styled, withStyles } from './components/Styled';\nexport { EventProvider, EventConsumer, EventContext } from './components/EventContext';\nexport { DireflowComponent, DireflowConfiguration, useExternalSource };\n"
  },
  {
    "path": "packages/direflow-component/src/plugins/externalLoaderPlugin.ts",
    "content": "import { injectIntoHead } from '../helpers/domControllers';\nimport { IDireflowPlugin } from '../types/DireflowConfig';\nimport { PluginRegistrator } from '../types/PluginRegistrator';\n\ntype TSource = {\n  [key: string]: {\n    state: 'loading' | 'completed';\n    callback?: Function | null;\n  };\n};\n\ndeclare global {\n  interface Window {\n    externalSourcesLoaded: TSource;\n  }\n}\n\nconst externalLoaderPlugin: PluginRegistrator = (\n  element: HTMLElement,\n  plugins: IDireflowPlugin[] | undefined,\n  app?: JSX.Element,\n) => {\n  const plugin = plugins?.find((p) => p.name === 'external-loader');\n  const paths = plugin?.options?.paths;\n\n  if (!paths || !paths.length || !app) {\n    return;\n  }\n\n  const scriptTags: HTMLScriptElement[] = [];\n  const styleTags: HTMLLinkElement[] = [];\n\n  paths.forEach((path: string | { src: string; async?: boolean; useHead?: boolean }) => {\n    const actualPath = typeof path === 'string' ? path : path.src;\n    const async = typeof path === 'string' ? false : path.async;\n    const useHead = typeof path === 'string' ? undefined : path.useHead;\n\n    if (actualPath.endsWith('.js')) {\n      const script = document.createElement('script');\n      script.src = actualPath;\n      script.async = !!async;\n\n      if (useHead !== undefined && !useHead) {\n        script.setAttribute('use-head', 'false');\n      } else {\n        script.setAttribute('use-head', 'true');\n      }\n\n      scriptTags.push(script);\n    }\n\n    if (actualPath.endsWith('.css')) {\n      const link = document.createElement('link');\n      link.rel = 'stylesheet';\n      link.href = actualPath;\n\n      if (useHead) {\n        link.setAttribute('use-head', 'true');\n      } else {\n        link.setAttribute('use-head', 'false');\n      }\n\n      styleTags.push(link);\n    }\n  });\n\n  const insertionPoint = document.createElement('span');\n  insertionPoint.id = 'direflow_external-sources';\n\n  if (!window.externalSourcesLoaded) {\n    window.externalSourcesLoaded = {};\n  }\n\n  scriptTags.forEach((script) => {\n    if (script.getAttribute('use-head') === 'true') {\n      injectIntoHead(script);\n    } else {\n      insertionPoint.appendChild(script);\n    }\n\n    window.externalSourcesLoaded[script.src] = {\n      state: 'loading',\n    };\n\n    script.addEventListener('load', () => {\n      window.externalSourcesLoaded[script.src].state = 'completed';\n      window.externalSourcesLoaded[script.src].callback?.();\n    });\n  });\n\n  styleTags.forEach((link) => {\n    if (link.getAttribute('use-head') === 'true') {\n      injectIntoHead(link);\n    } else {\n      insertionPoint.appendChild(link);\n    }\n\n    window.externalSourcesLoaded[link.href] = {\n      state: 'loading',\n    };\n\n    link.addEventListener('load', () => {\n      window.externalSourcesLoaded[link.href].state = 'completed';\n      window.externalSourcesLoaded[link.href].callback?.();\n    });\n  });\n\n  return [app, insertionPoint];\n};\n\nexport default externalLoaderPlugin;\n"
  },
  {
    "path": "packages/direflow-component/src/plugins/fontLoaderPlugin.ts",
    "content": "import WebFont from 'webfontloader';\nimport { IDireflowPlugin } from '../types/DireflowConfig';\nimport { PluginRegistrator } from '../types/PluginRegistrator';\n\nlet didInclude = false;\n\nconst fontLoaderPlugin: PluginRegistrator = (\n  element: HTMLElement,\n  plugins: IDireflowPlugin[] | undefined,\n) => {\n  if (didInclude) {\n    return;\n  }\n\n  const plugin = plugins?.find((p) => p.name === 'font-loader');\n\n  if (plugin?.options) {\n    WebFont.load(plugin.options);\n    didInclude = true;\n  }\n};\n\nexport default fontLoaderPlugin;\n"
  },
  {
    "path": "packages/direflow-component/src/plugins/iconLoaderPlugin.ts",
    "content": "import { IDireflowPlugin } from '../types/DireflowConfig';\nimport { PluginRegistrator } from '../types/PluginRegistrator';\n\nconst iconLoaderPlugin: PluginRegistrator = (\n  element: HTMLElement,\n  plugins: IDireflowPlugin[] | undefined,\n  app?: JSX.Element,\n) => {\n  const plugin = plugins?.find((p) => p.name === 'icon-loader');\n\n  if (!app) {\n    return;\n  }\n\n  if (plugin?.options?.packs.includes('material-icons')) {\n    const link = document.createElement('link');\n    link.rel = 'stylesheet';\n    link.href = 'https://fonts.googleapis.com/icon?family=Material+Icons';\n\n    const insertionPoint = document.createElement('span');\n    insertionPoint.id = 'direflow_material-icons';\n    insertionPoint.appendChild(link);\n\n    return [app, insertionPoint];\n  }\n};\n\nexport default iconLoaderPlugin;\n"
  },
  {
    "path": "packages/direflow-component/src/plugins/materialUiPlugin.tsx",
    "content": "import React from 'react';\nimport uniqueid from 'lodash';\nimport { IDireflowPlugin } from '../types/DireflowConfig';\nimport { PluginRegistrator } from '../types/PluginRegistrator';\n\nconst jssCache = new WeakMap<Element, any>();\n\nconst materialUiPlugin: PluginRegistrator = (\n  element: HTMLElement,\n  plugins: IDireflowPlugin[] | undefined,\n  app?: JSX.Element,\n) => {\n  if (plugins?.find((plugin) => plugin.name === 'material-ui')) {\n    try {\n      const { create } = require('jss');\n      const { jssPreset, StylesProvider, createGenerateClassName } = require('@material-ui/core/styles');\n      const seed = uniqueid(`${element.tagName.toLowerCase()}-`);\n      const insertionPoint = document.createElement('span');\n      insertionPoint.id = 'direflow_material-ui-styles';\n\n      let jss: any;\n      if (jssCache.has(element)) {\n        jss = jssCache.get(element);\n      } else {\n        jss = create({\n          ...jssPreset(),\n          insertionPoint,\n        });\n        jssCache.set(element, jss);\n      }\n\n      return [\n        <StylesProvider\n          jss={jss}\n          sheetsManager={new Map()}\n          generateClassName={createGenerateClassName({ seed })}\n        >\n          {app}\n        </StylesProvider>,\n        insertionPoint,\n      ];\n    } catch (err) {\n      console.error('Could not load Material-UI. Did you remember to install @material-ui/core?');\n    }\n  }\n};\n\nexport default materialUiPlugin;\n"
  },
  {
    "path": "packages/direflow-component/src/plugins/plugins.ts",
    "content": "import registerPlugin from '../helpers/registerPlugin';\nimport styledComponentsPlugin from './styledComponentsPlugin';\nimport externalLoaderPlugin from './externalLoaderPlugin';\nimport fontLoaderPlugin from './fontLoaderPlugin';\nimport iconLoaderPlugin from './iconLoaderPlugin';\nimport materialUiPlugin from './materialUiPlugin';\n\nconst plugins = [\n  registerPlugin(fontLoaderPlugin),\n  registerPlugin(iconLoaderPlugin),\n  registerPlugin(externalLoaderPlugin),\n  registerPlugin(styledComponentsPlugin),\n  registerPlugin(materialUiPlugin)\n];\n\nexport default plugins;\n"
  },
  {
    "path": "packages/direflow-component/src/plugins/styledComponentsPlugin.tsx",
    "content": "import React from 'react';\nimport { IDireflowPlugin } from '../types/DireflowConfig';\nimport { PluginRegistrator } from '../types/PluginRegistrator';\n\nconst styledComponentsPlugin: PluginRegistrator = (\n  element: HTMLElement,\n  plugins: IDireflowPlugin[] | undefined,\n  app?: JSX.Element,\n) => {\n  if (plugins?.find((plugin) => plugin.name === 'styled-components')) {\n    try {\n      const { StyleSheetManager } = require('styled-components');\n\n      const insertionPoint = document.createElement('span');\n      insertionPoint.id = 'direflow_styled-components-styles';\n\n      return [<StyleSheetManager target={insertionPoint}>{app}</StyleSheetManager>, insertionPoint];\n    } catch (error) {\n      console.error(\n        'Could not load styled-components. Did you remember to install styled-components?',\n      );\n    }\n  }\n};\n\nexport default styledComponentsPlugin;\n"
  },
  {
    "path": "packages/direflow-component/src/types/DireflowConfig.ts",
    "content": "export interface IDireflowComponent {\n  component: (React.FC<any> | React.ComponentClass<any, any>) & { [key: string]: any };\n  configuration: IDireflowConfig;\n  properties?: any;\n  plugins?: IDireflowPlugin[];\n}\n\nexport interface IDireflowConfig {\n  tagname: string;\n  useShadow?: boolean;\n  useAnonymousSlot?: boolean;\n}\n\nexport interface IDireflowPlugin {\n  name: string;\n  options?: any;\n}\n"
  },
  {
    "path": "packages/direflow-component/src/types/DireflowElement.ts",
    "content": "export type DireflowElement = { [key: string]: unknown } & HTMLElement;\n"
  },
  {
    "path": "packages/direflow-component/src/types/DireflowPromiseAlike.ts",
    "content": "import { type } from 'os';\n\ntype DireflowPromiseAlike = { then: (resolve: (element: HTMLElement) => void) => void };\n\nexport default DireflowPromiseAlike;\n"
  },
  {
    "path": "packages/direflow-component/src/types/PluginRegistrator.ts",
    "content": "import { IDireflowPlugin } from './DireflowConfig';\n\nexport type PluginRegistrator = (\n  element: HTMLElement,\n  plugins: IDireflowPlugin[] | undefined,\n  app?: JSX.Element,\n) => [JSX.Element, Element?] | void;\n"
  },
  {
    "path": "packages/direflow-component/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es2015\",\n    \"module\": \"esNext\",\n    \"lib\": [\n      \"es2017\",\n      \"es7\",\n      \"es6\",\n      \"dom\"\n    ],\n    \"declaration\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"skipLibCheck\": true,\n    \"jsx\": \"react\",\n    \"types\": [\n      \"node\"\n    ]\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"dist\"\n  ]\n}"
  },
  {
    "path": "packages/direflow-scripts/README.md",
    "content": "# direflow-scripts\n### This package includes configurations and scripts used by [Direflow](https://direflow.io)\n\n:warning: This package is not meant to be used on its own, but as a part of [Direflow](https://direflow.io).  \n\nPlease refer to the official webpage in order to get started."
  },
  {
    "path": "packages/direflow-scripts/bin/direflow-scripts",
    "content": "#!/usr/bin/env node\n\nrequire = require('esm')(module);\nconst cli = require('../dist/cli');\nconst [,, ...args] = process.argv;\ncli.default(args);\n"
  },
  {
    "path": "packages/direflow-scripts/declarations.d.ts",
    "content": "declare module 'config-overrides';\n\ndeclare module 'event-hooks-webpack-plugin';\n\ndeclare module 'html-webpack-externals-plugin';\n\ndeclare module 'event-hooks-webpack-plugin/lib/tasks';\n\ndeclare module 'webpack-filter-warnings-plugin';\n\ndeclare interface Window {\n  React?: any;\n  ReactDOM?: any;\n}\n"
  },
  {
    "path": "packages/direflow-scripts/direflow-jest.config.js",
    "content": "const { createContext } = require('react');\n\n// eslint-disable-next-line no-undef\njest.mock('../direflow-component', () => ({\n  Styled: (props) => {\n    return props.children;\n  },\n  EventContext: createContext(() => {}),\n}));\n"
  },
  {
    "path": "packages/direflow-scripts/package.json",
    "content": "{\n  \"name\": \"direflow-scripts\",\n  \"version\": \"4.0.0\",\n  \"description\": \"Create Web Components using React\",\n  \"main\": \"dist/index.js\",\n  \"author\": \"Silind Software\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"build\": \"tsc\"\n  },\n  \"bin\": {\n    \"direflow-scripts\": \"bin/direflow-scripts\"\n  },\n  \"files\": [\n    \"dist\",\n    \"bin\",\n    \"webpack.config.js\",\n    \"direflow-jest.config.js\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:Silind-Software/direflow.git\"\n  },\n  \"homepage\": \"https://direflow.io\",\n  \"dependencies\": {\n    \"@svgr/webpack\": \"^6.2.1\",\n    \"esm\": \"^3.2.25\",\n    \"event-hooks-webpack-plugin\": \"^2.2.0\",\n    \"handlebars\": \"^4.7.7\",\n    \"rimraf\": \"^3.0.2\",\n    \"ts-loader\": \"^9.3.0\",\n    \"webfontloader\": \"^1.6.28\",\n    \"webpack\": \"^5.73.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.18.2\",\n    \"@babel/preset-env\": \"^7.18.2\",\n    \"@babel/preset-react\": \"^7.17.12\",\n    \"@types/react\": \"17.0.2\",\n    \"@types/react-dom\": \"17.0.2\",\n    \"@types/webfontloader\": \"^1.6.34\",\n    \"babel-loader\": \"^8.2.5\",\n    \"terser-webpack-plugin\": \"^5.3.3\",\n    \"typescript\": \"^4.7.3\"\n  }\n}\n"
  },
  {
    "path": "packages/direflow-scripts/src/cli.ts",
    "content": "import chalk from 'chalk';\nimport { ChildProcess, spawn } from 'child_process';\nimport { resolve } from 'path';\nimport { interupted, succeeded } from './helpers/messages';\n\ntype TCommand = 'start' | 'test' | 'build' | 'build:lib';\n\nconst env = { ...process.env };\nenv.SKIP_PREFLIGHT_CHECK = 'true';\n\nexport default function cli(args: Array<TCommand | string>) {\n  const [command, ...restArgs] = args;\n\n  switch (command as TCommand) {\n    case 'start':\n      start();\n      break;\n    case 'test':\n      test(restArgs);\n      break;\n    case 'build':\n      build(restArgs);\n      break;\n    case 'build:lib':\n      buildLib(restArgs);\n      break;\n    default:\n      console.log('No arguments provided.');\n  }\n}\n\nfunction spawner(command: string, args: ReadonlyArray<string>, options?: any) {\n  return spawn(command, args, options).on('exit', (code: number) => {\n    if (code !== 0) {\n      process.exit(code as number);\n    }\n  });\n}\n\nfunction start() {\n  spawner('react-app-rewired', ['start'], {\n    shell: true,\n    stdio: 'inherit',\n    env,\n  });\n}\n\nfunction test(args: string[]) {\n  spawner('react-app-rewired', ['test', '--env=jest-environment-jsdom-fourteen', ...args], {\n    shell: true,\n    stdio: 'inherit',\n    env,\n  });\n}\n\nfunction build(args: string[]) {\n  spawner('react-app-rewired', ['build', ...args], {\n    shell: true,\n    stdio: 'inherit',\n    env,\n  });\n}\n\nfunction buildLib(args: string[]) {\n  console.log('Building React component library...');\n  let webpack: ChildProcess | undefined;\n\n  if (args[0] === '--verbose') {\n    webpack = spawner('webpack', ['--config', resolve(__dirname, '../webpack.config.js')], {\n      shell: true,\n      stdio: 'inherit',\n      env,\n    });\n  } else {\n    webpack = spawner('webpack', ['--config', resolve(__dirname, '../webpack.config.js')]);\n  }\n\n  webpack.stdout?.on('data', (data) => {\n    if (data.toString().includes('ERROR')) {\n      console.log(chalk.red('An error occurred during the build!'));\n      console.log(chalk.red(data.toString()));\n    }\n  });\n\n  webpack.on('exit', (code: number) => {\n    if (code !== 0) {\n      console.log(interupted());\n      return;\n    }\n\n    console.log(succeeded());\n  });\n}\n"
  },
  {
    "path": "packages/direflow-scripts/src/config/config-overrides.ts",
    "content": "import EventHooksPlugin from 'event-hooks-webpack-plugin';\nimport { EnvironmentPlugin } from 'webpack';\nimport rimraf from 'rimraf';\nimport fs from 'fs';\nimport { resolve } from 'path';\nimport { PromiseTask } from 'event-hooks-webpack-plugin/lib/tasks';\nimport entryResolver from '../helpers/entryResolver';\nimport {\n  TConfig,\n  IOptions,\n  IModule,\n  IOptimization,\n  IResolve,\n  TEntry,\n  IPlugin,\n} from '../types/ConfigOverrides';\nimport getDireflowConfig from '../helpers/getDireflowConfig';\nimport IDireflowConfig from '../types/DireflowConfig';\n\nexport = function override(config: TConfig, env: string, options?: IOptions) {\n  const originalEntry = [config.entry].flat() as string[];\n  const [pathIndex] = originalEntry.splice(0, 1);\n\n  /**\n   * TODO: Remove deprecated options\n   */\n  const direflowConfig = setDeprecatedOptions(\n    // Set deprecated options on config\n    env,\n    getDireflowConfig(pathIndex),\n    options,\n  );\n\n  const entries = addEntries(config.entry, pathIndex, env, direflowConfig);\n\n  const overridenConfig = {\n    ...config,\n    entry: entries,\n    module: overrideModule(config.module),\n    output: overrideOutput(config.output, direflowConfig),\n    optimization: overrideOptimization(config.optimization, env, direflowConfig),\n    resolve: overrideResolve(config.resolve),\n    plugins: overridePlugins(config.plugins, entries, env, direflowConfig),\n    externals: overrideExternals(config.externals, env, direflowConfig),\n  };\n\n  return overridenConfig;\n};\n\nfunction addEntries(entry: TEntry, pathIndex: string, env: string, config?: IDireflowConfig) {\n  const originalEntry = [entry].flat() as string[];\n\n  const react = config?.modules?.react;\n  const reactDOM = config?.modules?.reactDOM;\n  const useSplit = !!config?.build?.split;\n  const componentPath = config?.build?.componentPath || 'direflow-components';\n\n  const resolvedEntries = entryResolver(pathIndex, componentPath, { react, reactDOM });\n\n  const newEntry: { [key: string]: string } = { main: pathIndex };\n\n  originalEntry.forEach((path, index) => {\n    newEntry[`path-${index}`] = path;\n  });\n\n  resolvedEntries.forEach((entries: { [key: string]: string }) => {\n    Object.keys(entries).forEach((key) => {\n      newEntry[key] = entries[key];\n    });\n  });\n\n  const flatList = Object.values(newEntry);\n\n  if (env === 'development') {\n    return [...flatList, resolve(__dirname, '../template-scripts/welcome.js')];\n  }\n\n  if (useSplit) {\n    return newEntry;\n  }\n\n  return flatList;\n}\n\nfunction overrideModule(module: IModule) {\n  const nestedRulesIndex = module.rules.findIndex((rule) => 'oneOf' in rule);\n  const cssRuleIndex = module.rules[nestedRulesIndex].oneOf.findIndex((rule) => '.css'.match(rule.test));\n  const scssRuleIndex = module.rules[nestedRulesIndex].oneOf.findIndex((rule) => '.scss'.match(rule.test));\n\n  if (cssRuleIndex !== -1) {\n    module.rules[nestedRulesIndex].oneOf[cssRuleIndex].use = ['to-string-loader', 'css-loader'];\n  }\n\n  if (scssRuleIndex !== -1) {\n    module.rules[nestedRulesIndex].oneOf[scssRuleIndex].use = ['to-string-loader', 'css-loader', 'sass-loader'];\n  }\n\n  module.rules[nestedRulesIndex].oneOf.unshift({\n    test: /\\.svg$/,\n    use: ['@svgr/webpack'],\n  });\n\n  return module;\n}\n\nfunction overrideOutput(output: IOptions, config?: IDireflowConfig) {\n  const useSplit = config?.build?.split;\n  const filename = config?.build?.filename || 'direflowBundle.js';\n  const chunkFilename = config?.build?.chunkFilename || 'vendor.js';\n\n  const outputFilename = useSplit ? '[name].js' : filename;\n\n  return {\n    ...output,\n    filename: outputFilename,\n    chunkFilename,\n  };\n}\n\nfunction overrideOptimization(optimization: IOptimization, env: string, config?: IDireflowConfig) {\n  optimization.minimizer[0].options.sourceMap = env === 'development';\n  const useVendor = config?.build?.vendor;\n\n  const vendorSplitChunks = {\n    cacheGroups: {\n      vendor: {\n        test: /node_modules/,\n        chunks: 'initial',\n        name: 'vendor',\n        enforce: true,\n      },\n    },\n  };\n\n  return {\n    ...optimization,\n    splitChunks: useVendor ? vendorSplitChunks : false,\n    runtimeChunk: false,\n  };\n}\n\nfunction overridePlugins(plugins: IPlugin[], entry: TEntry, env: string, config?: IDireflowConfig) {\n  if (plugins[0].options) {\n    plugins[0].options.inject = 'head';\n  }\n\n  plugins.push(\n    new EventHooksPlugin({\n      done: new PromiseTask(() => copyBundleScript(env, entry, config)),\n    }),\n  );\n\n  if (config?.polyfills) {\n    plugins.push(\n      new EnvironmentPlugin(\n        Object.fromEntries(\n          Object.entries(config.polyfills).map(([key, value]) => {\n            const envKey = `DIREFLOW_${key.toUpperCase()}`;\n\n            if (value === 'true' || value === 'false') {\n              return [envKey, value === 'true'];\n            }\n\n            return [envKey, value];\n          }),\n        ),\n      ),\n    );\n  }\n\n  return plugins;\n}\n\nfunction overrideResolve(currentResolve: IResolve) {\n  try {\n    const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');\n\n    currentResolve.plugins = currentResolve.plugins.filter(\n      (plugin) => !(plugin instanceof ModuleScopePlugin),\n    );\n  } catch (error) {\n    // supress error\n  }\n\n  return currentResolve;\n}\n\nfunction overrideExternals(\n  externals: { [key: string]: any },\n  env: string,\n  config?: IDireflowConfig,\n) {\n  if (env === 'development') {\n    return externals;\n  }\n\n  const extraExternals: any = { ...externals };\n  const react = config?.modules?.react;\n  const reactDOM = config?.modules?.reactDOM;\n\n  if (react) {\n    extraExternals.react = 'React';\n  }\n\n  if (reactDOM) {\n    extraExternals['react-dom'] = 'ReactDOM';\n  }\n\n  return extraExternals;\n}\n\nasync function copyBundleScript(env: string, entry: TEntry, config?: IDireflowConfig) {\n  if (env !== 'production') {\n    return;\n  }\n\n  if (!fs.existsSync('build')) {\n    return;\n  }\n\n  const filename = config?.build?.filename || 'direflowBundle.js';\n  const chunkFilename = config?.build?.chunkFilename || 'vendor.js';\n  const emitAll = config?.build?.emitAll;\n  const emitSourceMaps = config?.build?.emitSourceMap;\n  const emitIndexHTML = config?.build?.emitIndexHTML;\n\n  if (emitAll) {\n    return;\n  }\n\n  fs.readdirSync('build').forEach((file: string) => {\n    if (file === filename) {\n      return;\n    }\n\n    if (file === chunkFilename) {\n      return;\n    }\n\n    if (!Array.isArray(entry) && Object.keys(entry).some((path) => `${path}.js` === file)) {\n      return;\n    }\n\n    if (emitSourceMaps && file.endsWith('.map')) {\n      return;\n    }\n\n    if (emitIndexHTML && file.endsWith('.html')) {\n      return;\n    }\n\n    rimraf.sync(`build/${file}`);\n  });\n}\n\n/**\n * TODO: This function should be removed in next minor version\n * @deprecated\n * @param flag\n * @param env\n */\nfunction hasOptions(flag: string, env: string) {\n  if (env !== 'production') {\n    return false;\n  }\n\n  if (process.argv.length < 3) {\n    return false;\n  }\n\n  if (!process.argv.some((arg: string) => arg === `--${flag}` || arg === `-${flag[0]}`)) {\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * TODO: This function should be removed in next minor version\n * @deprecated\n * @param config\n * @param options\n */\nfunction setDeprecatedOptions(env: string, config?: IDireflowConfig, options?: IOptions) {\n  if (!options) {\n    return config;\n  }\n\n  const newObj = config ? (JSON.parse(JSON.stringify(config)) as IDireflowConfig) : {};\n  const { filename, chunkFilename, react, reactDOM } = options;\n\n  const useSplit = hasOptions('split', env);\n  const useVendor = hasOptions('vendor', env);\n\n  if (filename && !newObj.build?.filename) {\n    if (!newObj.build) {\n      newObj.build = { filename };\n    } else {\n      newObj.build.filename = filename;\n    }\n  }\n\n  if (chunkFilename && !newObj.build?.chunkFilename) {\n    if (!newObj.build) {\n      newObj.build = { chunkFilename };\n    } else {\n      newObj.build.chunkFilename = chunkFilename;\n    }\n  }\n\n  if (useSplit && !newObj.build?.split) {\n    if (!newObj.build) {\n      newObj.build = { split: useSplit };\n    } else {\n      newObj.build.split = useSplit;\n    }\n  }\n\n  if (useVendor && !newObj.build?.vendor) {\n    if (!newObj.build) {\n      newObj.build = { vendor: useVendor };\n    } else {\n      newObj.build.vendor = useVendor;\n    }\n  }\n\n  if (react && !newObj.modules?.react) {\n    if (!newObj.modules) {\n      newObj.modules = { react } as { react: string };\n    } else {\n      newObj.modules.react = react as string;\n    }\n  }\n\n  if (reactDOM && !newObj.modules?.reactDOM) {\n    if (!newObj.modules) {\n      newObj.modules = { reactDOM } as { reactDOM: string };\n    } else {\n      newObj.modules.reactDOM = reactDOM as string;\n    }\n  }\n\n  return newObj;\n}\n"
  },
  {
    "path": "packages/direflow-scripts/src/helpers/asyncScriptLoader.ts",
    "content": "type TBundle = { script: Element; hasLoaded: boolean };\ndeclare global {\n  interface Window {\n    wcPolyfillsLoaded: TBundle[];\n    reactBundleLoaded: TBundle[];\n  }\n}\n\nconst asyncScriptLoader = (src: string, bundleListKey: 'wcPolyfillsLoaded' | 'reactBundleLoaded'): Promise<void> => {\n  return new Promise((resolve, reject) => {\n    const script = document.createElement('script');\n    script.async = true;\n    script.src = src;\n\n    if (!window[bundleListKey]) {\n      window[bundleListKey] = [];\n    }\n\n    const existingPolyfill = window[bundleListKey].find((loadedScript) => {\n      return loadedScript.script.isEqualNode(script);\n    });\n\n    if (existingPolyfill) {\n      if (existingPolyfill.hasLoaded) {\n        resolve();\n      }\n\n      existingPolyfill.script.addEventListener('load', () => resolve());\n      return;\n    }\n\n    const scriptEntry = {\n      script,\n      hasLoaded: false,\n    };\n\n    window[bundleListKey].push(scriptEntry);\n\n    script.addEventListener('load', () => {\n      scriptEntry.hasLoaded = true;\n      resolve();\n    });\n\n    script.addEventListener('error', () => reject(new Error('Polyfill failed to load')));\n\n    document.head.appendChild(script);\n  });\n};\n\nexport default asyncScriptLoader;\n"
  },
  {
    "path": "packages/direflow-scripts/src/helpers/entryResolver.ts",
    "content": "import fs from 'fs';\nimport { resolve, join, sep } from 'path';\nimport handlebars from 'handlebars';\nimport { IOptions } from '../types/ConfigOverrides';\n\nconst DEFAULT_REACT = 'https://unpkg.com/react@17/umd/react.production.min.js';\nconst DEFAULT_REACT_DOM = 'https://unpkg.com/react-dom@17/umd/react-dom.production.min.js';\n\nfunction entryResolver(indexPath: string, componentPath: string, { react, reactDOM }: IOptions) {\n  const paths = indexPath.split(sep);\n  const srcPath = [...paths].slice(0, paths.length - 1).join(sep);\n\n  let reactResource: any = 'none';\n  let reactDOMResource: any = 'none';\n\n  if (react !== false) {\n    reactResource = react || DEFAULT_REACT;\n  }\n\n  if (reactDOM !== false) {\n    reactDOMResource = reactDOM || DEFAULT_REACT_DOM;\n  }\n\n  const entryLoaderFile = fs.readFileSync(\n    resolve(__dirname, '../template-scripts/entryLoader.js'),\n    'utf8',\n  );\n  const componentFolders = fs.readdirSync(join(srcPath, componentPath));\n\n  const entryLoaderTemplate = handlebars.compile(entryLoaderFile);\n\n  const mainEntryFile = entryLoaderTemplate({\n    pathIndex: join(srcPath, paths[paths.length - 1]).replace(/\\\\/g, '\\\\\\\\'),\n    reactResource,\n    reactDOMResource,\n  });\n  const mainEntryLoaderPath = resolve(__dirname, '../main.js');\n  fs.writeFileSync(mainEntryLoaderPath, mainEntryFile);\n\n  const entryList = componentFolders\n    .map((folder) => {\n      if (!fs.statSync(join(srcPath, componentPath, folder)).isDirectory()) {\n        return;\n      }\n\n      const pathIndex = join(srcPath, componentPath, folder, paths[paths.length - 1]);\n\n      if (!fs.existsSync(pathIndex)) {\n        return;\n      }\n\n      const escapedPathIndex = pathIndex.replace(/\\\\/g, '\\\\\\\\');\n\n      const entryFile = entryLoaderTemplate({ pathIndex: escapedPathIndex, reactResource, reactDOMResource });\n      const entryLoaderPath = resolve(__dirname, `../${folder}.js`);\n\n      fs.writeFileSync(entryLoaderPath, entryFile);\n      return { [folder]: entryLoaderPath };\n    })\n    .filter(Boolean);\n\n  entryList.unshift({ main: mainEntryLoaderPath });\n\n  return entryList as Array<{ [key: string]: string }>;\n}\n\nexport default entryResolver;\n"
  },
  {
    "path": "packages/direflow-scripts/src/helpers/getDireflowConfig.ts",
    "content": "import fs from 'fs';\nimport { sep } from 'path';\nimport IDireflowConfig from '../types/DireflowConfig';\n\nconst getDireflowConfig = (indexPath: string) => {\n  try {\n    const paths = indexPath.split(sep);\n    const rootPath = [...paths].slice(0, paths.length - 2).join(sep);\n\n    const config = fs.readFileSync(`${rootPath}/direflow-config.json`, 'utf8');\n\n    if (!config) {\n      throw Error();\n    }\n\n    return JSON.parse(config) as IDireflowConfig;\n  } catch (error) { /* Suppress error */ }\n};\n\nexport default getDireflowConfig;\n"
  },
  {
    "path": "packages/direflow-scripts/src/helpers/messages.ts",
    "content": "import chalk from 'chalk';\n\nexport const interupted = () => `\n  ${chalk.red('Build got interrupted.')}\n  Did you remove the ${chalk.blue('src/component-exports')} file?\n\n  Try building with the command ${chalk.blue('build:lib --verbose')}\n`;\n\nexport const succeeded = () => `\n  ${chalk.greenBright('Succesfully created React component library')}\n\n  The ${chalk.blue('library')} folder can be found at ${chalk.green('/lib')}\n\n  Alter your ${chalk.blue('package.json')} file by adding the field: \n  ${chalk.green('{ \"main\": \"lib/component-exports.js\" }')}\n\n  ${chalk.blueBright('NB:')} If you are using hooks in your React components,\n  you may need to move ${chalk.blue('react')} and ${chalk.blue('react-dom')}\n  to ${chalk.blue('peerDependencies')}:\n  ${chalk.green(\n    `\n  \"peerDependencies\": {\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\"\n  }`,\n  )}\n\n  You may publish the React component library with: ${chalk.blue('npm publish')}\n`;\n"
  },
  {
    "path": "packages/direflow-scripts/src/helpers/writeTsConfig.ts",
    "content": "import { existsSync, writeFileSync } from 'fs';\nimport { resolve } from 'path';\n\nasync function writeTsConfig(srcPath: string) {\n  if (existsSync(resolve(__dirname, '../../tsconfig.lib.json'))) {\n    return;\n  }\n\n  const tsConfig = {\n    extends: `${srcPath}/tsconfig.json`,\n    compilerOptions: {\n      module: 'esnext',\n      noEmit: false,\n      outDir: `${srcPath}/lib`,\n      declaration: true,\n      lib: ['es6', 'dom', 'es2016', 'es2017'],\n    },\n  };\n\n  writeFileSync(resolve(__dirname, '../../tsconfig.lib.json'), JSON.stringify(tsConfig, null, 2));\n}\n\nexport default writeTsConfig;\n"
  },
  {
    "path": "packages/direflow-scripts/src/index.ts",
    "content": "import webpackConfig from './config/config-overrides';\n\nexport { webpackConfig };\n"
  },
  {
    "path": "packages/direflow-scripts/src/template-scripts/entryLoader.ts",
    "content": "const asyncScriptLoader = require('./helpers/asyncScriptLoader.js').default;\n\nconst reactResource: any = '{{reactResource}}';\nconst reactDOMResource: any = '{{reactDOMResource}}';\n\nconst includeReact = async () => {\n  try {\n    if (reactResource !== 'none') {\n      await asyncScriptLoader(reactResource, 'reactBundleLoaded');\n    }\n\n    if (reactDOMResource !== 'none') {\n      await asyncScriptLoader(reactDOMResource, 'reactBundleLoaded');\n    }\n  } catch (error) {\n    console.error(error);\n  }\n};\n\nconst includeIndex = () => {\n  try {\n    require('{{pathIndex}}');\n  } catch (error) {\n    console.warn('File is not found: {{pathIndex}}');\n  }\n};\n\nsetTimeout(async () => {\n  if (process.env.NODE_ENV === 'development'\n      || (window.React && window.ReactDOM)\n      || (reactResource === 'none' && reactDOMResource === 'none')) {\n    includeIndex();\n    return;\n  }\n\n  await includeReact();\n\n  try {\n    await new Promise((resolve, reject) => {\n      let intervalCounts = 0;\n\n      const interval = setInterval(() => {\n        if (intervalCounts >= 2500) {\n          reject(new Error('Direflow Error: React & ReactDOM was unable to load'));\n        }\n\n        if (window.React && window.ReactDOM) {\n          clearInterval(interval);\n          resolve(true);\n        }\n\n        intervalCounts += 1;\n      });\n    });\n\n    includeIndex();\n  } catch (error) {\n    console.error(error);\n  }\n});\n"
  },
  {
    "path": "packages/direflow-scripts/src/template-scripts/welcome.ts",
    "content": "console.log(\n  `\n%cDireflow Components running in development.\n\n%cTo build your components\n%c- Run 'npm run build'\n%c- Your build will be found in %cbuild/direflowBundle.js\n\n%cNeed help?\n%c- Visit: https://direflow.io\n\n`,\n  'color: white; font-size: 16px',\n  'color: #a0abd6; font-size: 16px; font-weight: bold',\n  'color: #ccc; font-size: 16px',\n  'color: #ccc; font-size: 16px',\n  'color: #ccc; font-size: 16px; font-weight: bold',\n  'color: #a0abd6; font-size: 16px; font-weight: bold',\n  'color: #ccc; font-size: 16px',\n);\n"
  },
  {
    "path": "packages/direflow-scripts/src/types/ConfigOverrides.ts",
    "content": "export interface IOptions {\n  filename?: string;\n  chunkFilename?: string;\n  react?: string | boolean;\n  reactDOM?: string | boolean;\n}\n\nexport interface IModule {\n  rules: {\n    oneOf: {\n      test: RegExp;\n      use: string[];\n    }[];\n  }[];\n}\n\nexport interface IOutput {\n  filename: string;\n  chunkFilename: string;\n}\n\nexport interface IOptimization {\n  minimizer: {\n    options: {\n      sourceMap: boolean;\n    };\n  }[];\n  runtimeChunk: boolean;\n  splitChunks: boolean | {\n    cacheGroups: {\n      vendor: {\n        test: RegExp;\n        chunks: string;\n        name: string;\n        enforce: boolean;\n      };\n    };\n  };\n}\n\nexport interface IPlugin {\n  options?: {\n    inject: string;\n  };\n  [key: string]: any;\n}\n\nexport interface IResolve {\n  plugins: unknown[];\n}\n\nexport type TEntry = string[] | { [key: string]: string };\n\nexport type TConfig = {\n  [key: string]: unknown;\n  entry: TEntry;\n  module: IModule;\n  output: IOutput;\n  optimization: IOptimization;\n  plugins: IPlugin[];\n  resolve: IResolve;\n  externals: { [key: string]: any };\n};\n"
  },
  {
    "path": "packages/direflow-scripts/src/types/DireflowConfig.ts",
    "content": "export default interface IDireflowConfig {\n  build?: {\n    componentPath?: string;\n    filename?: string;\n    chunkFilename?: string;\n    emitSourceMap?: boolean;\n    emitIndexHTML?: boolean;\n    emitAll?: boolean;\n    split?: boolean;\n    vendor?: boolean;\n  };\n  modules?: {\n    react?: string;\n    reactDOM?: string;\n  };\n  polyfills?: {\n    sd?: string | boolean;\n    ce?: string | boolean;\n    adapter: string | boolean;\n  };\n}\n"
  },
  {
    "path": "packages/direflow-scripts/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"module\": \"commonjs\",\n    \"lib\": [\"es2019\", \"es2017\", \"es7\", \"es6\", \"dom\"],\n    \"declaration\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"skipLibCheck\": true\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"direflow-jest.config.js\",\n    \"dist\"\n  ]\n}\n"
  },
  {
    "path": "packages/direflow-scripts/webpack.config.js",
    "content": "/* eslint-disable @typescript-eslint/camelcase */\n/* eslint-disable @typescript-eslint/no-var-requires */\nconst { resolve } = require('path');\nconst { existsSync } = require('fs');\nconst { EnvironmentPlugin } = require('webpack');\nconst TerserPlugin = require('terser-webpack-plugin');\n\nconst srcPath = process.cwd();\n\nconst indexJsPath = `${srcPath}/src/component-exports.js`;\nconst indexTsPath = `${srcPath}/src/component-exports.ts`;\n\nconst existsIndexJs = existsSync(indexJsPath);\nconst existsIndexTs = existsSync(indexTsPath);\n\nif (!existsIndexJs && !existsIndexTs) {\n  throw Error('No component-exports.js or component-exports.ts file found');\n}\n\nconst entryPath = existsIndexJs ? indexJsPath : indexTsPath;\n\nconst jsLoader = () => {\n  if (!existsIndexJs) {\n    return {};\n  }\n\n  return {\n    test: /\\.(js|jsx)$/,\n    exclude: /node_modules/,\n    use: {\n      loader: 'babel-loader',\n      options: {\n        presets: ['@babel/preset-env', '@babel/preset-react'],\n      },\n    },\n  };\n};\n\nconst tsLoder = () => {\n  if (!existsIndexTs) {\n    return {};\n  }\n\n  const writeTsConfig = require('./dist/helpers/writeTsConfig').default;\n  writeTsConfig(srcPath);\n\n  return {\n    test: /\\.tsx?$/,\n    loader: 'ts-loader',\n    options: {\n      configFile: resolve(__dirname, './tsconfig.lib.json'),\n    },\n  };\n};\n\nmodule.exports = {\n  mode: 'production',\n  devtool: 'none',\n  entry: entryPath,\n  resolve: {\n    extensions: ['.ts', '.tsx', '.js', '.css', '.scss'],\n    alias: {\n      react: resolve('../react'),\n      reactDOM: resolve('../reactDOM'),\n    },\n  },\n  output: {\n    path: `${srcPath}/lib`,\n    filename: 'component-exports.js',\n    library: 'direflow-library',\n    libraryTarget: 'commonjs2',\n    hashFunction: 'xxhash64',\n  },\n  optimization: {\n    minimizer: [\n      new TerserPlugin({\n        terserOptions: {\n          ecma: 5,\n          warnings: false,\n          parse: {},\n          compress: {\n            toplevel: true,\n            unused: true,\n            dead_code: true,\n            drop_console: true,\n          },\n          mangle: true,\n          module: true,\n          output: null,\n          toplevel: false,\n          nameCache: null,\n          ie8: false,\n          keep_classnames: undefined,\n          keep_fnames: false,\n          safari10: false,\n        },\n      }),\n    ],\n    moduleIds: 'hashed',\n    runtimeChunk: false,\n  },\n  module: {\n    rules: [\n      {\n        ...jsLoader(),\n      },\n      {\n        ...tsLoder(),\n      },\n      {\n        test: /\\.css$/,\n        use: [\n          {\n            loader: 'to-string-loader',\n          },\n          {\n            loader: 'css-loader',\n          },\n        ],\n      },\n      {\n        test: /\\.scss$/,\n        use: [\n          {\n            loader: 'to-string-loader',\n          },\n          {\n            loader: 'css-loader',\n          },\n          {\n            loader: 'sass-loader',\n          },\n        ],\n      },\n      {\n        test: /\\.svg$/,\n        use: ['@svgr/webpack'],\n      },\n    ],\n  },\n  plugins: [new EnvironmentPlugin({ NODE_ENV: 'production' })],\n  externals: {\n    'react': 'commonjs react',\n    'react-dom': 'commonjs react-dom',\n  },\n\n};\n"
  },
  {
    "path": "scripts/bash/setupLocal.sh",
    "content": "npm -g remove direflow-cli\nnpm run update-version link\nnpm link\nnpm run build:full\n"
  },
  {
    "path": "scripts/bash/startIntegrationTest.sh",
    "content": "# Install\ninstall() {\n  node ./scripts/node/installAll.js --test-setup\n\n  cd cypress/test-setup\n}\n\n# Build\nbuild() {\n  npm run build\n\n  # Replace with pm2 and kill by id, not by port\n  npm run serve &\n  wait-on http://localhost:5000\n}\n\n# CleanUp\ncleanup() {\n  echo \"Cypress has finished testing\"\n  echo \"Closing dev server ...\"\n\n  kill $(lsof -t -i:5000)\n}\n\ninstall\nbuild\n\ncd .. && cd ..\n\nif npm run cypress:run; then\n  cleanup\n  exit 0\nelse\n  cleanup\n  exit 1\nfi\n"
  },
  {
    "path": "scripts/node/buildAll.js",
    "content": "const fs = require('fs');\nconst { exec } = require('child_process');\n\nbuild('.');\n\nif (!fs.existsSync('packages')) {\n  return;\n}\n\nconst widgetsDirectory = fs.readdirSync('packages');\n\n// eslint-disable-next-line no-restricted-syntax\nfor (const directory of widgetsDirectory) {\n  if (fs.statSync(`packages/${directory}`).isDirectory()) {\n    build(`packages/${directory}`);\n  }\n}\n\nfunction build(dir) {\n  console.log('Beginning to build:', dir);\n\n  exec(`cd ${dir} && npm run build`, (err) => {\n    if (err) {\n      console.log(`✗ ${dir} could not build`);\n      console.log(err);\n      return;\n    }\n\n    console.log(`✓ ${dir} build succesfully`);\n  });\n}\n"
  },
  {
    "path": "scripts/node/cleanupAll.js",
    "content": "const fs = require('fs');\nconst { exec } = require('child_process');\n\nif (process.argv[2] === '--modules') {\n  if (fs.existsSync('packages/direflow-component/node_modules')) {\n    exec('rm -rf packages/direflow-component/node_modules', (err) => {\n      if (err) {\n        console.log('✗ packages/direflow-component/node_modules FAILED to remove');\n        console.log(err);\n        return;\n      }\n\n      console.log('✓ packages/direflow-component/node_modules is REMOVED');\n    });\n  }\n\n  return;\n}\n\ncleanDeps('.');\n\nif (!fs.existsSync('packages')) {\n  return;\n}\n\nconst widgetsDirectory = fs.readdirSync('packages');\n\n// eslint-disable-next-line no-restricted-syntax\nfor (const directory of widgetsDirectory) {\n  if (fs.statSync(`packages/${directory}`).isDirectory()) {\n    cleanDeps(`packages/${directory}`);\n  }\n}\n\nif (!fs.existsSync('cypress/test-setup')) {\n  return;\n}\n\nif (!fs.statSync('cypress/test-setup').isDirectory()) {\n  return;\n}\n\ncleanDeps('cypress/test-setup');\n\nfunction cleanDeps(dir) {\n  console.log('Beginning to clean:', dir);\n\n  if (fs.existsSync(`${dir}/node_modules`)) {\n    exec(`rm -rf ${dir}/node_modules`, (err) => {\n      if (err) {\n        console.log(`✗ ${dir}/node_modules FAILED to remove`);\n        console.log(err);\n        return;\n      }\n\n      console.log(`✓ ${dir}/node_modules is REMOVED`);\n    });\n  }\n\n  if (fs.existsSync(`${dir}/npm yarn.lock`)) {\n    exec(`rm ${dir}/npm yarn.lock`, (err) => {\n      if (err) {\n        console.log(`✗ ${dir}/npm yarn.lock FAILED to remove`);\n        console.log(err);\n        return;\n      }\n\n      console.log(`✓ ${dir}/npm yarn.lock is REMOVED`);\n    });\n  }\n\n  if (fs.existsSync(`${dir}/tsconfig.lib.json`)) {\n    exec(`rm ${dir}/tsconfig.lib.json`, (err) => {\n      if (err) {\n        console.log(`✗ ${dir}/tsconfig.lib.json FAILED to remove`);\n        console.log(err);\n        return;\n      }\n\n      console.log(`✓ ${dir}/tsconfig.lib.json is REMOVED`);\n    });\n  }\n\n  if (fs.existsSync(`${dir}/dist`)) {\n    exec(`rm -rf ${dir}/dist`, (err) => {\n      if (err) {\n        console.log(`✗ ${dir}/dist FAILED to remove`);\n        console.log(err);\n        return;\n      }\n\n      console.log(`✓ ${dir}/dist is REMOVED`);\n    });\n  }\n}\n"
  },
  {
    "path": "scripts/node/installAll.js",
    "content": "const fs = require('fs');\nconst { exec, execSync } = require('child_process');\n\nasync function installAll() {\n  await install('.');\n\n  if (!fs.existsSync('packages')) {\n    return;\n  }\n\n  const widgetsDirectory = fs.readdirSync('packages');\n\n  // eslint-disable-next-line no-restricted-syntax\n  for (const directory of widgetsDirectory) {\n    if (fs.statSync(`packages/${directory}`).isDirectory()) {\n      // eslint-disable-next-line no-await-in-loop\n      await install(`packages/${directory}`);\n    }\n  }\n}\n\nfunction installTestSetup() {\n  if (!fs.existsSync('cypress/test-setup')) {\n    return;\n  }\n\n  if (!fs.statSync('cypress/test-setup').isDirectory()) {\n    return;\n  }\n\n  install('cypress/test-setup');\n}\n\nfunction install(dir) {\n  return new Promise(async (resolve, reject) => {\n    console.log('Beginning to install: ', dir);\n\n    await new Promise((subResolve) => {\n      exec(`cd ${dir} && npm install`, (err) => {\n        if (err) {\n          console.log(`✗ ${dir} could not install`);\n          console.log(err);\n          reject();\n        }\n\n        console.log(`✓ ${dir} installed succesfully`);\n        subResolve();\n      });\n    });\n\n    if (process.argv[2] === '--no-deps') {\n      resolve();\n      return;\n    }\n\n    const packageJson = JSON.parse(fs.readFileSync(`${dir}/package.json`));\n    const peerDeps = packageJson.peerDependencies;\n\n    if (peerDeps) {\n      // eslint-disable-next-line no-restricted-syntax\n      for (const [package, version] of Object.entries(peerDeps)) {\n        execSync(`cd ${dir} && npm install ${package}@${version}`);\n        console.log(`✓ ${package}@${version} peer dependency installed succesfully`);\n      }\n\n      fs.writeFileSync(`${dir}/package.json`, JSON.stringify(packageJson, null, 2), 'utf-8');\n    }\n\n    resolve();\n  });\n}\n\nif (process.argv[2] === '--test-setup') {\n  installTestSetup();\n} else {\n  installAll();\n}\n"
  },
  {
    "path": "scripts/node/updateVersion.js",
    "content": "const fs = require('fs');\nconst { execSync } = require('child_process');\nconst path = require('path');\n\nconst arg = process.argv[2];\n\nif (!arg) {\n  console.log('Provide a version number');\n  return;\n}\n\nconst rootPackage = require('../../package.json');\nconst componentPackage = require('../../packages/direflow-component/package.json');\nconst scriptPackage = require('../../packages/direflow-scripts/package.json');\n\nlet componentPackageJs = fs.readFileSync('templates/js/package.json').toString();\nlet componentPackageTs = fs.readFileSync('templates/ts/package.json').toString();\n\nconst componentRegex = /\"direflow-component\": \"(.*)\"/g;\nconst componentReplace = (r) => `\"direflow-component\": ${JSON.stringify(r)}`;\n\nconst scriptsRegex = /\"direflow-scripts\": \"(.*)\"/g;\nconst scriptsReplace = (r) => `\"direflow-scripts\": ${JSON.stringify(r)}`;\n\nconst updateLink = () => {\n  const currentDirectory = process.cwd();\n\n  if (!rootPackage.version.includes('-link')) {\n    rootPackage.version = `${rootPackage.version}-link`;\n  }\n\n  if (!componentPackage.version.includes('-link')) {\n    componentPackage.version = `${componentPackage.version}-link`;\n  }\n\n  if (!scriptPackage.version.includes('-link')) {\n    scriptPackage.version = `${scriptPackage.version}-link`;\n  }\n\n  const componentPath = path.join(currentDirectory, 'packages', 'direflow-component');\n  const scriptsPath = path.join(currentDirectory, 'packages', 'direflow-scripts');\n\n  componentPackageJs = componentPackageJs\n    .replace(componentRegex, componentReplace(componentPath))\n    .replace(scriptsRegex, scriptsReplace(scriptsPath));\n\n  componentPackageTs = componentPackageTs\n    .replace(componentRegex, componentReplace(componentPath))\n    .replace(scriptsRegex, scriptsReplace(scriptsPath));\n\n  console.log('');\n  console.log('Version have been set to use LINK.');\n  console.log(`New version: ${rootPackage.version}`);\n  console.log('');\n};\n\nconst updateVersion = (version) => {\n  rootPackage.version = version;\n  componentPackage.version = version;\n  scriptPackage.version = version;\n\n  componentPackageJs = componentPackageJs\n    .replace(componentRegex, componentReplace(version))\n    .replace(scriptsRegex, scriptsReplace(version));\n\n  componentPackageTs = componentPackageTs\n    .replace(componentRegex, componentReplace(version))\n    .replace(scriptsRegex, scriptsReplace(version));\n\n  console.log('');\n  console.log('Version have updated.');\n  console.log(`New version: ${version}`);\n  console.log('');\n};\n\nconst writeToFiles = () => {\n  fs.writeFileSync('package.json', JSON.stringify(rootPackage, null, 2), 'utf-8');\n  fs.writeFileSync('packages/direflow-component/package.json', JSON.stringify(componentPackage, null, 2), 'utf-8');\n  fs.writeFileSync('packages/direflow-scripts/package.json', JSON.stringify(scriptPackage, null, 2), 'utf-8');\n  fs.writeFileSync('templates/js/package.json', componentPackageJs, 'utf-8');\n  fs.writeFileSync('templates/ts/package.json', componentPackageTs, 'utf-8');\n};\n\nif (arg === 'patch') {\n  const buffer = execSync('npm view direflow-cli version');\n  const currentVersion = buffer.toString('utf8');\n\n  if (\n    currentVersion.trim() === rootPackage.version.trim()\n    || rootPackage.version.includes('link')\n  ) {\n    const versionNumbers = currentVersion.split('.');\n    const patch = Number(versionNumbers[2]);\n\n    const patchVersion = `${versionNumbers[0]}.${versionNumbers[1]}.${patch + 1}`;\n\n    updateVersion(patchVersion);\n    writeToFiles();\n  }\n\n  return;\n}\n\nif (arg === 'link') {\n  updateLink();\n  writeToFiles();\n  return;\n}\n\nupdateVersion(arg);\nwriteToFiles();\n"
  },
  {
    "path": "templates/js/.eslintrc",
    "content": "{\n  \"env\": {\n      \"browser\": true,\n      \"es6\": true,\n      \"node\": true\n  },\n  \"settings\": {\n      \"pragma\": \"React\",\n      \"version\": \"detect\"\n  },\n  \"extends\": [\n      \"eslint:recommended\",\n      \"plugin:react/recommended\"\n  ],\n  \"globals\": {\n      \"Atomics\": \"readonly\",\n      \"SharedArrayBuffer\": \"readonly\"\n  },\n  \"parserOptions\": {\n      \"ecmaFeatures\": {\n          \"jsx\": true\n      },\n      \"ecmaVersion\": 2018,\n      \"sourceType\": \"module\"\n  },\n  \"plugins\": [\n      \"react\"\n  ],\n  \"rules\": {\n  }\n}"
  },
  {
    "path": "templates/js/README.md",
    "content": "This component was bootstrapped with [Direflow](https://direflow.io).\n\n# {{names.title}}\n> {{defaultDescription}}\n\n```html\n<{{names.snake}}></{{names.snake}}>\n```\n\nUse this README to describe your Direflow Component"
  },
  {
    "path": "templates/js/direflow-config.json",
    "content": "{\n  \"build\": {\n    \"componentPath\": \"direflow-components\",\n    \"filename\": \"direflowBundle.js\"\n  }\n}\n"
  },
  {
    "path": "templates/js/direflow-webpack.js",
    "content": "const { webpackConfig } = require('direflow-scripts');\n\n/**\n * Webpack configuration for Direflow Component\n * Additional webpack plugins / overrides can be provided here\n */\nmodule.exports = (config, env) => ({\n  ...webpackConfig(config, env),\n  // Add your own webpack config here (optional)\n});\n"
  },
  {
    "path": "templates/js/package.json",
    "content": "{\n  \"name\": \"{{names.snake}}\",\n  \"description\": \"{{defaultDescription}}\",\n  \"version\": \"1.0.0\",\n  {{#if npmModule}}\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"direflow\",\n    \"react\",\n    \"webcomponent\"\n  ],\n  \"homepage\": \"https://direflow.io/\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Silind-Software/direflow\"\n  },\n  \"bugs\": {\n    \"email\": \"direflow@silind.com\",\n    \"url\": \"https://github.com/Silind-Software/direflow/issues/new\"\n  },\n  \"main\": \"build/direflowBundle.js\",\n  \"files\": [\n    \"build\"\n  ],\n  {{else}}\n  \"private\": true,\n  {{/if}}\n  \"scripts\": {\n    \"start\": \"direflow-scripts start\",\n    \"build\": \"direflow-scripts build\",\n    \"build:lib\": \"direflow-scripts build:lib\",\n    \"test\": \"direflow-scripts test\"\n  },\n  \"dependencies\": {\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-scripts\": \"^4.0.3\",\n    \"direflow-component\": \"4.0.0\",\n    \"direflow-scripts\": \"4.0.0\"\n  },\n  \"devDependencies\": {\n    \"eslint-plugin-node\": \"^11.0.0\",\n    \"eslint-plugin-promise\": \"^4.2.1\",\n    \"eslint-plugin-react\": \"^7.18.0\",\n    \"to-string-loader\": \"^1.1.6\",\n    \"jest-environment-jsdom-fourteen\": \"0.1.0\",\n    \"react-app-rewired\": \"2.1.3\",\n    \"react-test-renderer\": \"16.9.0\",\n    \"webpack-cli\": \"^3.3.11\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"react-app\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"jest\": {\n    \"setupFilesAfterEnv\": [\n      \"direflow-scripts/direflow-jest.config.js\"\n    ]\n  },\n  \"config-overrides-path\": \"direflow-webpack.js\"\n}\n"
  },
  {
    "path": "templates/js/public/index.css",
    "content": "body {\n  padding: 0;\n  margin: 0;\n  width: 100vw;\n  padding-top: 150px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background-color: #F6FAFA;\n}"
  },
  {
    "path": "templates/js/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"index.css\">\n    <title>{{names.title}}</title>\n  </head>\n  <body>\n    <{{names.snake}}></{{names.snake}}>\n  </body>\n</html>"
  },
  {
    "path": "templates/js/src/component-exports.js",
    "content": "/**\n * In this file you can export components that will\n * be build as a pure React component library.\n * \n * Using the command `npm run build:lib` will\n * produce a folder `lib` with your React components.\n *\n * If you're not using a React component library,\n * this file can be safely deleted.\n */\n\nimport App from './direflow-components/{{names.snake}}/App';\n\nexport { \n  App \n};\n"
  },
  {
    "path": "templates/js/src/direflow-components/direflow-component/App.css",
    "content": ".app {\n  width: 400px;\n  height: 575px;\n  padding: 30px 60px;\n  box-sizing: border-box;\n  background-color: white;\n  box-shadow: 0 4px 14px 4px #375c821c;\n  font-family: 'Noto Sans JP', sans-serif;\n  border-bottom: 5px solid #cad5e6;\n}\n\n.top {\n  width: 100%;\n  height: 50%;\n  border-bottom: 2px solid #7998c7;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n.bottom {\n  width: 100%;\n  height: 50%;\n  border-top: 2px solid #7998c7;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-around;\n  align-items: center;\n}\n\n.header-image {\n  width: 165px;\n  height: 165px;\n  background: url('https://silind-s3.s3.eu-west-2.amazonaws.com/direflow/logo.svg');\n  background-size: contain;\n}\n\n.header-title {\n  font-size: 34px;\n  color: #5781C2;\n  font-family: 'Advent Pro', sans-serif;\n}\n\n.sample-text {\n  font-family: 'Noto Sans JP', sans-serif;\n  font-size: 16px;\n  color: #666;\n  text-align: center;\n}\n\n.button {\n  width: 150px;\n  height: 45px;\n  font-family: 'Noto Sans JP', sans-serif;\n  font-size: 20px;\n  font-weight: bold;\n  background-color: #5781C2;\n  color: white;\n  box-shadow: 2px 2px 5px #16314d98;\n  outline: none;\n  border: 0;\n  cursor: pointer;\n  transition: 0.3s;\n}\n\n.button:hover {\n  box-shadow: 4px 4px 8px #16314d63;\n  background-color: #40558f;\n}\n"
  },
  {
    "path": "templates/js/src/direflow-components/direflow-component/App.js",
    "content": "import React, { useContext } from 'react';\nimport PropTypes from 'prop-types';\nimport { EventContext, Styled } from 'direflow-component';\nimport styles from './App.css';\n\nconst App = (props) => {\n  const dispatch = useContext(EventContext);\n\n  const handleClick = () => {\n    const event = new Event('my-event');\n    dispatch(event);\n  };\n\n  const renderSampleList = props.sampleList.map((sample) => (\n    <div key={sample} className='sample-text'>\n      → {sample}\n    </div>\n  ));\n\n  return (\n    <Styled styles={styles}>\n      <div className='app'>\n        <div className='top'>\n          <div className='header-image' />\n        </div>\n        <div className='bottom'>\n          <div className='header-title'>{props.componentTitle}</div>\n          <div>{renderSampleList}</div>\n          <button className='button' onClick={handleClick}>\n            Click me!\n          </button>\n        </div>\n      </div>\n    </Styled>\n  );\n};\n\nApp.defaultProps = {\n  componentTitle: '{{names.title}}',\n  sampleList: [\n    'Create with React',\n    'Build as Web Component',\n    'Use it anywhere!',\n  ],\n}\n\nApp.propTypes = {\n  componentTitle: PropTypes.string,\n  sampleList: PropTypes.array,\n};\n\nexport default App;\n"
  },
  {
    "path": "templates/js/src/direflow-components/direflow-component/index.js",
    "content": "import { DireflowComponent } from 'direflow-component';\nimport App from './App';\n\nexport default DireflowComponent.create({\n  component: App,\n  configuration: {\n    tagname: '{{names.snake}}',\n  },\n  plugins: [\n    {\n      name: 'font-loader',\n      options: {\n        google: {\n          families: ['Advent Pro', 'Noto Sans JP'],\n        },\n      },\n    },\n  ],\n});\n"
  },
  {
    "path": "templates/js/src/direflow-components/direflow-component/test/App.test.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport renderer from 'react-test-renderer';\nimport App from '../App';\n\nconst reactProps = {\n  componentTitle: 'Component Test',\n  sampleList: ['Mock', 'Test', 'Data'],\n};\n\nit('renders without crashing', () => {\n  const div = document.createElement('div');\n  ReactDOM.render(<App {...reactProps} />, div);\n  ReactDOM.unmountComponentAtNode(div);\n});\n\nit('matches snapshot as expected', () => {\n  const renderTree = renderer.create(<App {...reactProps} />).toJSON();\n  expect(renderTree).toMatchSnapshot();\n});\n"
  },
  {
    "path": "templates/js/src/index.js",
    "content": "/**\n * This is the entry file of the Direflow setup.\n *\n * You can add any additional functionality here.\n * For example, this is a good place to hook into your\n * Web Component once it's mounted on the DOM.\n *\n * !This file cannot be removed.\n * It can be left blank if not needed.\n */\n\nimport {{names.pascal}} from './direflow-components/{{names.snake}}';\n\n{{names.pascal}}.then((element) => {\n\n  /**\n   * Access DOM node when it's mounted\n   */\n  console.log('{{names.snake}} is mounted on the DOM', element);\n});\n"
  },
  {
    "path": "templates/ts/.eslintrc",
    "content": "{\n  \"env\": {\n    \"browser\": true,\n    \"es6\": true,\n    \"node\": true\n  },\n  \"settings\": {\n    \"pragma\": \"React\",\n    \"version\": \"detect\"\n  },\n  \"extends\": [\n    \"eslint:recommended\",\n    \"plugin:react/recommended\",\n    \"plugin:@typescript-eslint/eslint-recommended\",\n    \"plugin:@typescript-eslint/recommended\"\n  ],\n  \"globals\": {\n    \"Atomics\": \"readonly\",\n    \"SharedArrayBuffer\": \"readonly\"\n  },\n  \"parser\": \"@typescript-eslint/parser\",\n  \"parserOptions\": {\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    },\n    \"ecmaVersion\": 2018,\n    \"sourceType\": \"module\"\n  },\n  \"plugins\": [\"react\", \"@typescript-eslint\"],\n  \"rules\": {\n    \"react/prop-types\": \"off\",\n    \"interface-name-prefix\": \"off\",\n    \"@typescript-eslint/explicit-function-return-type\": \"off\",\n    \"@typescript-eslint/interface-name-prefix\": \"off\",\n    \"@typescript-eslint/no-var-requires\": \"off\"\n  }\n}\n"
  },
  {
    "path": "templates/ts/README.md",
    "content": "This component was bootstrapped with [Direflow](https://direflow.io).\n\n# {{names.title}}\n> {{defaultDescription}}\n\n```html\n<{{names.snake}}></{{names.snake}}>\n```\n\nUse this README to describe your Direflow Component"
  },
  {
    "path": "templates/ts/direflow-config.json",
    "content": "{\n  \"build\": {\n    \"componentPath\": \"direflow-components\",\n    \"filename\": \"direflowBundle.js\"\n  }\n}\n"
  },
  {
    "path": "templates/ts/direflow-webpack.js",
    "content": "const { webpackConfig } = require('direflow-scripts');\n\n/**\n * Webpack configuration for Direflow Component\n * Additional webpack plugins / overrides can be provided here\n */\nmodule.exports = (config, env) => ({\n  ...webpackConfig(config, env),\n  // Add your own webpack config here (optional)\n});\n"
  },
  {
    "path": "templates/ts/package.json",
    "content": "{\n  \"name\": \"{{names.snake}}\",\n  \"description\": \"{{defaultDescription}}\",\n  \"version\": \"1.0.0\",\n  {{#if npmModule}}\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"direflow\",\n    \"react\",\n    \"webcomponent\"\n  ],\n  \"homepage\": \"https://direflow.io/\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Silind-Software/direflow\"\n  },\n  \"bugs\": {\n    \"email\": \"direflow@silind.com\",\n    \"url\": \"https://github.com/Silind-Software/direflow/issues/new\"\n  },\n  \"main\": \"build/direflowBundle.js\",\n  \"files\": [\n    \"build\"\n  ],\n  {{else}}\n  \"private\": true,\n  {{/if}}\n  \"scripts\": {\n    \"start\": \"direflow-scripts start\",\n    \"build\": \"direflow-scripts build\",\n    \"build:lib\": \"direflow-scripts build:lib\",\n    \"test\": \"direflow-scripts test\"\n  },\n  \"dependencies\": {\n    \"@types/node\": \"^16.11.7\",\n    \"@types/react\": \"17.0.2\",\n    \"@types/react-dom\": \"17.0.2\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-lib-adler32\": \"^1.0.3\",\n    \"react-scripts\": \"^4.0.3\",\n    \"direflow-component\": \"4.0.0\",\n    \"direflow-scripts\": \"4.0.0\",\n    \"webfontloader\": \"^1.6.28\"\n  },\n  \"devDependencies\": {\n    {{#if eslint}}\n    \"@typescript-eslint/eslint-plugin\": \"^5.27.0\",\n    \"@typescript-eslint/parser\": \"^5.27.0\",\n    \"eslint-plugin-node\": \"^11.1.0\",\n    \"eslint-plugin-promise\": \"^6.0.0\",\n    \"eslint-plugin-react\": \"^7.30.0\",\n    {{/if}}\n    \"@types/jest\": \"24.0.18\",\n    \"@types/react-test-renderer\": \"16.9.1\",\n    \"jest-environment-jsdom\": \"28.1.0\",\n    \"react-app-rewired\": \"2.2.1\",\n    \"react-test-renderer\": \"17.0.2\",\n    \"to-string-loader\": \"^1.2.0\",\n    {{#if tslint}}\n    \"tslint-react\": \"^5.0.0\",\n    \"tslint\": \"6.1.3\",\n    {{/if}}\n    \"typescript\": \"^4.7.3\",\n    \"webpack-cli\": \"^4.9.2\",\n    \"ts-loader\": \"^9.3.0\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"react-app\"\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"jest\": {\n    \"setupFilesAfterEnv\": [\n      \"direflow-scripts/direflow-jest.config.js\"\n    ]\n  },\n  \"config-overrides-path\": \"direflow-webpack.js\"\n}\n"
  },
  {
    "path": "templates/ts/public/index.css",
    "content": "body {\n  padding: 0;\n  margin: 0;\n  width: 100vw;\n  padding-top: 150px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background-color: #F6FAFA;\n}"
  },
  {
    "path": "templates/ts/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"index.css\">\n    <title>{{names.title}}</title>\n  </head>\n  <body>\n    <{{names.snake}}></{{names.snake}}>\n  </body>\n</html>"
  },
  {
    "path": "templates/ts/src/component-exports.ts",
    "content": "/**\n * In this file you can export components that will\n * be built as a pure React component library.\n * \n * Using the command `npm run build:lib` will\n * produce a folder `lib` with your React components.\n *\n * If you're not using a React component library,\n * this file can be safely deleted.\n */\n\nimport App from './direflow-components/{{names.snake}}/App';\n\nexport { \n  App \n};\n"
  },
  {
    "path": "templates/ts/src/direflow-components/direflow-component/App.css",
    "content": ".app {\n  width: 400px;\n  height: 575px;\n  padding: 30px 60px;\n  box-sizing: border-box;\n  background-color: white;\n  box-shadow: 0 4px 14px 4px #375c821c;\n  font-family: 'Noto Sans JP', sans-serif;\n  border-bottom: 5px solid #cad5e6;\n}\n\n.top {\n  width: 100%;\n  height: 50%;\n  border-bottom: 2px solid #7998c7;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n.bottom {\n  width: 100%;\n  height: 50%;\n  border-top: 2px solid #7998c7;\n  display: flex;\n  flex-direction: column;\n  justify-content: space-around;\n  align-items: center;\n}\n\n.header-image {\n  width: 165px;\n  height: 165px;\n  background: url('https://silind-s3.s3.eu-west-2.amazonaws.com/direflow/logo.svg');\n  background-size: contain;\n}\n\n.header-title {\n  font-size: 34px;\n  color: #5781C2;\n  font-family: 'Advent Pro', sans-serif;\n}\n\n.sample-text {\n  font-family: 'Noto Sans JP', sans-serif;\n  font-size: 16px;\n  color: #666;\n  text-align: center;\n}\n\n.button {\n  width: 150px;\n  height: 45px;\n  font-family: 'Noto Sans JP', sans-serif;\n  font-size: 20px;\n  font-weight: bold;\n  background-color: #5781C2;\n  color: white;\n  box-shadow: 2px 2px 5px #16314d98;\n  outline: none;\n  border: 0;\n  cursor: pointer;\n  transition: 0.3s;\n}\n\n.button:hover {\n  box-shadow: 4px 4px 8px #16314d63;\n  background-color: #40558f;\n}\n"
  },
  {
    "path": "templates/ts/src/direflow-components/direflow-component/App.tsx",
    "content": "import React, { FC, useContext } from 'react';\nimport { EventContext, Styled } from 'direflow-component';\nimport styles from './App.css';\n\ninterface IProps {\n  componentTitle: string;\n  sampleList: string[];\n}\n\nconst App: FC<IProps> = (props) => {\n  const dispatch = useContext(EventContext);\n\n  const handleClick = () => {\n    const event = new Event('my-event');\n    dispatch(event);\n  };\n\n  const renderSampleList = props.sampleList.map((sample: string) => (\n    <div key={sample} className='sample-text'>\n      → {sample}\n    </div>\n  ));\n\n  return (\n    <Styled styles={styles}>\n      <div className='app'>\n        <div className='top'>\n          <div className='header-image' />\n        </div>\n        <div className='bottom'>\n          <div className='header-title'>{props.componentTitle}</div>\n          <div>{renderSampleList}</div>\n          <button className='button' onClick={handleClick}>\n            Click me!\n          </button>\n        </div>\n      </div>\n    </Styled>\n  );\n};\n\nApp.defaultProps = {\n  componentTitle: '{{names.title}}',\n  sampleList: [\n    'Create with React',\n    'Build as Web Component',\n    'Use it anywhere!',\n  ],\n}\n\nexport default App;\n"
  },
  {
    "path": "templates/ts/src/direflow-components/direflow-component/index.tsx",
    "content": "import { DireflowComponent } from 'direflow-component';\nimport App from './App';\n\nexport default DireflowComponent.create({\n  component: App,\n  configuration: {\n    tagname: '{{names.snake}}',\n  },\n  plugins: [\n    {\n      name: 'font-loader',\n      options: {\n        google: {\n          families: ['Advent Pro', 'Noto Sans JP'],\n        },\n      },\n    },\n  ],\n});\n"
  },
  {
    "path": "templates/ts/src/direflow-components/direflow-component/test/App.test.tsx",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport renderer from 'react-test-renderer';\nimport App from '../App';\n\nconst reactProps = {\n  componentTitle: 'Component Test',\n  sampleList: ['Mock', 'Test', 'Data'],\n};\n\nit('renders without crashing', () => {\n  const div = document.createElement('div');\n  ReactDOM.render(<App {...reactProps} />, div);\n  ReactDOM.unmountComponentAtNode(div);\n});\n\nit('matches snapshot as expected', () => {\n  const renderTree = renderer.create(<App {...reactProps} />).toJSON();\n  expect(renderTree).toMatchSnapshot();\n});\n"
  },
  {
    "path": "templates/ts/src/index.tsx",
    "content": "/**\n * This is the entry file of the Direflow setup.\n *\n * You can add any additional functionality here.\n * For example, this is a good place to hook into your\n * Web Component once it's mounted on the DOM.\n *\n * !This file cannot be removed.\n * It can be left blank if not needed.\n */\n\nimport {{names.pascal}} from './direflow-components/{{names.snake}}';\n\n{{names.pascal}}.then((element) => {\n\n  /**\n   * Access DOM node when it's mounted\n   */\n  console.log('{{names.snake}} is mounted on the DOM', element);\n});\n"
  },
  {
    "path": "templates/ts/src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n\ndeclare module '*.css' {\n  export default style as string\n}\n\ndeclare module '*.scss' {\n  export default style as string\n}\n\ndeclare module '*.sass' {\n  export default style as string\n}\n\ndeclare module '*.svg' {\n  import * as React from 'react';\n\n  export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;\n\n  const src: string;\n  export default src;\n}\n\ndeclare namespace JSX {\n  interface IntrinsicElements {\n    'slot';\n  }\n}\n"
  },
  {
    "path": "templates/ts/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\"\n    ],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"noEmit\": true,\n    \"jsx\": \"react\",\n    \"isolatedModules\": true\n  },\n  \"include\": [\n    \"src\"\n  ],\n  \"exclude\": [\n    \"node_modules\",\n    \"dist\"\n  ]\n}\n"
  },
  {
    "path": "templates/ts/tslint.json",
    "content": "{\n  \"rules\": {\n    \"max-line-length\": { \"options\": [120], \"severity\": \"warning\" },\n    \"no-lowlevel-commenting\": { \"severity\": \"warning\" },\n    \"discreet-ternary\": { \"severity\": \"warning\" },\n    \"curly\": { \"severity\": \"warning\" },\n    \"jsx-wrap-multiline\": false,\n    \"typedef\": false\n  },\n  \"linterOptions\": {\n    \"exclude\": [\n      \"config/**/*.js\",\n      \"node_modules/**/*.ts\",\n      \"coverage/lcov-report/*.js\",\n      \"webpack.config.js\"\n    ]\n  },\n  \"extends\": [\"tslint:recommended\", \"tslint-react\", \"tslint-config-airbnb\"]\n}\n"
  },
  {
    "path": "test/detectDireflowSetup.test.ts",
    "content": "import { fs, vol } from 'memfs';\nimport isDireflowSetup from '../cli/helpers/detectDireflowSetup';\n\njest.mock('fs', () => fs);\n\nconst isSetupFilePath = '/path/to/mock/setup';\nconst isNotSetupFilePath = '/path/to/mock/non-setup';\n\nconst mockFsJson = {\n  [`${isSetupFilePath}/direflow-webpack.js`]: '',\n  [`${isNotSetupFilePath}/foo`]: '',\n};\nvol.fromJSON(mockFsJson);\n\ndescribe('Detect Direflow Setup', () => {\n  afterAll(() => {\n    vol.reset();\n  });\n\n  it('should return true if Direflow Setup', () => {\n    const isSetup = isDireflowSetup(isSetupFilePath);\n    expect(isSetup).toBeTruthy();\n  });\n\n  it('should return false if not Direflow Setup', () => {\n    const isSetup = isDireflowSetup(isNotSetupFilePath);\n    expect(isSetup).toBeFalsy();\n  });\n});\n"
  },
  {
    "path": "test/domController.test.ts",
    "content": "import { JSDOM } from 'jsdom';\nimport {\n  injectIntoShadowRoot,\n  injectIntoHead,\n  stripStyleFromHead,\n  existsIdenticalElement,\n} from '../packages/direflow-component/src/helpers/domControllers';\n\nconst dom = new JSDOM();\n(global as any).document = dom.window.document;\n(global as any).window = dom.window;\n\nconst webComponent = document.createElement('shadow-web-component');\nconst webComponentNoShadow = document.createElement('no-shadow-web-component');\nconst appElement = document.createElement('div');\nwebComponent.attachShadow({ mode: 'open' });\nwebComponent.shadowRoot?.append(appElement);\n\nconst linkElement = document.createElement('link');\nlinkElement.rel = 'shortcut icon';\nlinkElement.type = 'image/x-icon';\nlinkElement.href = 'https://some-test-url.jest';\n\nappElement.id = 'app';\nappElement.append(document.createElement('style'));\nappElement.append(document.createElement('script'));\n\nappElement.append(linkElement);\n\ndescribe('Inject into Shadow Root', () => {\n  it('should correctly inject into Shadow Root', () => {\n    const element = document.createElement('div');\n    element.id = 'injected_shadow';\n\n    injectIntoShadowRoot(webComponent, element);\n\n    expect(webComponent.shadowRoot?.children.length).toBe(2);\n    expect(webComponent.shadowRoot?.children[0]?.id).toBe('injected_shadow');\n  });\n\n  it('should not inject if already exists', () => {\n    const element = document.createElement('div');\n    element.id = 'injected_shadow';\n\n    injectIntoShadowRoot(webComponent, element);\n\n    expect(webComponent.shadowRoot?.children.length).toBe(2);\n  });\n});\n\ndescribe('Inject into Web Component', () => {\n  it('should correctly inject into Web Component', () => {\n    const element = document.createElement('div');\n    element.id = 'injected_no_shadow';\n\n    injectIntoShadowRoot(webComponentNoShadow, element);\n\n    expect(webComponentNoShadow.children.length).toBe(1);\n    expect(webComponentNoShadow.children[0]?.id).toBe('injected_no_shadow');\n  });\n\n  it('should not inject if already exists', () => {\n    const element = document.createElement('div');\n    element.id = 'injected_no_shadow';\n\n    injectIntoShadowRoot(webComponentNoShadow, element);\n\n    expect(webComponentNoShadow.children.length).toBe(1);\n  });\n});\n\ndescribe('Inject into head', () => {\n  it('should correctly inject into head', () => {\n    const element = document.createElement('style');\n    element.id = 'direflow-style';\n    injectIntoHead(element);\n\n    expect(document.head.children.length).toBe(1);\n    expect(document.head.children[0]?.id).toBe('direflow-style');\n  });\n\n  it('should not inject if already exists', () => {\n    const element = document.createElement('style');\n    element.id = 'direflow-style';\n    injectIntoHead(element);\n\n    expect(document.head.children.length).toBe(1);\n    expect(document.head.children[0]?.id).toBe('direflow-style');\n  });\n});\n\ndescribe('Strip style from head', () => {\n  it('should correctly strip style from head', () => {\n    stripStyleFromHead('direflow-style');\n    expect(document.head.children.length).toBe(0);\n    expect(document.head.children[0]).toBeUndefined();\n  });\n});\n\ndescribe('Exists identical element', () => {\n  it('should return true if identical element exists', () => {\n    const identicalLinkElement = document.createElement('link');\n    identicalLinkElement.rel = 'shortcut icon';\n    identicalLinkElement.type = 'image/x-icon';\n    identicalLinkElement.href = 'https://some-test-url.jest';\n\n    const exists = existsIdenticalElement(identicalLinkElement, appElement);\n    expect(exists).toBeTruthy();\n  });\n\n  it('should return true if identical element exists', () => {\n    const identicalLinkElement = document.createElement('link');\n    identicalLinkElement.rel = 'shortcut icon';\n    identicalLinkElement.type = 'image/x-icon';\n    identicalLinkElement.href = 'https://some-different-url.jest';\n\n    const exists = existsIdenticalElement(identicalLinkElement, appElement);\n    expect(exists).toBeFalsy();\n  });\n});\n"
  },
  {
    "path": "test/nameformats.test.ts",
    "content": "import { getNameFormats, createDefaultName } from '../cli/helpers/nameFormat';\n\ndescribe('Get correct name formats', () => {\n  it('should create name formats from slug', () => {\n    const slug = 'test-component-name';\n    const formats = getNameFormats(slug);\n\n    expect(formats.title).toBe('Test Component Name');\n    expect(formats.pascal).toBe('TestComponentName');\n    expect(formats.snake).toBe('test-component-name');\n  });\n\n  it('should create name formats from pascal', () => {\n    const slug = 'TestComponentName';\n    const formats = getNameFormats(slug);\n\n    expect(formats.title).toBe('Test Component Name');\n    expect(formats.pascal).toBe('TestComponentName');\n    expect(formats.snake).toBe('test-component-name');\n  });\n\n  it('should create name formats from title', () => {\n    const slug = 'Test Component Name';\n    const formats = getNameFormats(slug);\n\n    expect(formats.title).toBe('Test Component Name');\n    expect(formats.pascal).toBe('TestComponentName');\n    expect(formats.snake).toBe('test-component-name');\n  });\n});\n\ndescribe('Get defualt name', () => {\n  it('should create a default name', () => {\n    const defaultName = createDefaultName('awesome');\n    expect(defaultName).toBe('awesome-component');\n  });\n\n  it('should not create a default name', () => {\n    const defaultName = createDefaultName('nice-component');\n    expect(defaultName).toBe('nice-component');\n  });\n});\n"
  },
  {
    "path": "test/writeNames.test.ts",
    "content": "import { promisify } from 'util';\nimport { fs, vol } from 'memfs';\nimport writeProjectNames from '../cli/helpers/writeNames';\n\njest.mock('fs', () => fs);\n\nconst mockDirPath = '/path/to/mock/dir';\nconst mockFsJson = {\n  './package.json': `\n    {\n      \"name\": \"{{names.snake}}\",\n      \"description\": \"{{defaultDescription}}\"\n    }\n    `,\n  './README.md': `\n    # {{names.title}}\n    > {{defaultDescription}}\n    `,\n  './tslint.json': 'this-content-includes-tslint-rules',\n  './.eslintrc': 'this-content-includes-eslint-rules',\n  './nested/index.tsx': `\n    direflowComponent.configure({\n      name: '{{names.snake}}',\n      useShadow: true,\n    });\n    direflowComponent.create(App);\n    `,\n};\n\nconst readFile = promisify(fs.readFile);\n\nconst createMockFileSystem = async (options?: { noDescription?: boolean; useTslint?: boolean }) => {\n\n  vol.fromJSON(mockFsJson, mockDirPath);\n  await writeProjectNames({\n    names: {\n      title: 'Cool Component',\n      pascal: 'CoolComponent',\n      snake: 'cool-component',\n    },\n    projectDirectoryPath: mockDirPath,\n    description: options?.noDescription ? '' : 'This component is cool',\n    linter: options?.useTslint ? 'tslint' : 'eslint',\n    packageVersion: '0.0.0',\n    type: 'direflow-component',\n    npmModule: false,\n  });\n};\n\ndescribe('Write names to file #1', () => {\n  beforeAll(async () => {\n    await createMockFileSystem();\n  });\n\n  afterAll(() => {\n    vol.reset();\n  });\n\n  it('should change package.json correctly', async () => {\n    const changedFile = await readFile(`${mockDirPath}/package.json`) as any;\n    expect(changedFile.toString()).toBe(`\n    {\n      \"name\": \"cool-component\",\n      \"description\": \"This component is cool\"\n    }\n    `);\n  });\n\n  it('should change index.tsx correctly', async () => {\n    const changedFile = await readFile(`${mockDirPath}/nested/index.tsx`) as any;\n    expect(changedFile.toString()).toBe(`\n    direflowComponent.configure({\n      name: 'cool-component',\n      useShadow: true,\n    });\n    direflowComponent.create(App);\n    `);\n  });\n\n  it('should change README.md correctly', async () => {\n    const changedFile = await readFile(`${mockDirPath}/README.md`) as any;\n    expect(changedFile.toString()).toBe(`\n    # Cool Component\n    > This component is cool\n    `);\n  });\n});\n\ndescribe('Write names to file #1', () => {\n  beforeAll(async () => {\n    await createMockFileSystem({ noDescription: true });\n  });\n\n  afterAll(() => {\n    vol.reset();\n  });\n\n  it('should use fallback description in package.json', async () => {\n    const changedFile = await readFile(`${mockDirPath}/package.json`) as any;\n    expect(changedFile.toString()).toBe(`\n    {\n      \"name\": \"cool-component\",\n      \"description\": \"This project is created using Direflow\"\n    }\n    `);\n  });\n\n  it('should use fallback description in README.md', async () => {\n    const changedFile = await readFile(`${mockDirPath}/README.md`) as any;\n    expect(changedFile.toString()).toBe(`\n    # Cool Component\n    > This project is created using Direflow\n    `);\n  });\n});\n\ndescribe('Remove tslint file', () => {\n  beforeAll(async () => {\n    await createMockFileSystem();\n  });\n\n  afterAll(() => {\n    vol.reset();\n  });\n\n  it('should remove tslint file given eslint option', async () => {\n    const getFile = () => {\n      return readFile(`${mockDirPath}/tslint.json`);\n    };\n\n    await expect(getFile).rejects.toThrow(\n      Error(\"ENOENT: no such file or directory, open '/path/to/mock/dir/tslint.json'\"),\n    );\n  });\n});\n\ndescribe('Remove eslint file', () => {\n  beforeAll(async () => {\n    await createMockFileSystem({ useTslint: true });\n  });\n\n  afterAll(() => {\n    vol.reset();\n  });\n\n  it('should remove eslint file given tslint option', async () => {\n    const getFile = () => {\n      return readFile(`${mockDirPath}/.eslintrc`) as any;\n    };\n\n    await expect(getFile).rejects.toThrow(\n      Error(\"ENOENT: no such file or directory, open '/path/to/mock/dir/.eslintrc'\"),\n    );\n  });\n});\n"
  },
  {
    "path": "tsconfig.eslint.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\"node_modules\", \"dist\", \"templates\"]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"module\": \"commonjs\",\n    \"lib\": [\"es2017\", \"es7\", \"es6\", \"dom\"],\n    \"declaration\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"cli\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"skipLibCheck\": true\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"dist\",\n    \"templates\",\n    \"test\",\n    \"packages\",\n    \"cypress\"\n  ]\n}\n"
  }
]