diff --git a/README.md b/README.md index 0906314..82c9c55 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,36 @@ Output: └─ Invoice.php ``` +### Custom Layers (since 1.2) +Often times, additional top-level namespaces are needed to hold shared components, helpers, and things that are not domain-specific. A common example is the `Infrastructure` layer. You may configure these additional layers in the `ddd.layers` configuration. +```php +// In config/ddd.php +'layers' => [ + 'Infrastructure' => 'src/Infrastructure', + // 'Support' => 'src/Support', +], +``` +The configuration above will result in the following: +```bash +ddd:model Invoicing:Invoice +ddd:trait Infrastructure:Concerns/HasExpiryDate +``` +Output: +``` +├─ src/Domain +| └─ Invoicing +| └─ Models +| └─ Invoice.php +├─ src/Infrastructure + └─ Concerns + └─ HasExpiryDate.php +``` +After defining new layers in `ddd.php`, make sure the corresponding namespaces are also registered in your `composer.json` file. You may use the `ddd:config` helper command to handle this for you. +```bash +# Sync composer.json with ddd.php +php artisan ddd:config composer +``` + ### Nested Objects For any `ddd:*` generator command, nested objects can be specified with forward slashes. ```bash @@ -359,17 +389,12 @@ return [ | Application Layer |-------------------------------------------------------------------------- | - | Configure objects that belong in the application layer. - | - | e.g., App\Modules\Invoicing\Controllers\* - | App\Modules\Invoicing\Requests\* + | Configure domain objects in the application layer. | */ 'application' => [ - 'path' => 'app/Modules', 'namespace' => 'App\Modules', - - // Specify which ddd:* objects belong in the application layer + 'path' => 'app/Modules', 'objects' => [ 'controller', 'request', @@ -379,11 +404,31 @@ return [ /* |-------------------------------------------------------------------------- - | Generator Object Namespaces + | Custom Layers + |-------------------------------------------------------------------------- + | + | Mapping of additional top-level namespaces and paths that should + | be recognized as layers when generating ddd:* objects. + | + | e.g., 'Infrastructure' => 'src/Infrastructure', + | + | When using ddd:* generators, specifying a domain matching a key in + | this array will generate objects in that corresponding layer. + | + */ + 'layers' => [ + // 'Infrastructure' => 'src/Infrastructure', + // 'Integrations' => 'src/Integrations', + // 'Support' => 'src/Support', + ], + + /* + |-------------------------------------------------------------------------- + | Domain Object Namespaces |-------------------------------------------------------------------------- | - | This array maps the default relative namespaces of generated objects - | relative to their domain's root namespace. + | This value contains the default namespaces of ddd:* generated + | objects relative to the layer of which the object belongs to. | | e.g., Domain\Invoicing\Models\* | Domain\Invoicing\Data\* diff --git a/tests/Generator/ActionMakeTest.php b/tests/Generator/ActionMakeTest.php index ab55725..52148fb 100644 --- a/tests/Generator/ActionMakeTest.php +++ b/tests/Generator/ActionMakeTest.php @@ -58,7 +58,7 @@ Artisan::call("ddd:action {$domain}:{$given}"); expect(file_exists($expectedPath))->toBeTrue("ddd:action {$domain}:{$given} -> expected {$expectedPath} to exist."); -})->with('makeActionInputs')->only(); +})->with('makeActionInputs'); it('extends a base action if specified in config', function ($baseAction) { Config::set('ddd.base_action', $baseAction); diff --git a/tests/Support/ResolveObjectSchemaUsingTest.php b/tests/Support/ResolveObjectSchemaUsingTest.php index f43dcad..ec5ddaf 100644 --- a/tests/Support/ResolveObjectSchemaUsingTest.php +++ b/tests/Support/ResolveObjectSchemaUsingTest.php @@ -19,7 +19,7 @@ 'namespace' => 'App', ]); - DDD::resolveObjectSchemaUsing(function (string $domainName, ?string $nameInput, string $type, CommandContext $command): ?ObjectSchema { + DDD::resolveObjectSchemaUsing(function (string $domainName, string $nameInput, string $type, CommandContext $command): ?ObjectSchema { if ($type === 'controller' && $command->option('api')) { return new ObjectSchema( name: $name = str($nameInput)->replaceEnd('Controller', '')->finish('ApiController')->toString(),