├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── Commands │ ├── MakeComponent.php │ ├── MakeMixin.php │ └── VueGeneratorsCommand.php ├── Exceptions │ └── ResourceAlreadyExists.php ├── Paths.php ├── ServiceProvider.php ├── Stubs │ ├── Component.vue │ ├── EmptyComponent.vue │ ├── EmptyMixin.js │ └── Mixin.js └── config.php └── tests ├── CommandTest.php └── TestCase.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | .env 3 | composer.lock 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 7.2 5 | - 7.3 6 | - 7.4 7 | 8 | install: composer install 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Zach Leigh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Vue Generators 2 | [![Latest Stable Version](https://img.shields.io/packagist/v/zachleigh/laravel-vue-generators.svg)](//packagist.org/packages/zachleigh/laravel-vue-generators) 3 | [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](//packagist.org/packages/zachleigh/laravel-vue-generators) 4 | [![Build Status](https://img.shields.io/travis/zachleigh/laravel-vue-generators/master.svg)](https://travis-ci.org/zachleigh/laravel-vue-generators) 5 | [![Quality Score](https://img.shields.io/scrutinizer/g/zachleigh/laravel-vue-generators.svg)](https://scrutinizer-ci.com/g/zachleigh/laravel-vue-generators/) 6 | [![StyleCI](https://styleci.io/repos/73324143/shield?style=flat)](https://styleci.io/repos/72352058) 7 | [![Total Downloads](https://img.shields.io/packagist/dt/zachleigh/laravel-vue-generators.svg)](https://packagist.org/packages/zachleigh/laravel-vue-generators) 8 | 9 | ##### Generate Vue js file stubs via artisan commands. 10 | 11 | ### Contents 12 | - [Upgrade Information](#upgrade-information) 13 | - [Install](#install) 14 | - [Usage](#usage) 15 | - [Configuration](#configuration) 16 | - [Testing](#testing) 17 | - [Contributing](#contributing) 18 | 19 | ### Upgrade Information 20 | #### Version 0.1.* to Version 0.2.0 21 | Version 0.2.0 adds Laravel 5.4 support. For Laravel 5.3, please use [Version 0.1.4](https://github.com/zachleigh/laravel-vue-generators/tree/v0.1.4): 22 | ``` 23 | composer require zachleigh/laravel-vue-generators:0.1.* 24 | ``` 25 | 26 | ### Install 27 | Install via composer: 28 | ``` 29 | composer require zachleigh/laravel-vue-generators 30 | ``` 31 | In Laravel's config/app.php file, add the service provider to the array with the 'providers' key. 32 | ``` 33 | VueGenerators\ServiceProvider::class 34 | ``` 35 | Publish the config file: 36 | ``` 37 | php artisan vendor:publish --provider="VueGenerators\ServiceProvider" 38 | ``` 39 | 40 | ### Usage 41 | This package currently contains two commands: `component` and `mixin`. 42 | #### component 43 | Create a Vue js component file. 44 | ``` 45 | php artisan vueg:component {name} {--empty} {--path=} 46 | ``` 47 | ###### name 48 | Name of the component. 49 | ``` 50 | php artisan vueg:component MyComponent 51 | ``` 52 | Will create a file called MyComponent.vue at resources/assets/js/components/MyComponent.vue. 53 | ###### empty 54 | By default, the component will be filled with all available component methods (data, props, computed etc.). Use empty flag to create an empty component with no methods. 55 | ``` 56 | php artisan vueg:component MyComponent --empty 57 | ``` 58 | Will create a file with no component methods. 59 | ###### path 60 | By default, all components will be saved in resources/assets/js/components/. Specify a custom path with the path flag. Path root is in resources/. 61 | ``` 62 | php artisan vueg:component MyComponent --path=assets/js/custom/folder 63 | ``` 64 | Will create a file called MyComponent.vue at resources/assets/js/custom/folder/MyComponent.vue. 65 | 66 | #### mixin 67 | Create a Vue js mixin file. 68 | ``` 69 | php artisan vueg:mixin {name} {--empty} {--path=} 70 | ``` 71 | ###### name 72 | Name of the mixin. 73 | ``` 74 | php artisan vueg:mixin MyMixin 75 | ``` 76 | Will create a file called MyMixin.vue at resources/assets/js/mixins/MyMixin.vue. 77 | ###### empty 78 | By default, the mixin will be filled with all available mixin methods (data, props, computed etc.). Use empty flag to create an empty mixin with no methods. 79 | ``` 80 | php artisan vueg:mixin MyMixin --empty 81 | ``` 82 | Will create a file with no mixin methods. 83 | ###### path 84 | By default, all mixins will be saved in resources/assets/js/mixins/. Specify a custom path with the path flag. Path root is in resources/. 85 | ``` 86 | php artisan vueg:mixin MyMixin --path=assets/js/custom/folder 87 | ``` 88 | Will create a file called MyMixin.vue at resources/assets/js/custom/folder/MyMixin.vue. 89 | 90 | ### Configuration 91 | Set default paths for components and mixins. All paths are relative to Laravel's resources directory. 92 | ```php 93 | 'paths' => [ 94 | 'components' => 'path/to/components', 95 | 'mixins' => 'path/to/mixins', 96 | ] 97 | ``` 98 | 99 | ### Testing 100 | ``` 101 | composer test 102 | ``` 103 | 104 | ### Contributing 105 | Contributions are more than welcome. Fork, improve and make a pull request. For bugs, ideas for improvement or other, please create an [issue](https://github.com/zachleigh/laravel-lang-bundler/issues). 106 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zachleigh/laravel-vue-generators", 3 | "description": "Generate Vue js files via artisan commands.", 4 | "keywords" : ["laravel", "vue", "generators"], 5 | "type": "project", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Zach Leigh", 10 | "email": "zachleigh@fastmail.jp" 11 | } 12 | ], 13 | 14 | "require": { 15 | "php": ">=7.2.0", 16 | "laravel/browser-kit-testing": "^1.0" 17 | }, 18 | 19 | "require-dev": { 20 | "laravel/laravel": "^6.0", 21 | "phpunit/phpunit": "~4.0" 22 | }, 23 | 24 | "autoload": { 25 | "psr-4": { 26 | "VueGenerators\\": "src/" 27 | } 28 | }, 29 | 30 | "autoload-dev": { 31 | "psr-4": { 32 | "VueGenerators\\tests\\": "tests/" 33 | } 34 | }, 35 | 36 | "scripts": { 37 | "test": "phpunit" 38 | }, 39 | 40 | "minimum-stability": "stable", 41 | "prefer-stable": true 42 | } 43 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Commands/MakeComponent.php: -------------------------------------------------------------------------------- 1 | argument('name').'.vue'; 31 | 32 | $path = $this->createPath($filesystem, 'component'); 33 | 34 | $fullPath = resource_path("{$path}/{$name}"); 35 | 36 | $this->checkFileExists($filesystem, $fullPath, $name); 37 | 38 | $stub = $this->getStub($filesystem); 39 | 40 | $filesystem->put($fullPath, $stub); 41 | 42 | $this->info("Component {$name} succesfully created."); 43 | } 44 | 45 | /** 46 | * Get and return stub. 47 | * 48 | * @param Filesystem $filesystem 49 | * 50 | * @return string 51 | */ 52 | protected function getStub(Filesystem $filesystem) 53 | { 54 | $fileName = $this->option('empty') ? 'EmptyComponent' : 'Component'; 55 | 56 | return $filesystem->get(__DIR__.'/../Stubs/'.$fileName.'.vue'); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Commands/MakeMixin.php: -------------------------------------------------------------------------------- 1 | argument('name').'.js'; 31 | 32 | $path = $this->createPath($filesystem, 'mixin'); 33 | 34 | $fullPath = resource_path("{$path}/{$name}"); 35 | 36 | $this->checkFileExists($filesystem, $fullPath, $name); 37 | 38 | $stub = $this->getStub($filesystem); 39 | 40 | $filesystem->put($fullPath, $stub); 41 | 42 | $this->info("Mixin {$name} succesfully created."); 43 | } 44 | 45 | /** 46 | * Get and return stub. 47 | * 48 | * @param Filesystem $filesystem 49 | * 50 | * @return string 51 | */ 52 | protected function getStub(Filesystem $filesystem) 53 | { 54 | $fileName = $this->option('empty') ? 'EmptyMixin' : 'Mixin'; 55 | 56 | return $filesystem->get(__DIR__.'/../Stubs/'.$fileName.'.js'); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Commands/VueGeneratorsCommand.php: -------------------------------------------------------------------------------- 1 | option('path'); 25 | 26 | $defaultPath = config("vue-generators.paths.{$type}s"); 27 | 28 | $path = $customPath !== null ? $customPath : $defaultPath; 29 | 30 | $this->buildPathFromArray($path, $filesystem); 31 | 32 | return $path; 33 | } 34 | 35 | protected function checkFileExists(Filesystem $filesystem, $path, $name) 36 | { 37 | if ($filesystem->exists($path)) { 38 | throw ResourceAlreadyExists::fileExists($name); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Exceptions/ResourceAlreadyExists.php: -------------------------------------------------------------------------------- 1 | prepend('resources'); 18 | 19 | if (is_null($filesystem)) { 20 | $filesystem = new Filesystem(); 21 | } 22 | 23 | $base = base_path(); 24 | 25 | foreach ($pathArray as $path) { 26 | $base = $base.'/'.$path; 27 | 28 | if (!$filesystem->exists($base)) { 29 | $filesystem->makeDirectory($base); 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | registerCommands(); 19 | } 20 | 21 | /** 22 | * Perform post-registration booting of services. 23 | * 24 | * @return void 25 | */ 26 | public function boot() 27 | { 28 | $this->publishes([ 29 | __DIR__.'/config.php' => config_path('vue-generators.php'), 30 | ], 'config'); 31 | } 32 | 33 | /** 34 | * Register Artisan commands. 35 | */ 36 | protected function registerCommands() 37 | { 38 | $this->app->singleton('command.vueg.component', function ($app) { 39 | return $app[MakeComponent::class]; 40 | }); 41 | 42 | $this->app->singleton('command.vueg.mixin', function ($app) { 43 | return $app[MakeMixin::class]; 44 | }); 45 | 46 | $this->commands('command.vueg.component'); 47 | 48 | $this->commands('command.vueg.mixin'); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Stubs/Component.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 38 | -------------------------------------------------------------------------------- /src/Stubs/EmptyComponent.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /src/Stubs/EmptyMixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/Stubs/Mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | components: {}, 3 | 4 | data () { 5 | return { 6 | // 7 | } 8 | }, 9 | 10 | props: { 11 | // 12 | }, 13 | 14 | computed: { 15 | // 16 | }, 17 | 18 | created () { 19 | // 20 | }, 21 | 22 | mounted () { 23 | // 24 | }, 25 | 26 | methods: { 27 | // 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /src/config.php: -------------------------------------------------------------------------------- 1 | [ 13 | 'components' => 'assets/js/components', 14 | 'mixins' => 'assets/js/mixins', 15 | ], 16 | ]; 17 | -------------------------------------------------------------------------------- /tests/CommandTest.php: -------------------------------------------------------------------------------- 1 | assertFileNotExists($file); 17 | 18 | Artisan::call('vueg:component', [ 19 | 'name' => 'NewComponent', 20 | '--empty' => true, 21 | ]); 22 | 23 | $this->assertFileExists($file); 24 | } 25 | 26 | /** 27 | * @test 28 | */ 29 | public function it_generates_an_empty_component_file() 30 | { 31 | $file = resource_path('assets/js/components/NewComponent.vue'); 32 | 33 | $this->assertFileNotExists($file); 34 | 35 | Artisan::call('vueg:component', [ 36 | 'name' => 'NewComponent', 37 | '--empty' => true, 38 | ]); 39 | 40 | $this->assertFileEquals(__DIR__.'/../src/Stubs/EmptyComponent.vue', $file); 41 | } 42 | 43 | /** 44 | * @test 45 | */ 46 | public function it_generates_a_filled_component_file() 47 | { 48 | $file = resource_path('assets/js/components/NewComponent.vue'); 49 | 50 | $this->assertFileNotExists($file); 51 | 52 | Artisan::call('vueg:component', [ 53 | 'name' => 'NewComponent', 54 | ]); 55 | 56 | $this->assertFileEquals(__DIR__.'/../src/Stubs/Component.vue', $file); 57 | } 58 | 59 | /** 60 | * @test 61 | */ 62 | public function it_saves_component_file_to_specified_path() 63 | { 64 | $file = resource_path('custom/path/NewComponent.vue'); 65 | 66 | $this->assertFileNotExists($file); 67 | 68 | Artisan::call('vueg:component', [ 69 | 'name' => 'NewComponent', 70 | '--path' => 'custom/path', 71 | ]); 72 | 73 | $this->assertFileExists($file); 74 | } 75 | 76 | /** 77 | * @test 78 | */ 79 | public function it_saves_components_to_path_set_in_config() 80 | { 81 | app()['config']->set('vue-generators.paths.components', 'custom/path'); 82 | 83 | $file = resource_path('custom/path/NewComponent.vue'); 84 | 85 | $this->assertFileNotExists($file); 86 | 87 | Artisan::call('vueg:component', [ 88 | 'name' => 'NewComponent', 89 | ]); 90 | 91 | $this->assertFileExists($file); 92 | } 93 | 94 | /** 95 | * @test 96 | * 97 | * @expectedException VueGenerators\Exceptions\ResourceAlreadyExists 98 | * @expectedExceptionMessage File NewComponent.vue already exists at path. 99 | */ 100 | public function it_doesnt_overwrite_components_that_already_exist() 101 | { 102 | $file = resource_path('assets/js/components/NewComponent.vue'); 103 | 104 | Artisan::call('vueg:component', [ 105 | 'name' => 'NewComponent', 106 | ]); 107 | 108 | $this->assertFileExists($file); 109 | 110 | Artisan::call('vueg:component', [ 111 | 'name' => 'NewComponent', 112 | ]); 113 | } 114 | 115 | /** 116 | * @test 117 | */ 118 | public function it_saves_mixin_file_with_specified_name() 119 | { 120 | $file = resource_path('assets/js/mixins/NewMixin.js'); 121 | 122 | $this->assertFileNotExists($file); 123 | 124 | Artisan::call('vueg:mixin', [ 125 | 'name' => 'NewMixin', 126 | '--empty' => true, 127 | ]); 128 | 129 | $this->assertFileExists($file); 130 | } 131 | 132 | /** 133 | * @test 134 | */ 135 | public function it_generates_empty_mixin_file() 136 | { 137 | $file = resource_path('assets/js/mixins/NewMixin.js'); 138 | 139 | $this->assertFileNotExists($file); 140 | 141 | Artisan::call('vueg:mixin', [ 142 | 'name' => 'NewMixin', 143 | '--empty' => true, 144 | ]); 145 | 146 | $this->assertFileEquals(__DIR__.'/../src/Stubs/EmptyMixin.js', $file); 147 | } 148 | 149 | /** 150 | * @test 151 | */ 152 | public function it_generates_filled_mixin_file() 153 | { 154 | $file = resource_path('assets/js/mixins/NewMixin.js'); 155 | 156 | $this->assertFileNotExists($file); 157 | 158 | Artisan::call('vueg:mixin', [ 159 | 'name' => 'NewMixin', 160 | ]); 161 | 162 | $this->assertFileEquals(__DIR__.'/../src/Stubs/Mixin.js', $file); 163 | } 164 | 165 | /** 166 | * @test 167 | */ 168 | public function it_saves_mixin_file_to_specified_path() 169 | { 170 | $file = resource_path('custom/path/NewMixin.js'); 171 | 172 | $this->assertFileNotExists($file); 173 | 174 | Artisan::call('vueg:mixin', [ 175 | 'name' => 'NewMixin', 176 | '--path' => 'custom/path', 177 | ]); 178 | 179 | $this->assertFileExists($file); 180 | } 181 | 182 | /** 183 | * @test 184 | */ 185 | public function it_saves_mixins_to_path_set_in_config() 186 | { 187 | app()['config']->set('vue-generators.paths.mixins', 'custom/path'); 188 | 189 | $file = resource_path('custom/path/NewMixin.js'); 190 | 191 | $this->assertFileNotExists($file); 192 | 193 | Artisan::call('vueg:mixin', [ 194 | 'name' => 'NewMixin', 195 | ]); 196 | 197 | $this->assertFileExists($file); 198 | } 199 | 200 | /** 201 | * @test 202 | * 203 | * @expectedException VueGenerators\Exceptions\ResourceAlreadyExists 204 | * @expectedExceptionMessage File NewMixin.js already exists at path. 205 | */ 206 | public function it_doesnt_overwrite_mixin_that_already_exist() 207 | { 208 | $file = resource_path('assets/js/mixins/NewMixin.js'); 209 | 210 | Artisan::call('vueg:mixin', [ 211 | 'name' => 'NewMixin', 212 | ]); 213 | 214 | $this->assertFileExists($file); 215 | 216 | Artisan::call('vueg:mixin', [ 217 | 'name' => 'NewMixin', 218 | ]); 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | register(ServiceProvider::class); 25 | 26 | $app->make(Kernel::class)->bootstrap(); 27 | 28 | return $app; 29 | } 30 | 31 | /** 32 | * Setup DB and test variables before each test. 33 | */ 34 | protected function setUp() 35 | { 36 | $filesystem = new Filesystem(); 37 | 38 | $configDir = __DIR__.'./../src/config.php'; 39 | 40 | $configTarget = __DIR__.'./../vendor/laravel/laravel/config/vue-generators.php'; 41 | 42 | $filesystem->copy($configDir, $configTarget); 43 | 44 | parent::setUp(); 45 | } 46 | 47 | /** 48 | * Teardown after each class. 49 | */ 50 | protected function tearDown() 51 | { 52 | $filesystem = new Filesystem(); 53 | 54 | $filesystem->deleteDirectory(resource_path()); 55 | 56 | $this->buildPathFromArray('assets/js/components'); 57 | 58 | parent::tearDown(); 59 | } 60 | } 61 | --------------------------------------------------------------------------------