├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── bin └── sw-db-sync.js ├── config ├── databases │ ├── production.json.sample │ └── staging.json.sample └── settings.json.sample ├── dist ├── commands │ ├── index.js │ ├── index.js.map │ ├── selfUpdateCommand.js │ ├── selfUpdateCommand.js.map │ ├── startCommand.js │ └── startCommand.js.map ├── controllers │ ├── mainController.js │ ├── mainController.js.map │ ├── selfUpdateController.js │ ├── selfUpdateController.js.map │ ├── startController.js │ └── startController.js.map ├── models │ ├── databasesModel.js │ └── databasesModel.js.map ├── questions │ ├── configurationQuestions.js │ ├── configurationQuestions.js.map │ ├── databaseTypeQuestion.js │ ├── databaseTypeQuestion.js.map │ ├── selectDatabaseQuestion.js │ └── selectDatabaseQuestion.js.map ├── sw-db-sync.js ├── sw-db-sync.js.map ├── tasks │ ├── checksTask.js │ ├── checksTask.js.map │ ├── downloadTask.js │ ├── downloadTask.js.map │ ├── importTask.js │ ├── importTask.js.map │ ├── shopwareConfigureTask.js │ └── shopwareConfigureTask.js.map └── utils │ ├── console.js │ ├── console.js.map │ ├── versionCheck.js │ └── versionCheck.js.map ├── package-lock.json ├── package.json ├── src ├── commands │ ├── index.ts │ ├── selfUpdateCommand.ts │ └── startCommand.ts ├── controllers │ ├── mainController.ts │ ├── selfUpdateController.ts │ └── startController.ts ├── models │ └── databasesModel.ts ├── questions │ ├── configurationQuestions.ts │ ├── databaseTypeQuestion.ts │ └── selectDatabaseQuestion.ts ├── sw-db-sync.ts ├── tasks │ ├── checksTask.ts │ ├── downloadTask.ts │ ├── importTask.ts │ └── shopwareConfigureTask.ts └── utils │ ├── console.ts │ └── versionCheck.ts └── tsconfig.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: sidworks-dev 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # User-specific stuff 7 | .idea/**/workspace.xml 8 | .idea/**/tasks.xml 9 | .idea/**/usage.statistics.xml 10 | .idea/**/dictionaries 11 | .idea/**/shelf 12 | .idea/* 13 | 14 | # Generated files 15 | .idea/**/contentModel.xml 16 | 17 | # Sensitive or high-churn files 18 | .idea/**/dataSources/ 19 | .idea/**/dataSources.ids 20 | .idea/**/dataSources.local.xml 21 | .idea/**/sqlDataSources.xml 22 | .idea/**/dynamic.xml 23 | .idea/**/uiDesigner.xml 24 | .idea/**/dbnavigator.xml 25 | 26 | # Gradle 27 | .idea/**/gradle.xml 28 | .idea/**/libraries 29 | 30 | # Gradle and Maven with auto-import 31 | # When using Gradle or Maven with auto-import, you should exclude module files, 32 | # since they will be recreated, and may cause churn. Uncomment if using 33 | # auto-import. 34 | # .idea/artifacts 35 | # .idea/compiler.xml 36 | # .idea/jarRepositories.xml 37 | # .idea/modules.xml 38 | # .idea/*.iml 39 | # .idea/modules 40 | # *.iml 41 | # *.ipr 42 | 43 | # CMake 44 | cmake-build-*/ 45 | 46 | # Mongo Explorer plugin 47 | .idea/**/mongoSettings.xml 48 | 49 | # File-based project format 50 | *.iws 51 | 52 | # IntelliJ 53 | out/ 54 | 55 | # mpeltonen/sbt-idea plugin 56 | .idea_modules/ 57 | 58 | # JIRA plugin 59 | atlassian-ide-plugin.xml 60 | 61 | # Cursive Clojure plugin 62 | .idea/replstate.xml 63 | 64 | # Crashlytics plugin (for Android Studio and IntelliJ) 65 | com_crashlytics_export_strings.xml 66 | crashlytics.properties 67 | crashlytics-build.properties 68 | fabric.properties 69 | 70 | # Editor-based Rest Client 71 | .idea/httpRequests 72 | 73 | # Android studio 3.1+ serialized cache file 74 | .idea/caches/build_file_checksums.ser 75 | 76 | ### Vim template 77 | # Swap 78 | [._]*.s[a-v][a-z] 79 | !*.svg # comment out if you don't need vector files 80 | [._]*.sw[a-p] 81 | [._]s[a-rt-v][a-z] 82 | [._]ss[a-gi-z] 83 | [._]sw[a-p] 84 | 85 | # Session 86 | Session.vim 87 | Sessionx.vim 88 | 89 | # Temporary 90 | .netrwhist 91 | *~ 92 | # Auto-generated tag files 93 | tags 94 | # Persistent undo 95 | [._]*.un~ 96 | 97 | ### macOS template 98 | # General 99 | .DS_Store 100 | .AppleDouble 101 | .LSOverride 102 | 103 | # Icon must end with two \r 104 | Icon 105 | 106 | # Thumbnails 107 | ._* 108 | 109 | # Files that might appear in the root of a volume 110 | .DocumentRevisions-V100 111 | .fseventsd 112 | .Spotlight-V100 113 | .TemporaryItems 114 | .Trashes 115 | .VolumeIcon.icns 116 | .com.apple.timemachine.donotpresent 117 | 118 | # Directories potentially created on remote AFP share 119 | .AppleDB 120 | .AppleDesktop 121 | Network Trash Folder 122 | Temporary Items 123 | .apdisk 124 | 125 | ### Windows template 126 | # Windows thumbnail cache files 127 | Thumbs.db 128 | Thumbs.db:encryptable 129 | ehthumbs.db 130 | ehthumbs_vista.db 131 | 132 | # Dump file 133 | *.stackdump 134 | 135 | # Folder config file 136 | [Dd]esktop.ini 137 | 138 | # Recycle Bin used on file shares 139 | $RECYCLE.BIN/ 140 | 141 | # Windows Installer files 142 | *.cab 143 | *.msi 144 | *.msix 145 | *.msm 146 | *.msp 147 | 148 | # Windows shortcuts 149 | *.lnk 150 | 151 | ### Node template 152 | # Logs 153 | logs 154 | *.log 155 | npm-debug.log* 156 | yarn-debug.log* 157 | yarn-error.log* 158 | lerna-debug.log* 159 | 160 | # Diagnostic reports (https://nodejs.org/api/report.html) 161 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 162 | 163 | # Runtime data 164 | pids 165 | *.pid 166 | *.seed 167 | *.pid.lock 168 | 169 | # Directory for instrumented libs generated by jscoverage/JSCover 170 | lib-cov 171 | 172 | # Coverage directory used by tools like istanbul 173 | coverage 174 | *.lcov 175 | 176 | # nyc test coverage 177 | .nyc_output 178 | 179 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 180 | .grunt 181 | 182 | # Bower dependency directory (https://bower.io/) 183 | bower_components 184 | 185 | # node-waf configuration 186 | .lock-wscript 187 | 188 | # Compiled binary addons (https://nodejs.org/api/addons.html) 189 | build/Release 190 | 191 | # Dependency directories 192 | node_modules/ 193 | jspm_packages/ 194 | 195 | # Snowpack dependency directory (https://snowpack.dev/) 196 | web_modules/ 197 | 198 | # TypeScript cache 199 | *.tsbuildinfo 200 | 201 | # Optional npm cache directory 202 | .npm 203 | 204 | # Optional eslint cache 205 | .eslintcache 206 | 207 | # Microbundle cache 208 | .rpt2_cache/ 209 | .rts2_cache_cjs/ 210 | .rts2_cache_es/ 211 | .rts2_cache_umd/ 212 | 213 | # Optional REPL history 214 | .node_repl_history 215 | 216 | # Output of 'npm pack' 217 | *.tgz 218 | 219 | # Yarn Integrity file 220 | .yarn-integrity 221 | 222 | # dotenv environment variables file 223 | .env 224 | .env.test 225 | 226 | # parcel-bundler cache (https://parceljs.org/) 227 | .cache 228 | .parcel-cache 229 | 230 | # Next.js build output 231 | .next 232 | out 233 | 234 | # Nuxt.js build / generate output 235 | .nuxt 236 | 237 | # Gatsby files 238 | .cache/ 239 | # Comment in the public line in if your project uses Gatsby and not Next.js 240 | # https://nextjs.org/blog/next-9-1#public-directory-support 241 | # public 242 | 243 | # vuepress build output 244 | .vuepress/dist 245 | 246 | # Serverless directories 247 | .serverless/ 248 | 249 | # FuseBox cache 250 | .fusebox/ 251 | 252 | # DynamoDB Local files 253 | .dynamodb/ 254 | 255 | # TernJS port file 256 | .tern-port 257 | 258 | # Stores VSCode versions used for testing VSCode extensions 259 | .vscode-test 260 | 261 | # yarn v2 262 | .yarn/cache 263 | .yarn/unplugged 264 | .yarn/build-state.yml 265 | .yarn/install-state.gz 266 | .pnp.* 267 | 268 | # sample files 269 | config/databases/production.json 270 | config/databases/staging.json 271 | config/settings.json -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Open Software License ("OSL") v. 3.0 2 | 3 | This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: 4 | 5 | Licensed under the Open Software License version 3.0 6 | 7 | 1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: 8 | 9 | 1.1. to reproduce the Original Work in copies, either alone or as part of a collective work; 10 | 11 | 1.2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; 12 | 13 | 1.3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; 14 | 15 | 1.4. to perform the Original Work publicly; and 16 | 17 | 1.5. to display the Original Work publicly. 18 | 19 | 2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. 20 | 21 | 3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. 22 | 23 | 4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. 24 | 25 | 5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). 26 | 27 | 6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. 28 | 29 | 7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. 30 | 31 | 8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. 32 | 33 | 9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). 34 | 35 | 10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. 36 | 37 | 11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. 38 | 39 | 12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. 40 | 41 | 13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. 42 | 43 | 14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 44 | 45 | 15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. 46 | 47 | 16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under " or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Database synchronization tool for Shopware 6 (Mac/Linux) 2 | ![](https://i.imgur.com/QWNjULB.png) 3 | 4 | ## Main functionality 5 | This tool downloads clean/stripped or full Shopware 6 databases & media images over a SSH connection, imports and configures it for development purposes. Have a fully configurated production or staging environment on your local machine within minutes. Making life a little bit easier. 6 | 7 | ## Getting started 8 | Follow the [documentation](https://github.com/sidworks-dev/sw-db-sync/wiki) and get started. 9 | -------------------------------------------------------------------------------- /bin/sw-db-sync.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require('../dist/sw-db-sync.js') 3 | -------------------------------------------------------------------------------- /config/databases/production.json.sample: -------------------------------------------------------------------------------- 1 | { 2 | "databases": { 3 | "username-1-placeholder": { 4 | "username": "example1", 5 | "password": "", 6 | "server": "example1.io", 7 | "domainFolder": "example1.io", 8 | "port": "2222", 9 | "externalProjectFolder": "", 10 | "externalPhpPath": "" 11 | }, 12 | "username-2-placeholder": { 13 | "username": "example2", 14 | "password": "", 15 | "server": "example2.io", 16 | "domainFolder": "example2.io", 17 | "port": "2222", 18 | "externalProjectFolder": "", 19 | "externalPhpPath": "" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /config/databases/staging.json.sample: -------------------------------------------------------------------------------- 1 | { 2 | "databases": { 3 | "username-1-placeholder": { 4 | "username": "example1", 5 | "password": "", 6 | "server": "example1.io", 7 | "domainFolder": "example1.io", 8 | "port": "2222", 9 | "externalProjectFolder": "", 10 | "externalPhpPath": "", 11 | "localProjectUrl": "example1.development" 12 | }, 13 | "username-2-placeholder": { 14 | "username": "example2", 15 | "password": "", 16 | "server": "example2.io", 17 | "domainFolder": "example2.io", 18 | "port": "2222", 19 | "externalProjectFolder": "", 20 | "externalPhpPath": "", 21 | "localProjectUrl": "example2.development" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /config/settings.json.sample: -------------------------------------------------------------------------------- 1 | { 2 | "general": { 3 | "databaseLocation": "/Users/{username}/Databases" 4 | }, 5 | "ssh": { 6 | "keyLocation": "", 7 | "passphrase": "" 8 | }, 9 | "shopwareBackend": { 10 | "adminUsername": "admin", 11 | "adminPassword": "Password1!", 12 | "adminEmailAddress": "info@example.com" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /dist/commands/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.default = default_1; 4 | const tslib_1 = require("tslib"); 5 | const fs_1 = tslib_1.__importDefault(require("fs")); 6 | const path_1 = tslib_1.__importDefault(require("path")); 7 | // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types 8 | function default_1(program) { 9 | const commands = []; 10 | const loadPath = path_1.default.dirname(__filename); 11 | // Loop through command files 12 | fs_1.default.readdirSync(loadPath).filter(function (filename) { 13 | return (/\.js$/.test(filename) && filename !== 'index.js'); 14 | }).forEach(function (filename) { 15 | // const name: string = filename.substr(0, filename.lastIndexOf('.')) 16 | // Require command 17 | // eslint-disable-next-line @typescript-eslint/no-var-requires 18 | const command = require(path_1.default.join(loadPath, filename)); 19 | // Initialize command 20 | commands.push(command.default(program)); 21 | }); 22 | return commands; 23 | } 24 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/commands/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":";;AAKA,4BAmBC;;AAvBD,oDAAmB;AACnB,wDAAuB;AAEvB,6EAA6E;AAC7E,mBAAyB,OAAyB;IAC9C,MAAM,QAAQ,GAAwB,EAAE,CAAA;IACxC,MAAM,QAAQ,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAEzC,6BAA6B;IAC7B,YAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,QAAQ;QAC9C,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,UAAU,CAAC,CAAA;IAC9D,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,QAAQ;QACzB,qEAAqE;QAErE,kBAAkB;QAClB,8DAA8D;QAC9D,MAAM,OAAO,GAAG,OAAO,CAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAA;QAEtD,qBAAqB;QACrB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,OAAO,QAAQ,CAAA;AACnB,CAAC"} -------------------------------------------------------------------------------- /dist/commands/selfUpdateCommand.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const console_1 = require("../utils/console"); 5 | const selfUpdateController_1 = tslib_1.__importDefault(require("../controllers/selfUpdateController")); 6 | exports.default = (program) => program 7 | .command('self-update') 8 | .description('Updates the database synchronizer to the latest version') 9 | .action((service) => { 10 | (new selfUpdateController_1.default()).executeStart(service).catch((err) => (0, console_1.error)(err.message)); 11 | }); 12 | //# sourceMappingURL=selfUpdateCommand.js.map -------------------------------------------------------------------------------- /dist/commands/selfUpdateCommand.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"selfUpdateCommand.js","sourceRoot":"","sources":["../../src/commands/selfUpdateCommand.ts"],"names":[],"mappings":";;;AACA,8CAAsC;AACtC,uGAAuE;AAEvE,kBAAe,CAAC,OAAyB,EAAqB,EAAE,CAAC,OAAO;KACnE,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,yDAAyD,CAAC;KACtE,MAAM,CAAC,CAAC,OAA2B,EAAE,EAAE;IACpC,CAAC,IAAI,8BAAoB,EAAE,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,IAAA,eAAK,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;AAC9F,CAAC,CAAC,CAAA"} -------------------------------------------------------------------------------- /dist/commands/startCommand.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const startController_1 = tslib_1.__importDefault(require("../controllers/startController")); 5 | const console_1 = require("../utils/console"); 6 | exports.default = (program) => program 7 | .command('start') 8 | .description('Starts the database synchronizer') 9 | .action((service) => { 10 | (new startController_1.default()).executeStart(service).catch(err => (0, console_1.error)(err.message)); 11 | }); 12 | //# sourceMappingURL=startCommand.js.map -------------------------------------------------------------------------------- /dist/commands/startCommand.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"startCommand.js","sourceRoot":"","sources":["../../src/commands/startCommand.ts"],"names":[],"mappings":";;;AACA,6FAA6D;AAC7D,8CAAsC;AAEtC,kBAAe,CAAC,OAAyB,EAAqB,EAAE,CAAC,OAAO;KACnE,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,CAAC,OAA2B,EAAE,EAAE;IACpC,CAAC,IAAI,yBAAgB,EAAE,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,eAAK,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;AACnF,CAAC,CAAC,CAAA"} -------------------------------------------------------------------------------- /dist/controllers/mainController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | // @ts-ignore 5 | const settings_json_1 = tslib_1.__importDefault(require("../../config/settings.json")); 6 | const node_ssh_1 = require("node-ssh"); 7 | const databasesModel_1 = tslib_1.__importDefault(require("../models/databasesModel")); 8 | const os = tslib_1.__importStar(require("os")); 9 | const path = tslib_1.__importStar(require("path")); 10 | const listr2_1 = require("listr2"); 11 | const command_exists_1 = tslib_1.__importDefault(require("command-exists")); 12 | const inquirer_1 = tslib_1.__importDefault(require("inquirer")); 13 | inquirer_1.default.registerPrompt("search-list", require("../../node_modules/inquirer-search-list")); 14 | class MainController { 15 | constructor() { 16 | this.config = { 17 | 'customConfig': { 18 | 'sshKeyLocation': settings_json_1.default.ssh.keyLocation, 19 | 'sshPassphrase': settings_json_1.default.ssh.passphrase, 20 | 'localDatabaseFolderLocation': settings_json_1.default.general.databaseLocation 21 | }, 22 | 'serverVariables': { 23 | 'externalPhpPath': '', 24 | 'shopwareRoot': '', 25 | 'databaseName': '' 26 | }, 27 | 'settings': { 28 | 'currentFolder': '', 29 | 'currentFolderName': '', 30 | 'databaseFileName': '', 31 | 'databaseFullPath': '', 32 | 'strip': '', 33 | 'syncImages': 'no', 34 | 'rsyncInstalled': false, 35 | 'import': 'no', 36 | 'currentFolderIsShopware': false, 37 | 'isDdevActive': false 38 | }, 39 | 'localhost': { 40 | 'username': '', 41 | 'password': '', 42 | 'host': '', 43 | 'port': '', 44 | 'database': '', 45 | 'domainUrl': '', 46 | 'https': false 47 | }, 48 | 'finalMessages': { 49 | 'shopwareDatabaseLocation': '', 50 | 'importDomain': '' 51 | }, 52 | 'databases': { 53 | 'databasesList': null, 54 | 'databaseType': null, 55 | 'databaseData': null 56 | } 57 | }; 58 | this.list = new listr2_1.Listr([], { concurrent: false }); 59 | this.ssh = new node_ssh_1.NodeSSH(); 60 | this.databases = new databasesModel_1.default(); 61 | this.configureConfig = () => tslib_1.__awaiter(this, void 0, void 0, function* () { 62 | // Fetch SSH key location, if non configured 63 | if (!this.config.customConfig.sshKeyLocation) { 64 | this.config.customConfig.sshKeyLocation = os.userInfo().homedir + '/.ssh/id_rsa'; 65 | } 66 | // Check if rsync is installed locally 67 | yield (0, command_exists_1.default)('rsync') 68 | .then((command) => { 69 | this.config.settings.rsyncInstalled = true; 70 | }).catch(function () { }); 71 | // Get current folder from cwd 72 | this.config.settings.currentFolder = process.cwd(); 73 | // Set current folder name based on current folder 74 | this.config.settings.currentFolderName = path.basename(path.resolve(this.config.settings.currentFolder)); 75 | }); 76 | this.configureConfig().then(); 77 | } 78 | } 79 | exports.default = MainController; 80 | //# sourceMappingURL=mainController.js.map -------------------------------------------------------------------------------- /dist/controllers/mainController.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"mainController.js","sourceRoot":"","sources":["../../src/controllers/mainController.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,uFAAmD;AACnD,uCAAgC;AAChC,sFAAsD;AACtD,+CAAwB;AACxB,mDAA4B;AAC5B,mCAA+B;AAC/B,4EAA2C;AAC3C,gEAA+B;AAC/B,kBAAQ,CAAC,cAAc,CAAC,aAAa,EAAE,OAAO,CAAC,yCAAyC,CAAC,CAAC,CAAC;AAG3F,MAAM,cAAc;IAkDhB;QAjDO,WAAM,GAAG;YACZ,cAAc,EAAE;gBACZ,gBAAgB,EAAE,uBAAU,CAAC,GAAG,CAAC,WAAW;gBAC5C,eAAe,EAAE,uBAAU,CAAC,GAAG,CAAC,UAAU;gBAC1C,6BAA6B,EAAE,uBAAU,CAAC,OAAO,CAAC,gBAAgB;aACrE;YACD,iBAAiB,EAAE;gBACf,iBAAiB,EAAE,EAAE;gBACrB,cAAc,EAAE,EAAE;gBAClB,cAAc,EAAE,EAAE;aACrB;YACD,UAAU,EAAE;gBACR,eAAe,EAAE,EAAE;gBACnB,mBAAmB,EAAE,EAAE;gBACvB,kBAAkB,EAAE,EAAE;gBACtB,kBAAkB,EAAE,EAAE;gBACtB,OAAO,EAAE,EAAE;gBACX,YAAY,EAAE,IAAI;gBAClB,gBAAgB,EAAE,KAAK;gBACvB,QAAQ,EAAE,IAAI;gBACd,yBAAyB,EAAE,KAAK;gBAChC,cAAc,EAAE,KAAK;aACxB;YACD,WAAW,EAAE;gBACT,UAAU,EAAE,EAAE;gBACd,UAAU,EAAE,EAAE;gBACd,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,EAAE;gBACV,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,EAAE;gBACf,OAAO,EAAE,KAAK;aACjB;YACD,eAAe,EAAE;gBACb,0BAA0B,EAAE,EAAE;gBAC9B,cAAc,EAAE,EAAE;aACrB;YACD,WAAW,EAAE;gBACT,eAAe,EAAE,IAAI;gBACrB,cAAc,EAAE,IAAI;gBACpB,cAAc,EAAE,IAAI;aACvB;SACJ,CAAC;QACK,SAAI,GAAG,IAAI,cAAK,CACnB,EAAE,EACF,EAAC,UAAU,EAAE,KAAK,EAAC,CACtB,CAAC;QACK,QAAG,GAAG,IAAI,kBAAO,EAAE,CAAC;QACpB,cAAS,GAAG,IAAI,wBAAc,EAAE,CAAC;QAMxC,oBAAe,GAAG,GAAS,EAAE;YACzB,4CAA4C;YAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;gBAC3C,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,cAAc,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,GAAG,cAAc,CAAC;YACrF,CAAC;YAED,sCAAsC;YACtC,MAAM,IAAA,wBAAa,EAAC,OAAO,CAAC;iBAC3B,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBACd,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC;YAC/C,CAAC,CAAC,CAAC,KAAK,CAAC,cAAW,CAAC,CAAC,CAAC;YAEvB,8BAA8B;YAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAEnD,kDAAkD;YAClD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;QAC7G,CAAC,CAAA,CAAA;QApBG,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;CAoBJ;AAED,kBAAe,cAAc,CAAA"} -------------------------------------------------------------------------------- /dist/controllers/selfUpdateController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | // @ts-ignore 5 | const download_git_repo_1 = tslib_1.__importDefault(require("download-git-repo")); 6 | // @ts-ignore 7 | const get_installed_path_1 = require("get-installed-path"); 8 | const console_1 = require("../utils/console"); 9 | const versionCheck_1 = tslib_1.__importDefault(require("../utils/versionCheck")); 10 | class SelfUpdateController { 11 | constructor() { 12 | this.versionCheck = new versionCheck_1.default(); 13 | this.executeStart = (serviceName) => tslib_1.__awaiter(this, void 0, void 0, function* () { 14 | //await this.versionCheck.getToolVersions(); 15 | let self = this; 16 | let config = { 17 | 'npmPath': '', 18 | 'currentVersion': this.versionCheck.config.currentVersion, 19 | 'latestVersion': this.versionCheck.config.latestVersion 20 | }; 21 | yield (0, get_installed_path_1.getInstalledPath)('sw-db-sync').then((path) => { 22 | config.npmPath = path; 23 | }); 24 | if (config.currentVersion < config.latestVersion) { 25 | yield (0, console_1.consoleCommand)(`cd ${config.npmPath}; rm -rf dist`, false); 26 | yield (0, download_git_repo_1.default)('sidworks-dev/sw-db-sync#master', config.npmPath, function (err) { 27 | return tslib_1.__awaiter(this, void 0, void 0, function* () { 28 | yield (0, console_1.consoleCommand)(`cd ${config.npmPath}; npm install`, false); 29 | (0, console_1.success)(`Updated sw-db-sync from ${config.currentVersion} to ${config.latestVersion}`); 30 | }); 31 | }); 32 | } 33 | else { 34 | (0, console_1.success)(`sw-db-sync is already up to date`); 35 | } 36 | return true; 37 | }); 38 | } 39 | } 40 | exports.default = SelfUpdateController; 41 | //# sourceMappingURL=selfUpdateController.js.map 42 | -------------------------------------------------------------------------------- /dist/controllers/selfUpdateController.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"selfUpdateController.js","sourceRoot":"","sources":["../../src/controllers/selfUpdateController.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,kFAAwC;AACxC,aAAa;AACb,2DAAmD;AACnD,8CAAyD;AAGzD,iFAAiD;AAEjD,MAAM,oBAAoB;IAA1B;QACY,iBAAY,GAAG,IAAI,sBAAY,EAAE,CAAC;QAE1C,iBAAY,GAAG,CAAO,WAA+B,EAAoB,EAAE;YACvE,4CAA4C;YAE5C,IAAI,IAAI,GAAG,IAAI,CAAC;YAChB,IAAI,MAAM,GAAG;gBACT,SAAS,EAAE,EAAE;gBACb,gBAAgB,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,cAAc;gBACzD,eAAe,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,aAAa;aAC1D,CAAC;YAEF,MAAM,IAAA,qCAAgB,EAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE;gBACvD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;YAC1B,CAAC,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC/C,MAAM,IAAA,wBAAc,EAAC,MAAM,MAAM,CAAC,OAAO,eAAe,EAAE,KAAK,CAAC,CAAC;gBAEjE,MAAM,IAAA,2BAAQ,EAAC,iCAAiC,EAAE,MAAM,CAAC,OAAO,EAAE,UAAgB,GAAQ;;wBACtF,MAAM,IAAA,wBAAc,EAAC,MAAM,MAAM,CAAC,OAAO,eAAe,EAAE,KAAK,CAAC,CAAC;wBACjE,IAAA,iBAAO,EAAC,2BAA2B,MAAM,CAAC,cAAc,OAAO,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;oBAC3F,CAAC;iBAAA,CAAC,CAAC;YACP,CAAC;iBAAM,CAAC;gBACJ,IAAA,iBAAO,EAAC,kCAAkC,CAAC,CAAC;YAChD,CAAC;YAED,OAAO,IAAI,CAAC;QAChB,CAAC,CAAA,CAAA;IACL,CAAC;CAAA;AAED,kBAAe,oBAAoB,CAAA"} -------------------------------------------------------------------------------- /dist/controllers/startController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const console_1 = require("../utils/console"); 5 | // @ts-ignore 6 | const settings_json_1 = tslib_1.__importDefault(require("../../config/settings.json")); 7 | const mainController_1 = tslib_1.__importDefault(require("./mainController")); 8 | const databaseTypeQuestion_1 = tslib_1.__importDefault(require("../questions/databaseTypeQuestion")); 9 | const selectDatabaseQuestion_1 = tslib_1.__importDefault(require("../questions/selectDatabaseQuestion")); 10 | const configurationQuestions_1 = tslib_1.__importDefault(require("../questions/configurationQuestions")); 11 | const checksTask_1 = tslib_1.__importDefault(require("../tasks/checksTask")); 12 | const downloadTask_1 = tslib_1.__importDefault(require("../tasks/downloadTask")); 13 | const importTask_1 = tslib_1.__importDefault(require("../tasks/importTask")); 14 | const shopwareConfigureTask_1 = tslib_1.__importDefault(require("../tasks/shopwareConfigureTask")); 15 | class StartController extends mainController_1.default { 16 | constructor() { 17 | super(...arguments); 18 | this.executeStart = () => tslib_1.__awaiter(this, void 0, void 0, function* () { 19 | // Ask all the questions to the user 20 | yield this.askQuestions(); 21 | // Configure task list 22 | yield this.prepareTasks(); 23 | // Run all tasks 24 | try { 25 | yield this.list.run(); 26 | // Show final message when done with all tasks 27 | if (this.config.finalMessages.importDomain.length > 0) { 28 | (0, console_1.success)(`Shopware is successfully imported to localhost. ${this.config.finalMessages.importDomain} is now available.`); 29 | (0, console_1.info)(`You can log in to the Shopware backend with username: ${settings_json_1.default.shopwareBackend.adminUsername} and password: ${settings_json_1.default.shopwareBackend.adminPassword}`); 30 | } 31 | else if (this.config.finalMessages.shopwareDatabaseLocation.length > 0) { 32 | (0, console_1.success)(`Downloaded Shopware database to: ${this.config.finalMessages.shopwareDatabaseLocation}`); 33 | } 34 | process.exit(); 35 | } 36 | catch (e) { 37 | console.error(e); 38 | } 39 | }); 40 | // Ask questions to user 41 | this.askQuestions = () => tslib_1.__awaiter(this, void 0, void 0, function* () { 42 | // Clear the console 43 | (0, console_1.clearConsole)(); 44 | // Ask question about database type 45 | let databaseTypeQuestion = yield new databaseTypeQuestion_1.default(); 46 | yield databaseTypeQuestion.configure(this.config); 47 | // Make user choose a database from the list 48 | let selectDatabaseQuestion = yield new selectDatabaseQuestion_1.default(); 49 | yield selectDatabaseQuestion.configure(this.config); 50 | // Adds multiple configuration questions 51 | let configurationQuestions = yield new configurationQuestions_1.default(); 52 | yield configurationQuestions.configure(this.config); 53 | // Clear the console 54 | (0, console_1.clearConsole)(); 55 | }); 56 | // Configure task list 57 | this.prepareTasks = () => tslib_1.__awaiter(this, void 0, void 0, function* () { 58 | // Build up check list 59 | let checkTask = yield new checksTask_1.default(); 60 | yield checkTask.configure(this.list, this.config); 61 | // Build up download list 62 | let downloadTask = yield new downloadTask_1.default(); 63 | yield downloadTask.configure(this.list, this.config, this.ssh); 64 | // Import Shopware if possible 65 | if (this.config.settings.import && this.config.settings.import == "yes") { 66 | // Build import list 67 | let importTask = yield new importTask_1.default(); 68 | yield importTask.configure(this.list, this.config); 69 | // Build Shopware configure list 70 | let shopwareConfigureTask = yield new shopwareConfigureTask_1.default(); 71 | yield shopwareConfigureTask.configure(this.list, this.config); 72 | } 73 | }); 74 | } 75 | } 76 | exports.default = StartController; 77 | //# sourceMappingURL=startController.js.map -------------------------------------------------------------------------------- /dist/controllers/startController.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"startController.js","sourceRoot":"","sources":["../../src/controllers/startController.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/models/databasesModel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | // @ts-ignore 5 | const staging_json_1 = tslib_1.__importDefault(require("../../config/databases/staging.json")); 6 | // @ts-ignore 7 | const production_json_1 = tslib_1.__importDefault(require("../../config/databases/production.json")); 8 | class DatabasesModel { 9 | constructor() { 10 | this.databasesList = []; 11 | this.databaseData = { 12 | 'username': '', 13 | 'password': '', 14 | 'server': '', 15 | 'domainFolder': '', 16 | 'port': 22, 17 | 'localProjectFolder': '', 18 | 'externalProjectFolder': '', 19 | 'externalPhpPath': '', 20 | }; 21 | // Collect databases | collect single database 22 | this.collectDatabaseData = (databaseKey, databaseType) => tslib_1.__awaiter(this, void 0, void 0, function* () { 23 | // @ts-ignore 24 | var databases = staging_json_1.default.databases; 25 | if (databaseType == 'production') { 26 | // @ts-ignore 27 | databases = production_json_1.default.databases; 28 | } 29 | for (let [key, database] of Object.entries(databases)) { 30 | if (databaseKey == key) { 31 | // Collect single database info 32 | this.databaseData.username = database.username; 33 | // @ts-ignore 34 | this.databaseData.password = database.password; 35 | this.databaseData.server = database.server; 36 | this.databaseData.domainFolder = database.domainFolder; 37 | // @ts-ignore 38 | this.databaseData.port = database.port; 39 | this.databaseData.externalProjectFolder = database.externalProjectFolder; 40 | // @ts-ignore 41 | this.databaseData.externalPhpPath = database.externalPhpPath; 42 | } 43 | else { 44 | // Collect all database 45 | this.databasesList.push(`${database.domainFolder} / ${database.username} (${key})`); 46 | } 47 | } 48 | }); 49 | } 50 | } 51 | exports.default = DatabasesModel; 52 | //# sourceMappingURL=databasesModel.js.map -------------------------------------------------------------------------------- /dist/models/databasesModel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"databasesModel.js","sourceRoot":"","sources":["../../src/models/databasesModel.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,+FAAmE;AACnE,aAAa;AACb,qGAAyE;AAEzE,MAAM,cAAc;IAApB;QACQ,kBAAa,GAAyB,EAAE,CAAC;QACzC,iBAAY,GAAG;YACrB,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;YACZ,cAAc,EAAE,EAAE;YAClB,MAAM,EAAE,EAAE;YACV,oBAAoB,EAAE,EAAE;YACxB,uBAAuB,EAAE,EAAE;YAC3B,iBAAiB,EAAE,EAAE;SACrB,CAAC;QAEF,8CAA8C;QAC9C,wBAAmB,GAAG,CAAO,WAA0B,EAAE,YAA2B,EAAG,EAAE;YACxF,aAAa;YACb,IAAI,SAAS,GAAG,sBAAgB,CAAC,SAAS,CAAC;YAE3C,IAAI,YAAY,IAAI,YAAY,EAAE,CAAC;gBAClC,aAAa;gBACb,SAAS,GAAG,yBAAmB,CAAC,SAAS,CAAC;YAC3C,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvD,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC;oBACxB,+BAA+B;oBAC/B,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;oBAC/C,aAAa;oBACb,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;oBAC/C,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;oBAC3C,IAAI,CAAC,YAAY,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;oBACvD,aAAa;oBACb,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;oBACvC,IAAI,CAAC,YAAY,CAAC,qBAAqB,GAAG,QAAQ,CAAC,qBAAqB,CAAC;oBACzE,aAAa;oBACb,IAAI,CAAC,YAAY,CAAC,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAA;gBAC7D,CAAC;qBAAM,CAAC;oBACP,uBAAuB;oBACvB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,YAAY,MAAM,QAAQ,CAAC,QAAQ,KAAK,GAAG,GAAG,CAAC,CAAC;gBACrF,CAAC;YACF,CAAC;QACF,CAAC,CAAA,CAAA;IACF,CAAC;CAAA;AAED,kBAAe,cAAc,CAAC"} -------------------------------------------------------------------------------- /dist/questions/configurationQuestions.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const console_1 = require("console"); 5 | const inquirer_1 = tslib_1.__importDefault(require("inquirer")); 6 | class ConfigurationQuestions { 7 | constructor() { 8 | this.questionsOne = []; 9 | this.questionsTwo = []; 10 | this.configure = (config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 11 | yield this.addQuestions(config); 12 | // Set import configs 13 | yield inquirer_1.default 14 | .prompt(this.questionsOne) 15 | .then((answers) => { 16 | // Set stripped setting 17 | config.settings.strip = answers.strip; 18 | // Set import setting for Shopware 19 | config.settings.import = answers.import; 20 | // Set image import setting for Shopware 21 | config.settings.syncImages = answers.syncImages; 22 | // Change location of database download depending on answer 23 | if (config.settings.import == 'yes') { 24 | config.customConfig.localDatabaseFolderLocation = config.settings.currentFolder; 25 | } 26 | }) 27 | .catch((err) => { 28 | (0, console_1.error)(`Something went wrong: ${err.message}`); 29 | }); 30 | }); 31 | // Add questions 32 | this.addQuestions = (config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 33 | this.questionsOne.push({ 34 | type: 'list', 35 | name: 'strip', 36 | default: 'stripped', 37 | message: 'Does the Shopware database need to be stripped for development?', 38 | choices: ['stripped', 'full'], 39 | validate: (input) => { 40 | return input !== ''; 41 | } 42 | }); 43 | // Only push questions if Shopware project is found 44 | if (config.settings.currentFolderIsShopware) { 45 | this.questionsOne.push({ 46 | type: 'list', 47 | name: 'import', 48 | default: 'yes', 49 | message: 'Import Shopware database?', 50 | choices: ['yes', 'no'], 51 | validate: (input) => { 52 | return false; 53 | }, 54 | }); 55 | if (config.settings.rsyncInstalled) { 56 | this.questionsOne.push({ 57 | type: 'list', 58 | name: 'syncImages', 59 | default: 'yes', 60 | message: 'Synchronize images from public/media?', 61 | choices: ['yes', 'no'], 62 | validate: (input) => { 63 | return false; 64 | }, 65 | }); 66 | } 67 | } 68 | }); 69 | } 70 | } 71 | exports.default = ConfigurationQuestions; 72 | //# sourceMappingURL=configurationQuestions.js.map -------------------------------------------------------------------------------- /dist/questions/configurationQuestions.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"configurationQuestions.js","sourceRoot":"","sources":["../../src/questions/configurationQuestions.ts"],"names":[],"mappings":";;;AAAA,qCAAgC;AAChC,gEAA+B;AAE/B,MAAM,sBAAsB;IAA5B;QACY,iBAAY,GAAG,EAAE,CAAC;QAClB,iBAAY,GAAG,EAAE,CAAC;QAE1B,cAAS,GAAG,CAAO,MAAW,EAAE,EAAE;YAC9B,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAEhC,qBAAqB;YACrB,MAAM,kBAAQ;iBACT,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;iBACzB,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBACd,uBAAuB;gBACvB,MAAM,CAAC,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;gBAEtC,kCAAkC;gBAClC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;gBAEvC,wCAAwC;gBACxC,MAAM,CAAC,QAAQ,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAA;gBAE/C,2DAA2D;gBAC3D,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;oBAClC,MAAM,CAAC,YAAY,CAAC,2BAA2B,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;gBACpF,CAAC;YACL,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAsB,EAAE,EAAE;gBAC9B,IAAA,eAAK,EAAC,yBAAyB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;YACjD,CAAC,CAAC,CAAC;QACX,CAAC,CAAA,CAAA;QAED,gBAAgB;QAChB,iBAAY,GAAG,CAAO,MAAW,EAAE,EAAE;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAClB;gBACI,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,UAAU;gBACnB,OAAO,EAAE,iEAAiE;gBAC1E,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC;gBAC7B,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;oBACxB,OAAO,KAAK,KAAK,EAAE,CAAA;gBACvB,CAAC;aACJ,CACJ,CAAC;YAEF,mDAAmD;YACnD,IAAI,MAAM,CAAC,QAAQ,CAAC,uBAAuB,EAAE,CAAC;gBAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAClB;oBACI,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,2BAA2B;oBACpC,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;oBACtB,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;wBACxB,OAAO,KAAK,CAAC;oBACjB,CAAC;iBACJ,CACJ,CAAC;gBAEF,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;oBACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAClB;wBACI,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,YAAY;wBAClB,OAAO,EAAE,KAAK;wBACd,OAAO,EAAE,uCAAuC;wBAChD,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;wBACtB,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;4BACxB,OAAO,KAAK,CAAC;wBACjB,CAAC;qBACJ,CACJ,CAAC;gBACN,CAAC;YACL,CAAC;QACL,CAAC,CAAA,CAAA;IACL,CAAC;CAAA;AAED,kBAAe,sBAAsB,CAAA"} -------------------------------------------------------------------------------- /dist/questions/databaseTypeQuestion.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const console_1 = require("console"); 5 | const inquirer_1 = tslib_1.__importDefault(require("inquirer")); 6 | const databasesModel_1 = tslib_1.__importDefault(require("../models/databasesModel")); 7 | class DatabaseTypeQuestion { 8 | constructor() { 9 | this.databasesModel = new databasesModel_1.default(); 10 | this.questions = []; 11 | this.configure = (config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 12 | yield this.addQuestions(config); 13 | // Set database type 14 | yield inquirer_1.default 15 | .prompt(this.questions) 16 | .then((answers) => { 17 | // Set the database type 18 | config.databases.databaseType = answers.databaseType; 19 | // Collect databases 20 | this.databasesModel.collectDatabaseData('', answers.databaseType); 21 | // Set database list 22 | config.databases.databasesList = this.databasesModel.databasesList; 23 | }) 24 | .catch((err) => { 25 | (0, console_1.error)(`Something went wrong: ${err.message}`); 26 | }); 27 | }); 28 | // Add questions 29 | this.addQuestions = (config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 30 | this.questions.push({ 31 | type: 'list', 32 | name: 'databaseType', 33 | message: 'Set database type', 34 | default: 'staging', 35 | choices: ['staging', 'production'], 36 | validate: (input) => { 37 | return input !== ''; 38 | } 39 | }); 40 | }); 41 | } 42 | } 43 | exports.default = DatabaseTypeQuestion; 44 | //# sourceMappingURL=databaseTypeQuestion.js.map -------------------------------------------------------------------------------- /dist/questions/databaseTypeQuestion.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"databaseTypeQuestion.js","sourceRoot":"","sources":["../../src/questions/databaseTypeQuestion.ts"],"names":[],"mappings":";;;AAAA,qCAAgC;AAChC,gEAA+B;AAC/B,sFAAsD;AAEtD,MAAM,oBAAoB;IAA1B;QACY,mBAAc,GAAG,IAAI,wBAAc,EAAE,CAAC;QACtC,cAAS,GAAG,EAAE,CAAC;QAEvB,cAAS,GAAG,CAAO,MAAW,EAAE,EAAE;YAC9B,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAEhC,oBAAoB;YACpB,MAAM,kBAAQ;iBACb,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;iBACtB,IAAI,CAAC,CAAC,OAA+B,EAAE,EAAE;gBACtC,wBAAwB;gBACxB,MAAM,CAAC,SAAS,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;gBAErD,oBAAoB;gBACpB,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,EAAE,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;gBAElE,oBAAoB;gBACpB,MAAM,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC;YACvE,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAsB,EAAE,EAAE;gBAC9B,IAAA,eAAK,EAAC,yBAAyB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;YACjD,CAAC,CAAC,CAAC;QACP,CAAC,CAAA,CAAA;QAED,gBAAgB;QAChB,iBAAY,GAAG,CAAO,MAAW,EAAE,EAAE;YACjC,IAAI,CAAC,SAAS,CAAC,IAAI,CACf;gBACI,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,mBAAmB;gBAC5B,OAAO,EAAE,SAAS;gBAClB,OAAO,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;gBAClC,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;oBACxB,OAAO,KAAK,KAAK,EAAE,CAAA;gBACvB,CAAC;aACJ,CACJ,CAAA;QACL,CAAC,CAAA,CAAA;IACL,CAAC;CAAA;AAED,kBAAe,oBAAoB,CAAA"} -------------------------------------------------------------------------------- /dist/questions/selectDatabaseQuestion.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const console_1 = require("console"); 5 | const inquirer_1 = tslib_1.__importDefault(require("inquirer")); 6 | const databasesModel_1 = tslib_1.__importDefault(require("../models/databasesModel")); 7 | const path = tslib_1.__importStar(require("path")); 8 | const fs = tslib_1.__importStar(require("fs")); 9 | const command_exists_1 = tslib_1.__importDefault(require("command-exists")); 10 | class SelectDatabaseQuestion { 11 | constructor() { 12 | this.databasesModel = new databasesModel_1.default(); 13 | this.questions = []; 14 | this.configure = (config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 15 | yield this.addQuestions(config); 16 | yield inquirer_1.default 17 | .prompt(this.questions) 18 | .then((answers) => { 19 | // Get database key to get database settings 20 | let keyRegex = /\((.*)\)/i; 21 | let selectedDatabase = answers.database; 22 | let databaseKey = selectedDatabase.match(keyRegex)[1]; 23 | // Collects database data based on key 24 | this.databasesModel.collectDatabaseData(databaseKey, config.databases.databaseType); 25 | // Set database data in config 26 | config.databases.databaseData = this.databasesModel.databaseData; 27 | // If local folder is set for project, use that as currentFolder 28 | config.settings.currentFolder = process.cwd(); 29 | if (config.databases.databaseData.localProjectFolder && config.databases.databaseData.localProjectFolder.length > 0) { 30 | config.settings.currentFolder = config.databases.databaseData.localProjectFolder; 31 | } 32 | // Set current folder name based on current folder 33 | config.settings.currentFolderName = path.basename(path.resolve(config.settings.currentFolder)); 34 | // Check if current is shopware. This will be used to determine if we can import Shopware 35 | if (fs.existsSync(config.settings.currentFolder + '/vendor/shopware/core') || fs.existsSync(config.settings.currentFolder + '/public/index.php')) { 36 | config.settings.currentFolderIsShopware = true; 37 | if (fs.existsSync(config.settings.currentFolder + '/.ddev/config.yaml')) { 38 | // Check if ddev is installed locally 39 | (0, command_exists_1.default)('ddev').then((command) => { 40 | config.settings.isDdevActive = true; 41 | }).catch(function () { }); 42 | } 43 | } 44 | }) 45 | .catch((err) => { 46 | (0, console_1.error)(`Something went wrong: ${err.message}`); 47 | }); 48 | }); 49 | // Add questions 50 | this.addQuestions = (config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 51 | this.questions.push({ 52 | type: 'search-list', 53 | name: 'database', 54 | message: 'Select or search database', 55 | choices: config.databases.databasesList, 56 | validate: (input) => { 57 | return input !== ''; 58 | } 59 | }); 60 | }); 61 | } 62 | } 63 | exports.default = SelectDatabaseQuestion; 64 | //# sourceMappingURL=selectDatabaseQuestion.js.map -------------------------------------------------------------------------------- /dist/questions/selectDatabaseQuestion.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"selectDatabaseQuestion.js","sourceRoot":"","sources":["../../src/questions/selectDatabaseQuestion.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/sw-db-sync.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const commander_1 = tslib_1.__importDefault(require("commander")); 5 | const index_1 = tslib_1.__importDefault(require("./commands/index")); 6 | const fs_1 = tslib_1.__importDefault(require("fs")); 7 | // @ts-ignore 8 | const get_installed_path_1 = require("get-installed-path"); 9 | const console_1 = require("./utils/console"); 10 | const versionCheck_1 = tslib_1.__importDefault(require("./utils/versionCheck")); 11 | (0, get_installed_path_1.getInstalledPath)('sw-db-sync').then((path) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { 12 | // Lets make sure all required files are in place before running the tool 13 | let npmPath = path; 14 | let missingFiles = false; 15 | let requiredFiles = [ 16 | 'config/settings.json', 17 | 'config/databases/staging.json', 18 | 'config/databases/production.json' 19 | ]; 20 | new Promise((resolve, reject) => { 21 | requiredFiles.forEach((path) => { 22 | if (!fs_1.default.existsSync(`${npmPath}/${path}`)) { 23 | (0, console_1.error)(`${path} was not found. Make sure this file exists (${npmPath}/${path})`); 24 | missingFiles = true; 25 | } 26 | }); 27 | }); 28 | // If there are files missing, stop the program from running 29 | if (missingFiles) { 30 | return; 31 | } 32 | (0, index_1.default)(commander_1.default); 33 | // eslint-disable-next-line @typescript-eslint/no-var-requires 34 | const packageJson = require('../package.json'); 35 | let versionCheck = new versionCheck_1.default(); 36 | yield versionCheck.getToolVersions(); 37 | let description = `Shopware 6 Database Synchronizer - ${packageJson.version}`; 38 | if (versionCheck.config.currentVersion < versionCheck.config.latestVersion) { 39 | description = `${description}\nRun 'sw-db-sync self-update' to download the newest version: ${versionCheck.config.latestVersion}`; 40 | } 41 | commander_1.default 42 | .version(packageJson.version) 43 | .usage(' [options]') 44 | .description(description); 45 | commander_1.default.on('command:*', () => { 46 | commander_1.default.help(); 47 | }); 48 | commander_1.default.parse(process.argv); 49 | if (!process.argv.slice(2).length) { 50 | commander_1.default.outputHelp(); 51 | process.exit(); 52 | } 53 | })); 54 | //# sourceMappingURL=sw-db-sync.js.map -------------------------------------------------------------------------------- /dist/sw-db-sync.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"sw-db-sync.js","sourceRoot":"","sources":["../src/sw-db-sync.ts"],"names":[],"mappings":";;;AAAA,kEAA+B;AAC/B,qEAA4C;AAC5C,oDAAoB;AACpB,aAAa;AACb,2DAAmD;AACnD,6CAAsC;AACtC,gFAAgD;AAEhD,IAAA,qCAAgB,EAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAO,IAAS,EAAE,EAAE;IACpD,yEAAyE;IACzE,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,aAAa,GAAG;QAChB,sBAAsB;QACtB,+BAA+B;QAC/B,kCAAkC;KACrC,CAAC;IAEF,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC5B,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3B,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;gBACvC,IAAA,eAAK,EAAC,GAAG,IAAI,+CAA+C,OAAO,IAAI,IAAI,GAAG,CAAC,CAAC;gBAChF,YAAY,GAAG,IAAI,CAAC;YACxB,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,4DAA4D;IAC5D,IAAI,YAAY,EAAE,CAAC;QACf,OAAO;IACX,CAAC;IAED,IAAA,eAAa,EAAC,mBAAO,CAAC,CAAC;IAEvB,8DAA8D;IAC9D,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;IAC9C,IAAI,YAAY,GAAG,IAAI,sBAAY,EAAE,CAAC;IACtC,MAAM,YAAY,CAAC,eAAe,EAAE,CAAC;IACrC,IAAI,WAAW,GAAG,sCAAsC,WAAW,CAAC,OAAO,EAAE,CAAC;IAC9E,IAAI,YAAY,CAAC,MAAM,CAAC,cAAc,GAAG,YAAY,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QACzE,WAAW,GAAG,GAAG,WAAW,kEAAkE,YAAY,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;IACtI,CAAC;IAED,mBAAO;SACF,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;SAC5B,KAAK,CAAC,qBAAqB,CAAC;SAC5B,WAAW,CAAC,WAAW,CAAC,CAAA;IAE7B,mBAAO,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,mBAAO,CAAC,IAAI,EAAE,CAAA;IAClB,CAAC,CAAC,CAAA;IAEF,mBAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAE3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAChC,mBAAO,CAAC,UAAU,EAAE,CAAA;QACpB,OAAO,CAAC,IAAI,EAAE,CAAA;IAClB,CAAC;AACL,CAAC,CAAA,CAAC,CAAC"} -------------------------------------------------------------------------------- /dist/tasks/checksTask.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const fs = tslib_1.__importStar(require("fs")); 5 | const settings_json_1 = tslib_1.__importDefault(require("../../config/settings.json")); 6 | class ChecksTask { 7 | constructor() { 8 | this.checkTasks = []; 9 | this.configure = (list, config, ssh) => tslib_1.__awaiter(this, void 0, void 0, function* () { 10 | yield this.addTasks(list, config, ssh); 11 | return list; 12 | }); 13 | // Add tasks 14 | this.addTasks = (list, config, ssh) => tslib_1.__awaiter(this, void 0, void 0, function* () { 15 | list.add({ 16 | title: 'Running some checks', 17 | task: (ctx, task) => task.newListr(this.checkTasks) 18 | }); 19 | if (config.settings.import && config.settings.import == 'yes') { 20 | // Check if all settings are filled in, if we import 21 | this.checkTasks.push({ 22 | title: 'Checking if config/settings.json is correctly filled', 23 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 24 | // Lets make sure everything is filled in 25 | if (!settings_json_1.default.shopwareBackend.adminUsername || settings_json_1.default.shopwareBackend.adminUsername && settings_json_1.default.shopwareBackend.adminUsername.length == 0) { 26 | throw new Error('Admin username is missing config/settings.json'); 27 | } 28 | if (!settings_json_1.default.shopwareBackend.adminPassword || settings_json_1.default.shopwareBackend.adminPassword && settings_json_1.default.shopwareBackend.adminPassword.length == 0) { 29 | throw new Error('Admin password is missing in config/settings.json'); 30 | } 31 | if (!settings_json_1.default.shopwareBackend.adminEmailAddress || settings_json_1.default.shopwareBackend.adminEmailAddress && settings_json_1.default.shopwareBackend.adminEmailAddress.length == 0) { 32 | throw new Error('Admin email address is missing in config/settings.json'); 33 | } 34 | }) 35 | }); 36 | if (config.settings.import && config.settings.import == 'yes') { 37 | // Check if target folder exists before downloading 38 | this.checkTasks.push({ 39 | title: 'Checking if .env file exists', 40 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 41 | let envFileLocation = config.settings.currentFolder + '/.env'; 42 | if (fs.existsSync(envFileLocation)) { 43 | return true; 44 | } 45 | throw new Error(`.env is missing, make sure ${envFileLocation} exists.`); 46 | }) 47 | }); 48 | } 49 | } 50 | // Check if target folder exists before downloading 51 | this.checkTasks.push({ 52 | title: 'Checking if download folder exists', 53 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 54 | if (fs.existsSync(config.customConfig.localDatabaseFolderLocation)) { 55 | return true; 56 | } 57 | throw new Error(`Download folder ${config.customConfig.localDatabaseFolderLocation} does not exist. This can be configured in config/settings.json`); 58 | }) 59 | }); 60 | // Check if SSH key exists 61 | this.checkTasks.push({ 62 | title: 'Checking if SSH key exists', 63 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 64 | if (fs.existsSync(config.customConfig.sshKeyLocation)) { 65 | return true; 66 | } 67 | throw new Error(`SSH key ${config.customConfig.sshKeyLocation} does not exist. This can be configured in config/settings.json`); 68 | }) 69 | }); 70 | }); 71 | } 72 | } 73 | exports.default = ChecksTask; 74 | //# sourceMappingURL=checksTask.js.map -------------------------------------------------------------------------------- /dist/tasks/checksTask.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"checksTask.js","sourceRoot":"","sources":["../../src/tasks/checksTask.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/tasks/downloadTask.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const console_1 = require("../utils/console"); 5 | // @ts-ignore 6 | class DownloadTask { 7 | constructor() { 8 | this.downloadTasks = []; 9 | this.configure = (list, config, ssh) => tslib_1.__awaiter(this, void 0, void 0, function* () { 10 | yield this.addTasks(list, config, ssh); 11 | return list; 12 | }); 13 | // Add tasks 14 | this.addTasks = (list, config, ssh) => tslib_1.__awaiter(this, void 0, void 0, function* () { 15 | list.add({ 16 | title: 'Download database from server ' + '(' + config.databases.databaseData.username + ')', 17 | task: (ctx, task) => task.newListr(this.downloadTasks) 18 | }); 19 | this.downloadTasks.push({ 20 | title: 'Connecting to server through SSH', 21 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 22 | // Open connection to SSH server 23 | yield ssh.connect({ 24 | host: config.databases.databaseData.server, 25 | password: config.databases.databaseData.password, 26 | username: config.databases.databaseData.username, 27 | port: config.databases.databaseData.port, 28 | privateKey: config.customConfig.sshKeyLocation, 29 | passphrase: config.customConfig.sshPassphrase 30 | }); 31 | }) 32 | }); 33 | this.downloadTasks.push({ 34 | title: 'Retrieving server settings', 35 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 36 | // Retrieve settings from server to use 37 | yield ssh.execCommand((0, console_1.sshNavigateToShopwareRootCommand)('pwd; which php;', config)).then((result) => { 38 | if (result) { 39 | let serverValues = result.stdout.split("\n"); 40 | config.serverVariables.shopwareRoot = serverValues[0]; 41 | // Get PHP path 42 | config.serverVariables.externalPhpPath = serverValues[1]; 43 | } 44 | }); 45 | // Use custom PHP path instead if given 46 | if (config.databases.databaseData.externalPhpPath && config.databases.databaseData.externalPhpPath.length > 0) { 47 | config.serverVariables.externalPhpPath = config.databases.databaseData.externalPhpPath; 48 | } 49 | }) 50 | }); 51 | this.downloadTasks.push({ 52 | title: 'Downloading Shopware6 DB Dump File to server', 53 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 54 | yield ssh.execCommand((0, console_1.sshNavigateToShopwareRootCommand)('curl -O https://raw.githubusercontent.com/jellesiderius/shopware6-database-dump/main/shopware6-database-dump.sh', config)); 55 | }) 56 | }); 57 | this.downloadTasks.push({ 58 | title: 'Dumping Shopware database and moving it to server root (' + config.settings.strip + ')', 59 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 60 | var username = '', password = '', host = '', port = '', database = ''; 61 | // Retrieve database name 62 | yield ssh.execCommand((0, console_1.sshNavigateToShopwareRootCommand)('cat .env | grep "DATABASE_URL="', config)).then((result) => { 63 | if (result) { 64 | var resultValues = result.stdout, databaseDetails = (0, console_1.extractDatabaseDetails)(resultValues); 65 | username = databaseDetails.username; 66 | password = databaseDetails.password; 67 | host = databaseDetails.host; 68 | port = databaseDetails.port; 69 | database = databaseDetails.database; 70 | config.settings.databaseFileName = database; 71 | } 72 | }); 73 | // Dump database 74 | var dumpCommand = `/bin/bash shopware6-database-dump.sh -d ${database} -u ${username} -pa ${password} --host ${host} -p ${port} --gdpr`; 75 | if (config.settings.strip == 'full') { 76 | dumpCommand = `/bin/bash shopware6-database-dump.sh -d ${database} -u ${username} -pa ${password} --host ${host} -p ${port}`; 77 | } 78 | yield ssh.execCommand((0, console_1.sshNavigateToShopwareRootCommand)(`${dumpCommand}; mv ${config.settings.databaseFileName}.sql ~`, config)); 79 | }) 80 | }); 81 | this.downloadTasks.push({ 82 | title: 'Downloading Shopware 6 database to localhost', 83 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 84 | // Download file and place it on localhost 85 | let localDatabaseFolderLocation = config.customConfig.localDatabaseFolderLocation; 86 | let localDatabaseLocation = localDatabaseFolderLocation + `/${config.settings.databaseFileName}.sql`; 87 | if (config.settings.rsyncInstalled) { 88 | yield (0, console_1.localhostRsyncDownloadCommand)(`~/${config.settings.databaseFileName}.sql`, `${localDatabaseFolderLocation}`, config); 89 | } 90 | else { 91 | yield ssh.getFile(localDatabaseLocation, config.settings.databaseFileName + '.sql').then(function (Contents) { 92 | }, function (error) { 93 | throw new Error(error); 94 | }); 95 | } 96 | // Set final message with Shopware 6 DB location 97 | config.finalMessages.shopwareDatabaseLocation = localDatabaseLocation; 98 | config.settings.databaseFullPath = localDatabaseFolderLocation; 99 | }) 100 | }); 101 | this.downloadTasks.push({ 102 | title: 'Cleaning up and closing SSH connection', 103 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 104 | // Remove the Shopware 6 database file on the server 105 | yield ssh.execCommand(`rm ${config.settings.databaseFileName}.sql`); 106 | // Remove database dump file and close connection to SSH 107 | yield ssh.execCommand((0, console_1.sshNavigateToShopwareRootCommand)('rm shopware6-database-dump.sh', config)); 108 | // Close the SSH connection 109 | yield ssh.dispose(); 110 | }) 111 | }); 112 | }); 113 | } 114 | } 115 | exports.default = DownloadTask; 116 | //# sourceMappingURL=downloadTask.js.map -------------------------------------------------------------------------------- /dist/tasks/downloadTask.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"downloadTask.js","sourceRoot":"","sources":["../../src/tasks/downloadTask.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/tasks/importTask.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const console_1 = require("../utils/console"); 5 | class ImportTask { 6 | constructor() { 7 | this.importTasks = []; 8 | this.configure = (list, config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 9 | yield this.addTasks(list, config); 10 | return list; 11 | }); 12 | // Add tasks 13 | this.addTasks = (list, config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 14 | list.add({ 15 | title: 'Import Shopware database to localhost', 16 | task: (ctx, task) => task.newListr(this.importTasks) 17 | }); 18 | this.importTasks.push({ 19 | title: 'Getting localhost .env info', 20 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 21 | yield (0, console_1.localhostShopwareRootExec)(`cat .env | grep "DATABASE_URL="`, config).then((result) => { 22 | if (result) { 23 | var databaseDetails = (0, console_1.extractDatabaseDetails)(result); 24 | config.localhost.username = databaseDetails.username; 25 | config.localhost.password = databaseDetails.password; 26 | config.localhost.host = databaseDetails.host; 27 | config.localhost.port = databaseDetails.port; 28 | config.localhost.database = databaseDetails.database; 29 | } 30 | }); 31 | yield (0, console_1.localhostShopwareRootExec)(`cat .env | grep "APP_URL="`, config).then((result) => { 32 | if (result) { 33 | var appUrl = result, splittedAppUrl = appUrl.split('//'), appUrlFromArray = splittedAppUrl[1].replace('"', '').trim(); 34 | config.localhost.domainUrl = appUrlFromArray; 35 | // Determine http or https 36 | if (appUrl.indexOf('https') !== -1) { 37 | config.localhost.https = true; 38 | } 39 | } 40 | }); 41 | }) 42 | }); 43 | this.importTasks.push({ 44 | title: 'Importing database to localhost', 45 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 46 | // Drop database 47 | yield (0, console_1.localhostShopwareRootExec)(`mysqladmin -u ${config.localhost.username} --password=${config.localhost.password} drop ${config.localhost.database} -f`, config, true); 48 | // Create database 49 | yield (0, console_1.localhostShopwareRootExec)(`mysqladmin -u ${config.localhost.username} --password=${config.localhost.password} create ${config.localhost.database} -f`, config, true); 50 | // Import database 51 | yield (0, console_1.localhostShopwareRootExec)(`mysql -u ${config.localhost.username} --password=${config.localhost.password} ${config.localhost.database} --force < ${config.settings.databaseFullPath}/${config.settings.databaseFileName}.sql`, config, true); 52 | }) 53 | }); 54 | if (config.settings.syncImages == 'yes') { 55 | this.importTasks.push({ 56 | title: 'Synchronizing public/media & public/thumbnail', 57 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 58 | // Sync media 59 | yield (0, console_1.localhostShopwareRootExec)(`rsync -avz -e "ssh -p ${config.databases.databaseData.port}" ${config.databases.databaseData.username}@${config.databases.databaseData.server}:${config.serverVariables.shopwareRoot}/public/media/* public/media/`, config, true, false, true); 60 | // Sync thumbnail 61 | yield (0, console_1.localhostShopwareRootExec)(`rsync -avz -e "ssh -p ${config.databases.databaseData.port}" ${config.databases.databaseData.username}@${config.databases.databaseData.server}:${config.serverVariables.shopwareRoot}/public/thumbnail/* public/thumbnail/`, config, true, false, true); 62 | }) 63 | }); 64 | } 65 | this.importTasks.push({ 66 | title: 'Cleaning up', 67 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 68 | // Remove local SQL file 69 | yield (0, console_1.localhostShopwareRootExec)(`rm ${config.settings.databaseFileName}.sql`, config); 70 | }) 71 | }); 72 | }); 73 | } 74 | } 75 | exports.default = ImportTask; 76 | //# sourceMappingURL=importTask.js.map -------------------------------------------------------------------------------- /dist/tasks/importTask.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"importTask.js","sourceRoot":"","sources":["../../src/tasks/importTask.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/tasks/shopwareConfigureTask.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | const console_1 = require("../utils/console"); 5 | const settings_json_1 = tslib_1.__importDefault(require("../../config/settings.json")); 6 | class ShopwareConfigureTask { 7 | constructor() { 8 | this.configureTasks = []; 9 | this.configure = (list, config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 10 | yield this.addTasks(list, config); 11 | return list; 12 | }); 13 | // Add tasks 14 | this.addTasks = (list, config) => tslib_1.__awaiter(this, void 0, void 0, function* () { 15 | list.add({ 16 | title: 'Configuring Shopware 6 for development usage', 17 | task: (ctx, task) => task.newListr(this.configureTasks) 18 | }); 19 | this.configureTasks.push({ 20 | title: "Setting URL for sales channels", 21 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 22 | yield (0, console_1.localhostShopwareRootExec)(`bin/console sales-channel:update:domain ${config.localhost.domainUrl}`, config); 23 | if (config.localhost.https) { 24 | yield (0, console_1.localhostShopwareRootMysqlExec)("UPDATE sales_channel_domain SET url = REPLACE(url,'http://', 'https://')", config); 25 | config.finalMessages.importDomain = `https://${config.localhost.domainUrl}`; 26 | } 27 | else { 28 | yield (0, console_1.localhostShopwareRootMysqlExec)("UPDATE sales_channel_domain SET url = REPLACE(url,'https://', 'http://')", config); 29 | config.finalMessages.importDomain = `http://${config.localhost.domainUrl}`; 30 | } 31 | }) 32 | }); 33 | if (config.settings.syncImages == 'no') { 34 | this.configureTasks.push({ 35 | title: "Emptying media tables", 36 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 37 | // Product media 38 | yield (0, console_1.localhostShopwareRootMysqlExec)('TRUNCATE TABLE product_media', config); 39 | // Theme media 40 | yield (0, console_1.localhostShopwareRootMysqlExec)('TRUNCATE TABLE theme_media', config); 41 | }) 42 | }); 43 | } 44 | this.configureTasks.push({ 45 | title: "Refreshing plugins", 46 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 47 | yield (0, console_1.localhostShopwareRootExec)(`bin/console plugin:refresh`, config); 48 | }) 49 | }); 50 | this.configureTasks.push({ 51 | title: "Compiling theme", 52 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 53 | yield (0, console_1.localhostShopwareRootExec)(`bin/console theme:compile`, config); 54 | }) 55 | }); 56 | this.configureTasks.push({ 57 | title: 'Creating a admin user', 58 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 59 | yield (0, console_1.localhostShopwareRootExec)(`bin/console user:create -a ${settings_json_1.default.shopwareBackend.adminUsername} -p ${settings_json_1.default.shopwareBackend.adminPassword} --email ${settings_json_1.default.shopwareBackend.adminEmailAddress}`, config); 60 | }) 61 | }); 62 | this.configureTasks.push({ 63 | title: 'Reindexing Shopware (ES)', 64 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 65 | // Reindex 66 | yield (0, console_1.localhostShopwareRootExec)(`bin/console es:index -n`, config); 67 | // Reset indexes 68 | yield (0, console_1.localhostShopwareRootExec)(`bin/console es:reset -n`, config); 69 | }) 70 | }); 71 | this.configureTasks.push({ 72 | title: 'Flushing Shopware 6 caches', 73 | task: () => tslib_1.__awaiter(this, void 0, void 0, function* () { 74 | // Flush the shopware caches and import config data 75 | yield (0, console_1.localhostShopwareRootExec)(`bin/console cache:clear`, config); 76 | }) 77 | }); 78 | }); 79 | } 80 | } 81 | exports.default = ShopwareConfigureTask; 82 | //# sourceMappingURL=shopwareConfigureTask.js.map -------------------------------------------------------------------------------- /dist/tasks/shopwareConfigureTask.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"shopwareConfigureTask.js","sourceRoot":"","sources":["../../src/tasks/shopwareConfigureTask.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/utils/console.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.localhostShopwareRootMysqlExec = exports.extractDatabaseDetails = exports.localhostRsyncDownloadCommand = exports.localhostShopwareRootExec = exports.sshNavigateToShopwareRootCommand = exports.consoleCommand = exports.clearConsole = exports.emptyLine = exports.url = exports.error = exports.warning = exports.success = exports.info = exports.verbose = void 0; 4 | const tslib_1 = require("tslib"); 5 | const kleur_1 = tslib_1.__importDefault(require("kleur")); 6 | const readline = tslib_1.__importStar(require("readline")); 7 | const prefix = { 8 | verbose: kleur_1.default.gray(kleur_1.default.bold('🛠 ')), 9 | info: kleur_1.default.gray(kleur_1.default.bold('✨ ')), 10 | success: kleur_1.default.gray(kleur_1.default.bold('✅ ')), 11 | warning: kleur_1.default.yellow(kleur_1.default.bold('⚠️ Warning: ')), 12 | error: kleur_1.default.red(kleur_1.default.bold('🚨 Error: ')), 13 | }; 14 | const body = { 15 | default: kleur_1.default.white, 16 | verbose: kleur_1.default.gray, 17 | warning: kleur_1.default.yellow, 18 | error: kleur_1.default.red 19 | }; 20 | const log = (prefix, body) => { 21 | let out = prefix; 22 | out = out.concat(body); 23 | console.log(out); 24 | }; 25 | const verbose = (message) => { 26 | log(prefix.verbose, body.verbose(message)); 27 | }; 28 | exports.verbose = verbose; 29 | const info = (message) => { 30 | log(prefix.info, body.default(message)); 31 | }; 32 | exports.info = info; 33 | const warning = (message) => { 34 | log(prefix.warning, body.warning(message)); 35 | }; 36 | exports.warning = warning; 37 | const error = (message) => { 38 | log(prefix.error, body.error(message)); 39 | }; 40 | exports.error = error; 41 | const success = (message) => { 42 | log(prefix.success, body.default(message)); 43 | }; 44 | exports.success = success; 45 | const url = (url) => { 46 | return kleur_1.default.bold(kleur_1.default.underline(url)); 47 | }; 48 | exports.url = url; 49 | const emptyLine = () => { 50 | console.log(''); 51 | }; 52 | exports.emptyLine = emptyLine; 53 | const clearConsole = () => { 54 | const blank = '\n'.repeat(process.stdout.rows); 55 | console.log(blank); 56 | readline.cursorTo(process.stdout, 0, 0); 57 | readline.clearScreenDown(process.stdout); 58 | }; 59 | exports.clearConsole = clearConsole; 60 | const consoleCommand = (cmd, skipErrors) => { 61 | const exec = require('child_process').exec; 62 | return new Promise((resolve, reject) => { 63 | exec(cmd, (error, stdout, stderr) => { 64 | if (error && !skipErrors) { 65 | // @ts-ignore 66 | throw new Error(error); 67 | process.exit(); 68 | } 69 | resolve(stdout ? stdout : stderr); 70 | }); 71 | }); 72 | }; 73 | exports.consoleCommand = consoleCommand; 74 | // Navigate to Shopware root folder 75 | const sshNavigateToShopwareRootCommand = (command, config) => { 76 | // See if external project folder is filled in, otherwise try default path 77 | if (config.databases.databaseData.externalProjectFolder && config.databases.databaseData.externalProjectFolder.length > 0) { 78 | return `cd ${config.databases.databaseData.externalProjectFolder} > /dev/null 2>&1; ${command}`; 79 | } 80 | else { 81 | return 'cd domains > /dev/null 2>&1;' + 82 | 'cd ' + config.databases.databaseData.domainFolder + ' > /dev/null 2>&1;' + 83 | 'cd application > /dev/null 2>&1;' + 84 | 'cd public_html > /dev/null 2>&1;' + 85 | 'cd current > /dev/null 2>&1;' + command; 86 | } 87 | }; 88 | exports.sshNavigateToShopwareRootCommand = sshNavigateToShopwareRootCommand; 89 | const localhostShopwareRootExec = (command, config, skipErrors = false, noExec = false, skipDdev = false) => { 90 | if (config.settings.isDdevActive && !skipDdev) { 91 | if (noExec) { 92 | return consoleCommand(`cd ${config.settings.currentFolder}; ddev ${command};`, skipErrors); 93 | } 94 | return consoleCommand(`cd ${config.settings.currentFolder}; ddev exec ${command};`, skipErrors); 95 | } 96 | return consoleCommand(`cd ${config.settings.currentFolder}; ${command};`, skipErrors); 97 | }; 98 | exports.localhostShopwareRootExec = localhostShopwareRootExec; 99 | const localhostRsyncDownloadCommand = (source, destination, config) => { 100 | let sshCommand; 101 | config.databases.databaseData.port ? sshCommand = `ssh -p ${config.databases.databaseData.port} -o StrictHostKeyChecking=no` : sshCommand = `ssh -o StrictHostKeyChecking=no`; 102 | let totalRsyncCommand = `rsync -avz -e "${sshCommand}" ${config.databases.databaseData.username}@${config.databases.databaseData.server}:${source} ${destination}`; 103 | // If password is set, use sshpass 104 | if (config.databases.databaseData.password) { 105 | totalRsyncCommand = `sshpass -p "${config.databases.databaseData.password}" ` + totalRsyncCommand; 106 | } 107 | return consoleCommand(totalRsyncCommand, false); 108 | }; 109 | exports.localhostRsyncDownloadCommand = localhostRsyncDownloadCommand; 110 | const localhostShopwareRootMysqlExec = (command, config, skipErrors = false) => { 111 | let noExec = false; 112 | if (config.settings.isDdevActive) { 113 | noExec = true; 114 | } 115 | return localhostShopwareRootExec(`mysql -u ${config.localhost.username} --password=${config.localhost.password} ${config.localhost.database} -e "${command}"`, config, skipErrors, noExec); 116 | }; 117 | exports.localhostShopwareRootMysqlExec = localhostShopwareRootMysqlExec; 118 | const extractDatabaseDetails = (string) => { 119 | var details = string, details = details.replace('DATABASE_URL="mysql', '').replace('DATABASE_URL=mysql', '').replace('//', '').replace('"', '').replace('@', ':').replace('/', ':'), details = details.split(':'), details = details.filter((a) => a); 120 | let detailsObject = { 121 | username: details[0].trim(), 122 | password: details[1].replace('$', '\\$').replace(/"/g, '\'').trim(), 123 | host: details[2].trim(), 124 | port: details[3].trim(), 125 | database: details[4].trim() 126 | }; 127 | return detailsObject; 128 | }; 129 | exports.extractDatabaseDetails = extractDatabaseDetails; 130 | //# sourceMappingURL=console.js.map -------------------------------------------------------------------------------- /dist/utils/console.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/utils/console.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/utils/versionCheck.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const tslib_1 = require("tslib"); 4 | // @ts-ignore 5 | const package_json_1 = tslib_1.__importDefault(require("../../package.json")); 6 | // @ts-ignore 7 | const fetch = tslib_1.__importStar(require("node-fetch")); 8 | class VersionCheck { 9 | constructor() { 10 | this.config = { 11 | 'latestVersion': '', 12 | 'currentVersion': package_json_1.default.version 13 | }; 14 | // versions 15 | this.getToolVersions = () => tslib_1.__awaiter(this, void 0, void 0, function* () { 16 | yield fetch('https://raw.githubusercontent.com/sidworks-dev/sw-db-sync/master/package.json') 17 | .then((res) => res.json()) 18 | .then((json) => this.config.latestVersion = json.version); 19 | }); 20 | } 21 | } 22 | exports.default = VersionCheck; 23 | //# sourceMappingURL=versionCheck.js.map 24 | -------------------------------------------------------------------------------- /dist/utils/versionCheck.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"versionCheck.js","sourceRoot":"","sources":["../../src/utils/versionCheck.ts"],"names":[],"mappings":";;;AAAA,aAAa;AACb,8EAA6C;AAC7C,aAAa;AACb,0DAAmC;AAEnC,MAAM,YAAY;IAAlB;QACQ,WAAM,GAAG;YACf,eAAe,EAAE,EAAE;YACnB,gBAAgB,EAAE,sBAAW,CAAC,OAAO;SACrC,CAAA;QAED,WAAW;QACX,oBAAe,GAAG,GAAS,EAAE;YAC5B,MAAM,KAAK,CAAC,gFAAgF,CAAC;iBAC3F,IAAI,CAAC,CAAC,GAAyB,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;iBAC/C,IAAI,CAAC,CAAC,IAA0B,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAClF,CAAC,CAAA,CAAA;IACF,CAAC;CAAA;AAED,kBAAe,YAAY,CAAC"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sw-db-sync", 3 | "version": "0.2.1", 4 | "description": "Database synchronizer for Shopware 6", 5 | "author": { 6 | "name": "Jelle Siderius" 7 | }, 8 | "main": "./src/sw-db-sync.js", 9 | "bin": { 10 | "sw-db-sync": "bin/sw-db-sync.js" 11 | }, 12 | "preferGlobal": true, 13 | "devDependencies": { 14 | "@types/command-exists": "^1.2.0", 15 | "@types/commander": "^2.12.2", 16 | "@types/get-installed-path": "^4.0.1", 17 | "@types/inquirer": "^7.3.1", 18 | "@types/node": "^14.17.34", 19 | "@types/shelljs": "^0.8.11", 20 | "@types/ssh2": "^0.5.48", 21 | "@types/ssh2-streams": "^0.1.9", 22 | "@typescript-eslint/eslint-plugin": "^4.33.0", 23 | "@typescript-eslint/parser": "^4.33.0", 24 | "delay": "^5.0.0", 25 | "eslint": "^7.32.0", 26 | "ts-node": "^9.1.0", 27 | "typescript": "^4.5.2" 28 | }, 29 | "dependencies": { 30 | "command-exists": "^1.2.9", 31 | "commander": "^7.0.0", 32 | "download-git-repo": "^3.0.2", 33 | "execa": "^5.0.0", 34 | "get-installed-path": "^4.0.8", 35 | "inquirer": "^7.3.3", 36 | "inquirer-search-checkbox": "^1.0.0", 37 | "inquirer-search-list": "^1.2.6", 38 | "kleur": "^4.1.3", 39 | "listr2": "^3.13.5", 40 | "node-fetch": "^2.6.6", 41 | "node-ssh": "^11.1.1", 42 | "shelljs": "^0.8.5", 43 | "tslib": "^2.7.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/commands/index.ts: -------------------------------------------------------------------------------- 1 | import commander from 'commander' 2 | import fs from 'fs' 3 | import path from 'path' 4 | 5 | // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types 6 | export default function (program: typeof commander): commander.Command[] { 7 | const commands: commander.Command[] = [] 8 | const loadPath = path.dirname(__filename) 9 | 10 | // Loop through command files 11 | fs.readdirSync(loadPath).filter(function (filename) { 12 | return (/\.js$/.test(filename) && filename !== 'index.js') 13 | }).forEach(function (filename) { 14 | // const name: string = filename.substr(0, filename.lastIndexOf('.')) 15 | 16 | // Require command 17 | // eslint-disable-next-line @typescript-eslint/no-var-requires 18 | const command = require(path.join(loadPath, filename)) 19 | 20 | // Initialize command 21 | commands.push(command.default(program)) 22 | }) 23 | 24 | return commands 25 | } -------------------------------------------------------------------------------- /src/commands/selfUpdateCommand.ts: -------------------------------------------------------------------------------- 1 | import commander from 'commander' 2 | import {error} from '../utils/console' 3 | import SelfUpdateController from "../controllers/selfUpdateController"; 4 | 5 | export default (program: typeof commander): commander.Command => program 6 | .command('self-update') 7 | .description('Updates the database synchronizer to the latest version') 8 | .action((service: string | undefined) => { 9 | (new SelfUpdateController()).executeStart(service).catch((err: any) => error(err.message)) 10 | }) 11 | -------------------------------------------------------------------------------- /src/commands/startCommand.ts: -------------------------------------------------------------------------------- 1 | import commander from 'commander' 2 | import ImportController from '../controllers/startController' 3 | import {error} from '../utils/console' 4 | 5 | export default (program: typeof commander): commander.Command => program 6 | .command('start') 7 | .description('Starts the database synchronizer') 8 | .action((service: string | undefined) => { 9 | (new ImportController()).executeStart(service).catch(err => error(err.message)) 10 | }) -------------------------------------------------------------------------------- /src/controllers/mainController.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import configFile from '../../config/settings.json' 3 | import {NodeSSH} from 'node-ssh' 4 | import DatabasesModel from "../models/databasesModel"; 5 | import * as os from 'os' 6 | import * as path from 'path' 7 | import { Listr } from 'listr2'; 8 | import CommandExists from 'command-exists'; 9 | import inquirer from 'inquirer' 10 | inquirer.registerPrompt("search-list", require("../../node_modules/inquirer-search-list")); 11 | 12 | 13 | class MainController { 14 | public config = { 15 | 'customConfig': { 16 | 'sshKeyLocation': configFile.ssh.keyLocation, 17 | 'sshPassphrase': configFile.ssh.passphrase, 18 | 'localDatabaseFolderLocation': configFile.general.databaseLocation 19 | }, 20 | 'serverVariables': { 21 | 'externalPhpPath': '', 22 | 'shopwareRoot': '', 23 | 'databaseName': '' 24 | }, 25 | 'settings': { 26 | 'currentFolder': '', 27 | 'currentFolderName': '', 28 | 'databaseFileName': '', 29 | 'databaseFullPath': '', 30 | 'strip': '', 31 | 'syncImages': 'no', 32 | 'rsyncInstalled': false, 33 | 'import': 'no', 34 | 'currentFolderIsShopware': false, 35 | 'isDdevActive': false 36 | }, 37 | 'localhost': { 38 | 'username': '', 39 | 'password': '', 40 | 'host': '', 41 | 'port': '', 42 | 'database': '', 43 | 'domainUrl': '', 44 | 'https': false 45 | }, 46 | 'finalMessages': { 47 | 'shopwareDatabaseLocation': '', 48 | 'importDomain': '' 49 | }, 50 | 'databases': { 51 | 'databasesList': null, 52 | 'databaseType': null, 53 | 'databaseData': null 54 | } 55 | }; 56 | public list = new Listr( 57 | [], 58 | {concurrent: false} 59 | ); 60 | public ssh = new NodeSSH(); 61 | public databases = new DatabasesModel(); 62 | 63 | constructor() { 64 | this.configureConfig().then(); 65 | } 66 | 67 | configureConfig = async () => { 68 | // Fetch SSH key location, if non configured 69 | if (!this.config.customConfig.sshKeyLocation) { 70 | this.config.customConfig.sshKeyLocation = os.userInfo().homedir + '/.ssh/id_rsa'; 71 | } 72 | 73 | // Check if rsync is installed locally 74 | await CommandExists('rsync') 75 | .then((command) =>{ 76 | this.config.settings.rsyncInstalled = true; 77 | }).catch(function(){}); 78 | 79 | // Get current folder from cwd 80 | this.config.settings.currentFolder = process.cwd(); 81 | 82 | // Set current folder name based on current folder 83 | this.config.settings.currentFolderName = path.basename(path.resolve(this.config.settings.currentFolder)); 84 | } 85 | } 86 | 87 | export default MainController 88 | -------------------------------------------------------------------------------- /src/controllers/selfUpdateController.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import download from 'download-git-repo' 3 | // @ts-ignore 4 | import {getInstalledPath} from 'get-installed-path' 5 | import {consoleCommand, success} from "../utils/console"; 6 | // @ts-ignore 7 | import packageFile from '../../package.json'; 8 | import VersionCheck from "../utils/versionCheck"; 9 | 10 | class SelfUpdateController { 11 | private versionCheck = new VersionCheck(); 12 | 13 | executeStart = async (serviceName: string | undefined): Promise => { 14 | //await this.versionCheck.getToolVersions(); 15 | 16 | let self = this; 17 | let config = { 18 | 'npmPath': '', 19 | 'currentVersion': this.versionCheck.config.currentVersion, 20 | 'latestVersion': this.versionCheck.config.latestVersion 21 | }; 22 | 23 | await getInstalledPath('sw-db-sync').then((path: string) => { 24 | config.npmPath = path; 25 | }); 26 | 27 | if (config.currentVersion < config.latestVersion) { 28 | await consoleCommand(`cd ${config.npmPath}; rm -rf dist`, false); 29 | 30 | await download('sidworks-dev/sw-db-sync#master', config.npmPath, async function (err: any) { 31 | await consoleCommand(`cd ${config.npmPath}; npm install`, false); 32 | success(`Updated sw-db-sync from ${config.currentVersion} to ${config.latestVersion}`); 33 | }); 34 | } else { 35 | success(`sw-db-sync is already up to date`); 36 | } 37 | 38 | return true; 39 | } 40 | } 41 | 42 | export default SelfUpdateController 43 | -------------------------------------------------------------------------------- /src/controllers/startController.ts: -------------------------------------------------------------------------------- 1 | import { clearConsole, info, success } from "../utils/console"; 2 | // @ts-ignore 3 | import configFile from '../../config/settings.json' 4 | import MainController from "./mainController"; 5 | import DatabaseTypeQuestion from "../questions/databaseTypeQuestion"; 6 | import SelectDatabaseQuestion from "../questions/selectDatabaseQuestion"; 7 | import ConfigurationQuestions from "../questions/configurationQuestions"; 8 | import ChecksTask from "../tasks/checksTask"; 9 | import DownloadTask from "../tasks/downloadTask"; 10 | import ImportTask from "../tasks/importTask"; 11 | import ShopwareConfigureTask from "../tasks/shopwareConfigureTask"; 12 | 13 | class StartController extends MainController { 14 | executeStart = async (): Promise => { 15 | // Ask all the questions to the user 16 | await this.askQuestions(); 17 | 18 | // Configure task list 19 | await this.prepareTasks(); 20 | 21 | // Run all tasks 22 | try { 23 | await this.list.run(); 24 | 25 | // Show final message when done with all tasks 26 | if (this.config.finalMessages.importDomain.length > 0) { 27 | success(`Shopware is successfully imported to localhost. ${this.config.finalMessages.importDomain} is now available.`); 28 | info(`You can log in to the Shopware backend with username: ${configFile.shopwareBackend.adminUsername} and password: ${configFile.shopwareBackend.adminPassword}`); 29 | } else if (this.config.finalMessages.shopwareDatabaseLocation.length > 0) { 30 | success(`Downloaded Shopware database to: ${this.config.finalMessages.shopwareDatabaseLocation}`); 31 | } 32 | 33 | process.exit(); 34 | } catch (e) { 35 | console.error(e) 36 | } 37 | } 38 | 39 | // Ask questions to user 40 | askQuestions = async () => { 41 | // Clear the console 42 | clearConsole(); 43 | 44 | // Ask question about database type 45 | let databaseTypeQuestion = await new DatabaseTypeQuestion(); 46 | await databaseTypeQuestion.configure(this.config); 47 | 48 | // Make user choose a database from the list 49 | let selectDatabaseQuestion = await new SelectDatabaseQuestion(); 50 | await selectDatabaseQuestion.configure(this.config); 51 | 52 | // Adds multiple configuration questions 53 | let configurationQuestions = await new ConfigurationQuestions(); 54 | await configurationQuestions.configure(this.config); 55 | 56 | // Clear the console 57 | clearConsole(); 58 | } 59 | 60 | // Configure task list 61 | prepareTasks = async () => { 62 | // Build up check list 63 | let checkTask = await new ChecksTask(); 64 | await checkTask.configure(this.list, this.config); 65 | 66 | // Build up download list 67 | let downloadTask = await new DownloadTask(); 68 | await downloadTask.configure(this.list, this.config, this.ssh); 69 | 70 | // Import Shopware if possible 71 | if (this.config.settings.import && this.config.settings.import == "yes") { 72 | // Build import list 73 | let importTask = await new ImportTask(); 74 | await importTask.configure(this.list, this.config); 75 | 76 | // Build Shopware configure list 77 | let shopwareConfigureTask = await new ShopwareConfigureTask(); 78 | await shopwareConfigureTask.configure(this.list, this.config); 79 | } 80 | } 81 | } 82 | 83 | export default StartController 84 | -------------------------------------------------------------------------------- /src/models/databasesModel.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import stagingDatabases from "../../config/databases/staging.json"; 3 | // @ts-ignore 4 | import productionDatabases from "../../config/databases/production.json"; 5 | 6 | class DatabasesModel { 7 | public databasesList: { [k: string]: any } = []; 8 | public databaseData = { 9 | 'username': '', 10 | 'password': '', 11 | 'server': '', 12 | 'domainFolder': '', 13 | 'port': 22, 14 | 'localProjectFolder': '', 15 | 'externalProjectFolder': '', 16 | 'externalPhpPath': '', 17 | }; 18 | 19 | // Collect databases | collect single database 20 | collectDatabaseData = async (databaseKey: string | void, databaseType: string | void ) => { 21 | // @ts-ignore 22 | var databases = stagingDatabases.databases; 23 | 24 | if (databaseType == 'production') { 25 | // @ts-ignore 26 | databases = productionDatabases.databases; 27 | } 28 | 29 | for (let [key, database] of Object.entries(databases)) { 30 | if (databaseKey == key) { 31 | // Collect single database info 32 | this.databaseData.username = database.username; 33 | // @ts-ignore 34 | this.databaseData.password = database.password; 35 | this.databaseData.server = database.server; 36 | this.databaseData.domainFolder = database.domainFolder; 37 | // @ts-ignore 38 | this.databaseData.port = database.port; 39 | this.databaseData.externalProjectFolder = database.externalProjectFolder; 40 | // @ts-ignore 41 | this.databaseData.externalPhpPath = database.externalPhpPath 42 | } else { 43 | // Collect all database 44 | this.databasesList.push(`${database.domainFolder} / ${database.username} (${key})`); 45 | } 46 | } 47 | } 48 | } 49 | 50 | export default DatabasesModel; 51 | -------------------------------------------------------------------------------- /src/questions/configurationQuestions.ts: -------------------------------------------------------------------------------- 1 | import { error } from "console"; 2 | import inquirer from 'inquirer' 3 | 4 | class ConfigurationQuestions { 5 | private questionsOne = []; 6 | private questionsTwo = []; 7 | 8 | configure = async (config: any) => { 9 | await this.addQuestions(config); 10 | 11 | // Set import configs 12 | await inquirer 13 | .prompt(this.questionsOne) 14 | .then((answers) => { 15 | // Set stripped setting 16 | config.settings.strip = answers.strip; 17 | 18 | // Set import setting for Shopware 19 | config.settings.import = answers.import 20 | 21 | // Set image import setting for Shopware 22 | config.settings.syncImages = answers.syncImages 23 | 24 | // Change location of database download depending on answer 25 | if (config.settings.import == 'yes') { 26 | config.customConfig.localDatabaseFolderLocation = config.settings.currentFolder; 27 | } 28 | }) 29 | .catch((err: { message: any; }) => { 30 | error(`Something went wrong: ${err.message}`) 31 | }); 32 | } 33 | 34 | // Add questions 35 | addQuestions = async (config: any) => { 36 | this.questionsOne.push( 37 | { 38 | type: 'list', 39 | name: 'strip', 40 | default: 'stripped', 41 | message: 'Does the Shopware database need to be stripped for development?', 42 | choices: ['stripped', 'full'], 43 | validate: (input: string) => { 44 | return input !== '' 45 | } 46 | } 47 | ); 48 | 49 | // Only push questions if Shopware project is found 50 | if (config.settings.currentFolderIsShopware) { 51 | this.questionsOne.push( 52 | { 53 | type: 'list', 54 | name: 'import', 55 | default: 'yes', 56 | message: 'Import Shopware database?', 57 | choices: ['yes', 'no'], 58 | validate: (input: string) => { 59 | return false; 60 | }, 61 | } 62 | ); 63 | 64 | if (config.settings.rsyncInstalled) { 65 | this.questionsOne.push( 66 | { 67 | type: 'list', 68 | name: 'syncImages', 69 | default: 'yes', 70 | message: 'Synchronize images from public/media?', 71 | choices: ['yes', 'no'], 72 | validate: (input: string) => { 73 | return false; 74 | }, 75 | } 76 | ); 77 | } 78 | } 79 | } 80 | } 81 | 82 | export default ConfigurationQuestions 83 | -------------------------------------------------------------------------------- /src/questions/databaseTypeQuestion.ts: -------------------------------------------------------------------------------- 1 | import { error } from "console"; 2 | import inquirer from 'inquirer' 3 | import DatabasesModel from "../models/databasesModel"; 4 | 5 | class DatabaseTypeQuestion { 6 | private databasesModel = new DatabasesModel(); 7 | private questions = []; 8 | 9 | configure = async (config: any) => { 10 | await this.addQuestions(config); 11 | 12 | // Set database type 13 | await inquirer 14 | .prompt(this.questions) 15 | .then((answers: { databaseType: any; }) => { 16 | // Set the database type 17 | config.databases.databaseType = answers.databaseType; 18 | 19 | // Collect databases 20 | this.databasesModel.collectDatabaseData('', answers.databaseType); 21 | 22 | // Set database list 23 | config.databases.databasesList = this.databasesModel.databasesList; 24 | }) 25 | .catch((err: { message: any; }) => { 26 | error(`Something went wrong: ${err.message}`) 27 | }); 28 | } 29 | 30 | // Add questions 31 | addQuestions = async (config: any) => { 32 | this.questions.push( 33 | { 34 | type: 'list', 35 | name: 'databaseType', 36 | message: 'Set database type', 37 | default: 'staging', 38 | choices: ['staging', 'production'], 39 | validate: (input: string) => { 40 | return input !== '' 41 | } 42 | } 43 | ) 44 | } 45 | } 46 | 47 | export default DatabaseTypeQuestion -------------------------------------------------------------------------------- /src/questions/selectDatabaseQuestion.ts: -------------------------------------------------------------------------------- 1 | import { error } from "console"; 2 | import inquirer from 'inquirer' 3 | import DatabasesModel from "../models/databasesModel"; 4 | import * as path from 'path' 5 | import * as fs from 'fs' 6 | import CommandExists from "command-exists"; 7 | 8 | class SelectDatabaseQuestion { 9 | private databasesModel = new DatabasesModel(); 10 | private questions = []; 11 | 12 | configure = async (config: any) => { 13 | await this.addQuestions(config); 14 | 15 | await inquirer 16 | .prompt(this.questions) 17 | .then((answers) => { 18 | // Get database key to get database settings 19 | let keyRegex = /\((.*)\)/i; 20 | let selectedDatabase = answers.database; 21 | let databaseKey = selectedDatabase.match(keyRegex)[1]; 22 | 23 | // Collects database data based on key 24 | this.databasesModel.collectDatabaseData(databaseKey, config.databases.databaseType); 25 | 26 | // Set database data in config 27 | config.databases.databaseData = this.databasesModel.databaseData; 28 | 29 | // If local folder is set for project, use that as currentFolder 30 | config.settings.currentFolder = process.cwd(); 31 | if (config.databases.databaseData.localProjectFolder && config.databases.databaseData.localProjectFolder.length > 0) { 32 | config.settings.currentFolder = config.databases.databaseData.localProjectFolder; 33 | } 34 | 35 | // Set current folder name based on current folder 36 | config.settings.currentFolderName = path.basename(path.resolve(config.settings.currentFolder)); 37 | 38 | // Check if current is shopware. This will be used to determine if we can import Shopware 39 | if (fs.existsSync(config.settings.currentFolder + '/vendor/shopware/core') || fs.existsSync(config.settings.currentFolder + '/public/index.php')) { 40 | config.settings.currentFolderIsShopware = true; 41 | 42 | if (fs.existsSync(config.settings.currentFolder + '/.ddev/config.yaml')) { 43 | // Check if ddev is installed locally 44 | CommandExists('ddev').then((command) => { 45 | config.settings.isDdevActive = true; 46 | }).catch(function () {}); 47 | } 48 | } 49 | }) 50 | .catch((err: { message: any; }) => { 51 | error(`Something went wrong: ${err.message}`) 52 | }); 53 | } 54 | 55 | // Add questions 56 | addQuestions = async (config: any) => { 57 | this.questions.push( 58 | { 59 | type: 'search-list', 60 | name: 'database', 61 | message: 'Select or search database', 62 | choices: config.databases.databasesList, 63 | validate: (input: string) => { 64 | return input !== '' 65 | } 66 | } 67 | ) 68 | } 69 | } 70 | 71 | export default SelectDatabaseQuestion 72 | -------------------------------------------------------------------------------- /src/sw-db-sync.ts: -------------------------------------------------------------------------------- 1 | import program from 'commander' 2 | import commandLoader from './commands/index' 3 | import fs from 'fs'; 4 | // @ts-ignore 5 | import {getInstalledPath} from 'get-installed-path' 6 | import {error} from "./utils/console"; 7 | import VersionCheck from "./utils/versionCheck"; 8 | 9 | getInstalledPath('sw-db-sync').then(async (path: any) => { 10 | // Lets make sure all required files are in place before running the tool 11 | let npmPath = path; 12 | let missingFiles = false; 13 | let requiredFiles = [ 14 | 'config/settings.json', 15 | 'config/databases/staging.json', 16 | 'config/databases/production.json' 17 | ]; 18 | 19 | new Promise((resolve, reject) => { 20 | requiredFiles.forEach((path) => { 21 | if (!fs.existsSync(`${npmPath}/${path}`)) { 22 | error(`${path} was not found. Make sure this file exists (${npmPath}/${path})`); 23 | missingFiles = true; 24 | } 25 | }); 26 | }); 27 | 28 | // If there are files missing, stop the program from running 29 | if (missingFiles) { 30 | return; 31 | } 32 | 33 | commandLoader(program); 34 | 35 | // eslint-disable-next-line @typescript-eslint/no-var-requires 36 | const packageJson = require('../package.json') 37 | let versionCheck = new VersionCheck(); 38 | await versionCheck.getToolVersions(); 39 | let description = `Shopware 6 Database Synchronizer - ${packageJson.version}`; 40 | if (versionCheck.config.currentVersion < versionCheck.config.latestVersion) { 41 | description = `${description}\nRun 'sw-db-sync self-update' to download the newest version: ${versionCheck.config.latestVersion}`; 42 | } 43 | 44 | program 45 | .version(packageJson.version) 46 | .usage(' [options]') 47 | .description(description) 48 | 49 | program.on('command:*', () => { 50 | program.help() 51 | }) 52 | 53 | program.parse(process.argv) 54 | 55 | if (!process.argv.slice(2).length) { 56 | program.outputHelp() 57 | process.exit() 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /src/tasks/checksTask.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs' 2 | import { Listr } from 'listr2'; 3 | import configFile from '../../config/settings.json' 4 | 5 | class ChecksTask { 6 | private checkTasks = []; 7 | 8 | configure = async (list: any, config: any, ssh: any) => { 9 | await this.addTasks(list, config, ssh); 10 | return list; 11 | } 12 | 13 | // Add tasks 14 | addTasks = async (list: any, config: any, ssh: any) => { 15 | list.add( 16 | { 17 | title: 'Running some checks', 18 | task: (ctx: any, task: any): Listr => 19 | task.newListr( 20 | this.checkTasks 21 | ) 22 | } 23 | ) 24 | 25 | if (config.settings.import && config.settings.import == 'yes') { 26 | // Check if all settings are filled in, if we import 27 | this.checkTasks.push( 28 | { 29 | title: 'Checking if config/settings.json is correctly filled', 30 | task: async (): Promise => { 31 | // Lets make sure everything is filled in 32 | if (!configFile.shopwareBackend.adminUsername || configFile.shopwareBackend.adminUsername && configFile.shopwareBackend.adminUsername.length == 0) { 33 | throw new Error('Admin username is missing config/settings.json'); 34 | } 35 | 36 | if (!configFile.shopwareBackend.adminPassword || configFile.shopwareBackend.adminPassword && configFile.shopwareBackend.adminPassword.length == 0) { 37 | throw new Error('Admin password is missing in config/settings.json'); 38 | } 39 | 40 | if (!configFile.shopwareBackend.adminEmailAddress || configFile.shopwareBackend.adminEmailAddress && configFile.shopwareBackend.adminEmailAddress.length == 0) { 41 | throw new Error('Admin email address is missing in config/settings.json'); 42 | } 43 | } 44 | } 45 | ); 46 | 47 | if (config.settings.import && config.settings.import == 'yes') { 48 | // Check if target folder exists before downloading 49 | this.checkTasks.push( 50 | { 51 | title: 'Checking if .env file exists', 52 | task: async (): Promise => { 53 | let envFileLocation = config.settings.currentFolder + '/.env'; 54 | if (fs.existsSync(envFileLocation)) { 55 | return true; 56 | } 57 | 58 | throw new Error(`.env is missing, make sure ${envFileLocation} exists.`); 59 | } 60 | } 61 | ); 62 | } 63 | } 64 | 65 | // Check if target folder exists before downloading 66 | this.checkTasks.push( 67 | { 68 | title: 'Checking if download folder exists', 69 | task: async (): Promise => { 70 | if (fs.existsSync(config.customConfig.localDatabaseFolderLocation)) { 71 | return true; 72 | } 73 | 74 | throw new Error(`Download folder ${config.customConfig.localDatabaseFolderLocation} does not exist. This can be configured in config/settings.json`); 75 | } 76 | } 77 | ); 78 | 79 | // Check if SSH key exists 80 | this.checkTasks.push( 81 | { 82 | title: 'Checking if SSH key exists', 83 | task: async (): Promise => { 84 | if (fs.existsSync(config.customConfig.sshKeyLocation)) { 85 | return true; 86 | } 87 | 88 | throw new Error(`SSH key ${config.customConfig.sshKeyLocation} does not exist. This can be configured in config/settings.json`); 89 | } 90 | } 91 | ); 92 | } 93 | } 94 | 95 | export default ChecksTask 96 | -------------------------------------------------------------------------------- /src/tasks/downloadTask.ts: -------------------------------------------------------------------------------- 1 | import {localhostRsyncDownloadCommand, sshNavigateToShopwareRootCommand, extractDatabaseDetails } from '../utils/console'; 2 | import { Listr } from 'listr2'; 3 | // @ts-ignore 4 | 5 | class DownloadTask { 6 | private downloadTasks = []; 7 | 8 | configure = async (list: any, config: any, ssh: any) => { 9 | await this.addTasks(list, config, ssh); 10 | return list; 11 | } 12 | 13 | // Add tasks 14 | addTasks = async (list: any, config: any, ssh: any) => { 15 | list.add( 16 | { 17 | title: 'Download database from server ' + '(' + config.databases.databaseData.username + ')', 18 | task: (ctx: any, task: any): Listr => 19 | task.newListr( 20 | this.downloadTasks 21 | ) 22 | } 23 | ) 24 | 25 | this.downloadTasks.push( 26 | { 27 | title: 'Connecting to server through SSH', 28 | task: async (): Promise => { 29 | // Open connection to SSH server 30 | await ssh.connect({ 31 | host: config.databases.databaseData.server, 32 | password: config.databases.databaseData.password, 33 | username: config.databases.databaseData.username, 34 | port: config.databases.databaseData.port, 35 | privateKey: config.customConfig.sshKeyLocation, 36 | passphrase: config.customConfig.sshPassphrase 37 | }); 38 | } 39 | } 40 | ); 41 | 42 | this.downloadTasks.push( 43 | { 44 | title: 'Retrieving server settings', 45 | task: async (): Promise => { 46 | // Retrieve settings from server to use 47 | await ssh.execCommand(sshNavigateToShopwareRootCommand('pwd; which php;', config)).then((result: any) => { 48 | if (result) { 49 | let serverValues = result.stdout.split("\n"); 50 | config.serverVariables.shopwareRoot = serverValues[0]; 51 | 52 | // Get PHP path 53 | config.serverVariables.externalPhpPath = serverValues[1]; 54 | } 55 | }); 56 | 57 | // Use custom PHP path instead if given 58 | if (config.databases.databaseData.externalPhpPath && config.databases.databaseData.externalPhpPath.length > 0) { 59 | config.serverVariables.externalPhpPath = config.databases.databaseData.externalPhpPath; 60 | } 61 | } 62 | } 63 | ); 64 | 65 | this.downloadTasks.push( 66 | { 67 | title: 'Downloading Shopware6 DB Dump File to server', 68 | task: async (): Promise => { 69 | await ssh.execCommand(sshNavigateToShopwareRootCommand('curl -O https://raw.githubusercontent.com/jellesiderius/shopware6-database-dump/main/shopware6-database-dump.sh', config)); 70 | } 71 | }, 72 | ); 73 | 74 | this.downloadTasks.push( 75 | { 76 | title: 'Dumping Shopware database and moving it to server root (' + config.settings.strip + ')', 77 | task: async (): Promise => { 78 | var username = '', 79 | password = '', 80 | host = '', 81 | port = '', 82 | database = ''; 83 | 84 | // Retrieve database name 85 | await ssh.execCommand(sshNavigateToShopwareRootCommand('cat .env | grep "DATABASE_URL="', config)).then((result: any) => { 86 | if (result) { 87 | var resultValues = result.stdout, 88 | databaseDetails = extractDatabaseDetails(resultValues); 89 | 90 | username = databaseDetails.username; 91 | password = databaseDetails.password; 92 | host = databaseDetails.host; 93 | port = databaseDetails.port; 94 | database = databaseDetails.database; 95 | 96 | config.settings.databaseFileName = database; 97 | } 98 | }); 99 | 100 | // Dump database 101 | var dumpCommand = `/bin/bash shopware6-database-dump.sh -d ${database} -u ${username} -pa ${password} --host ${host} -p ${port} --gdpr` 102 | if (config.settings.strip == 'full') { 103 | dumpCommand = `/bin/bash shopware6-database-dump.sh -d ${database} -u ${username} -pa ${password} --host ${host} -p ${port}` 104 | } 105 | 106 | await ssh.execCommand(sshNavigateToShopwareRootCommand(`${dumpCommand}; mv ${config.settings.databaseFileName}.sql ~`, config)); 107 | } 108 | } 109 | ); 110 | 111 | this.downloadTasks.push( 112 | { 113 | title: 'Downloading Shopware 6 database to localhost', 114 | task: async (): Promise => { 115 | // Download file and place it on localhost 116 | let localDatabaseFolderLocation = config.customConfig.localDatabaseFolderLocation; 117 | let localDatabaseLocation = localDatabaseFolderLocation + `/${config.settings.databaseFileName}.sql`; 118 | 119 | if (config.settings.rsyncInstalled) { 120 | await localhostRsyncDownloadCommand(`~/${config.settings.databaseFileName}.sql`, `${localDatabaseFolderLocation}`, config); 121 | } else { 122 | await ssh.getFile(localDatabaseLocation, config.settings.databaseFileName + '.sql').then(function (Contents: any) { 123 | }, function (error: any) { 124 | throw new Error(error) 125 | }); 126 | } 127 | 128 | // Set final message with Shopware 6 DB location 129 | config.finalMessages.shopwareDatabaseLocation = localDatabaseLocation; 130 | config.settings.databaseFullPath = localDatabaseFolderLocation; 131 | } 132 | } 133 | ); 134 | 135 | this.downloadTasks.push( 136 | { 137 | title: 'Cleaning up and closing SSH connection', 138 | task: async (): Promise => { 139 | // Remove the Shopware 6 database file on the server 140 | await ssh.execCommand(`rm ${config.settings.databaseFileName}.sql`); 141 | 142 | // Remove database dump file and close connection to SSH 143 | await ssh.execCommand(sshNavigateToShopwareRootCommand('rm shopware6-database-dump.sh', config)); 144 | 145 | // Close the SSH connection 146 | await ssh.dispose(); 147 | } 148 | } 149 | ); 150 | } 151 | } 152 | 153 | export default DownloadTask 154 | -------------------------------------------------------------------------------- /src/tasks/importTask.ts: -------------------------------------------------------------------------------- 1 | import {extractDatabaseDetails, localhostShopwareRootExec} from '../utils/console'; 2 | import { Listr } from 'listr2'; 3 | 4 | class ImportTask { 5 | private importTasks = []; 6 | 7 | configure = async (list: any, config: any) => { 8 | await this.addTasks(list, config); 9 | return list; 10 | } 11 | 12 | // Add tasks 13 | addTasks = async (list: any, config: any) => { 14 | list.add( 15 | { 16 | title: 'Import Shopware database to localhost', 17 | task: (ctx: any, task: any): Listr => 18 | task.newListr( 19 | this.importTasks 20 | ) 21 | } 22 | ) 23 | 24 | this.importTasks.push( 25 | { 26 | title: 'Getting localhost .env info', 27 | task: async (): Promise => { 28 | await localhostShopwareRootExec(`cat .env | grep "DATABASE_URL="`, config).then((result: any) => { 29 | if (result) { 30 | var databaseDetails = extractDatabaseDetails(result); 31 | 32 | config.localhost.username = databaseDetails.username; 33 | config.localhost.password = databaseDetails.password; 34 | config.localhost.host = databaseDetails.host; 35 | config.localhost.port = databaseDetails.port; 36 | config.localhost.database = databaseDetails.database; 37 | } 38 | }); 39 | 40 | await localhostShopwareRootExec(`cat .env | grep "APP_URL="`, config).then((result: any) => { 41 | if (result) { 42 | var appUrl = result, 43 | splittedAppUrl = appUrl.split('//'), 44 | appUrlFromArray = splittedAppUrl[1].replace('"', '').trim(); 45 | 46 | config.localhost.domainUrl = appUrlFromArray; 47 | 48 | // Determine http or https 49 | if (appUrl.indexOf('https') !== -1) { 50 | config.localhost.https = true; 51 | } 52 | } 53 | }); 54 | } 55 | } 56 | ); 57 | 58 | this.importTasks.push( 59 | { 60 | title: 'Importing database to localhost', 61 | task: async (): Promise => { 62 | // Drop database 63 | await localhostShopwareRootExec(`mysqladmin -u ${config.localhost.username} --password=${config.localhost.password} drop ${config.localhost.database} -f`, config, true); 64 | 65 | // Create database 66 | await localhostShopwareRootExec(`mysqladmin -u ${config.localhost.username} --password=${config.localhost.password} create ${config.localhost.database} -f`, config, true); 67 | 68 | // Import database 69 | await localhostShopwareRootExec(`mysql -u ${config.localhost.username} --password=${config.localhost.password} ${config.localhost.database} --force < ${config.settings.databaseFullPath}/${config.settings.databaseFileName}.sql`, config, true); 70 | } 71 | } 72 | ); 73 | 74 | if (config.settings.syncImages == 'yes') { 75 | this.importTasks.push( 76 | { 77 | title: 'Synchronizing public/media & public/thumbnail', 78 | task: async (): Promise => { 79 | // Sync media 80 | await localhostShopwareRootExec(`rsync -avz -e "ssh -p ${config.databases.databaseData.port}" ${config.databases.databaseData.username}@${config.databases.databaseData.server}:${config.serverVariables.shopwareRoot}/public/media/* public/media/`, config, true, false, true); 81 | 82 | // Sync thumbnail 83 | await localhostShopwareRootExec(`rsync -avz -e "ssh -p ${config.databases.databaseData.port}" ${config.databases.databaseData.username}@${config.databases.databaseData.server}:${config.serverVariables.shopwareRoot}/public/thumbnail/* public/thumbnail/`, config, true, false, true); 84 | } 85 | } 86 | ); 87 | } 88 | 89 | this.importTasks.push( 90 | { 91 | title: 'Cleaning up', 92 | task: async (): Promise => { 93 | // Remove local SQL file 94 | await localhostShopwareRootExec(`rm ${config.settings.databaseFileName}.sql`, config); 95 | } 96 | } 97 | ); 98 | } 99 | } 100 | 101 | export default ImportTask 102 | -------------------------------------------------------------------------------- /src/tasks/shopwareConfigureTask.ts: -------------------------------------------------------------------------------- 1 | import {localhostShopwareRootExec, localhostShopwareRootMysqlExec} from '../utils/console'; 2 | import { Listr } from 'listr2'; 3 | import configFile from '../../config/settings.json' 4 | 5 | class ShopwareConfigureTask { 6 | private configureTasks = []; 7 | 8 | configure = async (list: any, config: any) => { 9 | await this.addTasks(list, config); 10 | return list; 11 | } 12 | 13 | // Add tasks 14 | addTasks = async (list: any, config: any) => { 15 | list.add( 16 | { 17 | title: 'Configuring Shopware 6 for development usage', 18 | task: (ctx: any, task: any): Listr => 19 | task.newListr( 20 | this.configureTasks 21 | ) 22 | } 23 | ) 24 | 25 | this.configureTasks.push( 26 | { 27 | title: "Setting URL for sales channels", 28 | task: async (): Promise => { 29 | await localhostShopwareRootExec(`bin/console sales-channel:update:domain ${config.localhost.domainUrl}`, config); 30 | 31 | if (config.localhost.https) { 32 | await localhostShopwareRootMysqlExec("UPDATE sales_channel_domain SET url = REPLACE(url,'http://', 'https://')", config); 33 | config.finalMessages.importDomain = `https://${config.localhost.domainUrl}`; 34 | } else { 35 | await localhostShopwareRootMysqlExec("UPDATE sales_channel_domain SET url = REPLACE(url,'https://', 'http://')", config); 36 | config.finalMessages.importDomain = `http://${config.localhost.domainUrl}`; 37 | } 38 | } 39 | } 40 | ); 41 | 42 | if (config.settings.syncImages == 'no') { 43 | this.configureTasks.push( 44 | { 45 | title: "Emptying media tables", 46 | task: async (): Promise => { 47 | // Product media 48 | await localhostShopwareRootMysqlExec('TRUNCATE TABLE product_media', config); 49 | 50 | // Theme media 51 | await localhostShopwareRootMysqlExec('TRUNCATE TABLE theme_media', config); 52 | } 53 | } 54 | ); 55 | } 56 | 57 | this.configureTasks.push( 58 | { 59 | title: "Refreshing plugins", 60 | task: async (): Promise => { 61 | await localhostShopwareRootExec(`bin/console plugin:refresh`, config); 62 | } 63 | } 64 | ); 65 | 66 | this.configureTasks.push( 67 | { 68 | title: "Compiling theme", 69 | task: async (): Promise => { 70 | await localhostShopwareRootExec(`bin/console theme:compile`, config); 71 | } 72 | } 73 | ); 74 | 75 | this.configureTasks.push( 76 | { 77 | title: 'Creating a admin user', 78 | task: async (): Promise => { 79 | await localhostShopwareRootExec(`bin/console user:create -a ${configFile.shopwareBackend.adminUsername} -p ${configFile.shopwareBackend.adminPassword} --email ${configFile.shopwareBackend.adminEmailAddress}`, config); 80 | } 81 | } 82 | ); 83 | 84 | this.configureTasks.push( 85 | { 86 | title: 'Reindexing Shopware (ES)', 87 | task: async (): Promise => { 88 | // Reindex 89 | await localhostShopwareRootExec(`bin/console es:index -n`, config); 90 | // Reset indexes 91 | await localhostShopwareRootExec(`bin/console es:reset -n`, config); 92 | } 93 | } 94 | ); 95 | 96 | this.configureTasks.push( 97 | { 98 | title: 'Flushing Shopware 6 caches', 99 | task: async (): Promise => { 100 | // Flush the shopware caches and import config data 101 | await localhostShopwareRootExec(`bin/console cache:clear`, config); 102 | } 103 | } 104 | ); 105 | } 106 | } 107 | 108 | export default ShopwareConfigureTask 109 | -------------------------------------------------------------------------------- /src/utils/console.ts: -------------------------------------------------------------------------------- 1 | import kleur from 'kleur' 2 | import * as readline from 'readline' 3 | import {ExecException} from "child_process"; 4 | 5 | const prefix = { 6 | verbose: kleur.gray(kleur.bold('🛠 ')), 7 | info: kleur.gray(kleur.bold('✨ ')), 8 | success: kleur.gray(kleur.bold('✅ ')), 9 | warning: kleur.yellow(kleur.bold('⚠️ Warning: ')), 10 | error: kleur.red(kleur.bold('🚨 Error: ')), 11 | } 12 | 13 | const body = { 14 | default: kleur.white, 15 | verbose: kleur.gray, 16 | warning: kleur.yellow, 17 | error: kleur.red 18 | } 19 | 20 | const log = (prefix: string, body: string): void => { 21 | let out = prefix 22 | out = out.concat(body) 23 | 24 | console.log(out) 25 | } 26 | 27 | const verbose = (message: string): void => { 28 | log(prefix.verbose, body.verbose(message)) 29 | } 30 | 31 | const info = (message: string): void => { 32 | log(prefix.info, body.default(message)) 33 | } 34 | 35 | const warning = (message: string): void => { 36 | log(prefix.warning, body.warning(message)) 37 | } 38 | 39 | const error = (message: string): void => { 40 | log(prefix.error, body.error(message)) 41 | } 42 | 43 | const success = (message: string): void => { 44 | log(prefix.success, body.default(message)) 45 | } 46 | 47 | const url = (url: string): string => { 48 | return kleur.bold(kleur.underline(url)) 49 | } 50 | 51 | const emptyLine = (): void => { 52 | console.log('') 53 | } 54 | 55 | const clearConsole = (): void => { 56 | const blank = '\n'.repeat(process.stdout.rows) 57 | console.log(blank) 58 | readline.cursorTo(process.stdout, 0, 0) 59 | readline.clearScreenDown(process.stdout) 60 | } 61 | 62 | const consoleCommand = (cmd: string, skipErrors: boolean) => { 63 | const exec = require('child_process').exec; 64 | return new Promise((resolve, reject) => { 65 | exec(cmd, (error: ExecException | null, stdout: string, stderr: string) => { 66 | if (error && !skipErrors) { 67 | // @ts-ignore 68 | throw new Error(error) 69 | process.exit(); 70 | } 71 | resolve(stdout ? stdout : stderr); 72 | }); 73 | }); 74 | } 75 | 76 | // Navigate to Shopware root folder 77 | const sshNavigateToShopwareRootCommand = (command: string, config: any) => { 78 | // See if external project folder is filled in, otherwise try default path 79 | if (config.databases.databaseData.externalProjectFolder && config.databases.databaseData.externalProjectFolder.length > 0) { 80 | return `cd ${config.databases.databaseData.externalProjectFolder} > /dev/null 2>&1; ${command}`; 81 | } else { 82 | return 'cd domains > /dev/null 2>&1;' + 83 | 'cd ' + config.databases.databaseData.domainFolder + ' > /dev/null 2>&1;' + 84 | 'cd application > /dev/null 2>&1;' + 85 | 'cd public_html > /dev/null 2>&1;' + 86 | 'cd current > /dev/null 2>&1;' + command; 87 | } 88 | } 89 | 90 | const localhostShopwareRootExec = (command: string, config: any, skipErrors: boolean = false, noExec: boolean = false, skipDdev: boolean = false) => { 91 | if (config.settings.isDdevActive && !skipDdev) { 92 | if (noExec) { 93 | return consoleCommand(`cd ${config.settings.currentFolder}; ddev ${command};`, skipErrors); 94 | } 95 | 96 | return consoleCommand(`cd ${config.settings.currentFolder}; ddev exec ${command};`, skipErrors); 97 | } 98 | 99 | return consoleCommand(`cd ${config.settings.currentFolder}; ${command};`, skipErrors); 100 | } 101 | 102 | const localhostRsyncDownloadCommand = (source: string, destination: string, config: any) => { 103 | let sshCommand: string; 104 | config.databases.databaseData.port ? sshCommand = `ssh -p ${config.databases.databaseData.port} -o StrictHostKeyChecking=no` : sshCommand = `ssh -o StrictHostKeyChecking=no`; 105 | 106 | let totalRsyncCommand = `rsync -avz -e "${sshCommand}" ${config.databases.databaseData.username}@${config.databases.databaseData.server}:${source} ${destination}`; 107 | 108 | // If password is set, use sshpass 109 | if (config.databases.databaseData.password) { 110 | totalRsyncCommand = `sshpass -p "${config.databases.databaseData.password}" ` + totalRsyncCommand; 111 | } 112 | 113 | return consoleCommand(totalRsyncCommand, false) 114 | } 115 | 116 | const localhostShopwareRootMysqlExec = (command: string, config: any, skipErrors: boolean = false) => { 117 | let noExec = false; 118 | 119 | if (config.settings.isDdevActive) { 120 | noExec = true; 121 | } 122 | 123 | return localhostShopwareRootExec(`mysql -u ${config.localhost.username} --password=${config.localhost.password} ${config.localhost.database} -e "${command}"`, config, skipErrors, noExec); 124 | } 125 | 126 | const extractDatabaseDetails = (string: string) => { 127 | var details = string, 128 | details = details.replace('DATABASE_URL="mysql', '').replace('DATABASE_URL=mysql', '').replace('//', '').replace('"', '').replace('@', ':').replace('/', ':'), 129 | details = details.split(':'), 130 | details = details.filter((a) => a); 131 | 132 | 133 | let detailsObject = { 134 | username: details[0].trim(), 135 | password: details[1].replace('$', '\\$').replace(/"/g, '\'').trim(), 136 | host: details[2].trim(), 137 | port: details[3].trim(), 138 | database: details[4].trim() 139 | }; 140 | 141 | return detailsObject; 142 | } 143 | 144 | export { 145 | verbose, 146 | info, 147 | success, 148 | warning, 149 | error, 150 | url, 151 | emptyLine, 152 | clearConsole, 153 | consoleCommand, 154 | sshNavigateToShopwareRootCommand, 155 | localhostShopwareRootExec, 156 | localhostRsyncDownloadCommand, 157 | extractDatabaseDetails, 158 | localhostShopwareRootMysqlExec 159 | } 160 | -------------------------------------------------------------------------------- /src/utils/versionCheck.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import packageFile from "../../package.json"; 3 | // @ts-ignore 4 | import * as fetch from 'node-fetch' 5 | 6 | class VersionCheck { 7 | public config = { 8 | 'latestVersion': '', 9 | 'currentVersion': packageFile.version 10 | } 11 | 12 | // versions 13 | getToolVersions = async () => { 14 | await fetch('https://raw.githubusercontent.com/sidworks-dev/sw-db-sync/master/package.json') 15 | .then((res: { json: () => any; }) => res.json()) 16 | .then((json: { version: string; }) => this.config.latestVersion = json.version); 17 | } 18 | } 19 | 20 | export default VersionCheck; 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es6", 7 | "es2015", 8 | "dom" 9 | ], 10 | "outDir": "dist", 11 | "rootDir": "src", 12 | "typeRoots": [ 13 | "./node_modules/@types", 14 | "./src/types" 15 | ], 16 | "strict": true, 17 | "esModuleInterop": true, 18 | "resolveJsonModule": true, 19 | "importHelpers": true, 20 | "allowSyntheticDefaultImports": true, 21 | "forceConsistentCasingInFileNames": true, 22 | "moduleResolution": "node", 23 | "pretty": true, 24 | "sourceMap": true, 25 | "allowJs": true, 26 | "noEmit": false, 27 | "watch": true 28 | }, 29 | "include": [ 30 | "./src/**/*" 31 | ], 32 | "exclude": [ 33 | "node_modules", 34 | "tests", 35 | "dist" 36 | ] 37 | } --------------------------------------------------------------------------------