mirror of
https://github.com/symfony/recipes.git
synced 2026-09-11 15:16:30 +03:00
Update Flex endpoint
This commit is contained in:
@@ -0,0 +1,343 @@
|
||||
{
|
||||
"manifests": {
|
||||
"symfony/framework-bundle": {
|
||||
"manifest": {
|
||||
"bundles": {
|
||||
"Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle": [
|
||||
"all"
|
||||
]
|
||||
},
|
||||
"copy-from-recipe": {
|
||||
"config/": "%CONFIG_DIR%/",
|
||||
"public/": "%PUBLIC_DIR%/",
|
||||
"src/": "%SRC_DIR%/",
|
||||
".editorconfig": ".editorconfig",
|
||||
"AGENTS.md": "AGENTS.md",
|
||||
"CLAUDE.md": "CLAUDE.md"
|
||||
},
|
||||
"composer-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
},
|
||||
"env": {
|
||||
"APP_ENV": "dev",
|
||||
"APP_SECRET": "",
|
||||
"APP_SHARE_DIR": "%VAR_DIR%/share"
|
||||
},
|
||||
"dotenv": {
|
||||
"dev": {
|
||||
"APP_SECRET": "%generate(secret)%"
|
||||
}
|
||||
},
|
||||
"gitignore": [
|
||||
"/.env.local",
|
||||
"/.env.local.php",
|
||||
"/.env.*.local",
|
||||
"/%CONFIG_DIR%/secrets/prod/prod.decrypt.private.php",
|
||||
"/%PUBLIC_DIR%/bundles/",
|
||||
"/%VAR_DIR%/",
|
||||
"/vendor/"
|
||||
],
|
||||
"post-install-output": [
|
||||
" * <fg=blue>Run</> your application:",
|
||||
" 1. Go to the project directory",
|
||||
" 2. Create your code repository with the <comment>git init</comment> command",
|
||||
" 3. Download the Symfony CLI at <comment>https://symfony.com/download</> to install a development web server",
|
||||
"",
|
||||
" * <fg=blue>Read</> the documentation at <comment>https://symfony.com/doc</>"
|
||||
]
|
||||
},
|
||||
"files": {
|
||||
".editorconfig": {
|
||||
"contents": [
|
||||
"# editorconfig.org",
|
||||
"",
|
||||
"root = true",
|
||||
"",
|
||||
"[*]",
|
||||
"charset = utf-8",
|
||||
"end_of_line = lf",
|
||||
"indent_size = 4",
|
||||
"indent_style = space",
|
||||
"insert_final_newline = true",
|
||||
"trim_trailing_whitespace = true",
|
||||
"",
|
||||
"[{compose.yaml,compose.*.yaml}]",
|
||||
"indent_size = 2",
|
||||
"",
|
||||
"[*.md]",
|
||||
"trim_trailing_whitespace = false",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"AGENTS.md": {
|
||||
"contents": [
|
||||
"# AGENTS.md",
|
||||
"",
|
||||
"This is a Symfony project. Check `composer.json` for the exact Symfony/PHP version",
|
||||
"in use, and read `symfony.lock` to see which recipes ran. Don't assume Doctrine,",
|
||||
"Twig, API Platform, Messenger, or Lock are installed unless one of those says so.",
|
||||
"",
|
||||
"## Ask before generating",
|
||||
"",
|
||||
"If the task doesn't specify, ask rather than guess:",
|
||||
"",
|
||||
"- Persistence: Doctrine ORM, Doctrine ODM, or none?",
|
||||
"- Interface: server-rendered (Twig), API (Serializer, maybe API Platform), or both?",
|
||||
"- Auth: SecurityBundle, and which authenticator?",
|
||||
"",
|
||||
"If you can't ask (no interactive channel), state the assumption you're making and",
|
||||
"pick the smallest option (e.g. no persistence layer) rather than scaffolding a",
|
||||
"full stack nobody asked for.",
|
||||
"",
|
||||
"## Adding features: Flex, not hand-wiring",
|
||||
"",
|
||||
"Install new capabilities with `composer require <package>` (e.g. `symfony/lock`,",
|
||||
"`symfony/messenger`, `orm-pack`) and let the Flex recipe register the bundle and",
|
||||
"generate its config. Don't hand-edit `config/bundles.php` or hand-write a bundle's",
|
||||
"base config; that's what the recipe is for. Don't skip a good-fit component just",
|
||||
"because it isn't installed yet; installing it is one command.",
|
||||
"",
|
||||
"## Conventions",
|
||||
"",
|
||||
"Follow https://symfony.com/doc/current/best_practices.html to write idiomatic",
|
||||
"Symfony:",
|
||||
"",
|
||||
"- Use PHP attributes for framework metadata, and not only on controllers:",
|
||||
" `#[Route]`, `#[MapRequestPayload]`, `#[IsGranted]` on actions, `#[Assert\\...]`",
|
||||
" on properties, `#[AsCommand]`, `#[AsEventListener]`, `#[AsMessageHandler]`, and",
|
||||
" `#[AsAlias]` / `#[AsTaggedItem]` / `#[Autoconfigure]` on services. No YAML or",
|
||||
" XML routing.",
|
||||
"- Rely on autowiring and autoconfiguration. Type-hint constructor arguments and",
|
||||
" let the container resolve them. Where a type-hint can't express it, stay in the",
|
||||
" class with `#[Autowire]` (parameters, env vars, expressions) or `#[Target]` (one",
|
||||
" of several implementations of an interface). A YAML service definition is the",
|
||||
" last resort, not the first.",
|
||||
"- Controllers extend `AbstractController`, stay thin, and delegate to services.",
|
||||
"- Use the framework for what it already does: Form for server-rendered forms,",
|
||||
" Validator for validation, Serializer for JSON, Messenger for async work,",
|
||||
" Security (voters, authenticators) for access control, Twig `path()`/`url()`",
|
||||
" instead of hardcoded URLs.",
|
||||
"- Before hand-writing infrastructure (locks, queues, caches, HTTP clients,",
|
||||
" mailers, schedulers) or reaching for a third-party library, check whether a",
|
||||
" Symfony component covers it. It usually does.",
|
||||
"",
|
||||
"Three specifics worth spelling out, because they are easy to get wrong:",
|
||||
"",
|
||||
"- Bind request data with `#[MapRequestPayload]` / `#[MapQueryString]` on action",
|
||||
" arguments, which wires up Serializer and Validator for you, instead of calling",
|
||||
" `json_decode()` or `SerializerInterface` by hand. If neither package is",
|
||||
" installed yet, `composer require` them rather than falling back to manual",
|
||||
" parsing.",
|
||||
"- Use constructor property promotion, and `readonly` for DTOs and value objects.",
|
||||
" Don't mark a service `readonly` if it might become `lazy: true`: a lazy proxy",
|
||||
" can't extend a `readonly` class.",
|
||||
"- Use `symfony/lock` (`LockFactory`) for mutual exclusion. A hand-built flag or",
|
||||
" lock file looks fine in review and is usually wrong under concurrency.",
|
||||
"",
|
||||
"## Everyday workflow",
|
||||
"",
|
||||
"- Run the app with `symfony serve -d`, and commands with `symfony console ...`",
|
||||
" (or `bin/console` when the Symfony CLI isn't available).",
|
||||
"- When something fails, read `var/log/dev.log` and the web profiler",
|
||||
" (`/_profiler`) before changing code.",
|
||||
"- If `maker-bundle` is installed, prefer `bin/console make:*` with every argument",
|
||||
" passed up front and `--no-interaction` where supported: makers prompt on a",
|
||||
" terminal by default, which hangs a non-interactive shell. If a maker still",
|
||||
" needs interactive input, hand-write the code instead.",
|
||||
"- If Doctrine ORM is installed, schema changes go through migrations",
|
||||
" (`bin/console make:migration`, then `doctrine:migrations:migrate`), never",
|
||||
" `doctrine:schema:update` or hand-written SQL.",
|
||||
"- `.env` is committed and holds defaults only. Real secrets belong in `.env.local`",
|
||||
" (git-ignored) or the secrets vault (`bin/console secrets:set`), read via",
|
||||
" `%env(...)%`.",
|
||||
"",
|
||||
"## Testing",
|
||||
"",
|
||||
"Install `symfony/test-pack` if it isn't already. Functional/HTTP tests extend",
|
||||
"`WebTestCase`; service-level tests extend `KernelTestCase`. Run",
|
||||
"`php bin/phpunit` (falls back to `vendor/bin/phpunit`). A feature isn't done",
|
||||
"until it has a test that exercises it the way a caller would, an HTTP request for",
|
||||
"a controller or a service call for a service, not just \"it didn't throw.\"",
|
||||
"",
|
||||
"## Code style",
|
||||
"",
|
||||
"Symfony's coding standard, the `@Symfony` php-cs-fixer ruleset (a PSR-12-derived",
|
||||
"superset). Run `vendor/bin/php-cs-fixer fix` if `friendsofphp/php-cs-fixer` is",
|
||||
"installed; it isn't part of the skeleton by default.",
|
||||
"",
|
||||
"## Discover, don't guess",
|
||||
"",
|
||||
"Framework APIs change between versions and your training data may be stale. Look",
|
||||
"things up in the project instead of relying on memory:",
|
||||
"",
|
||||
"- `bin/console about`: versions, environment, paths.",
|
||||
"- `bin/console debug:router`, `debug:container`, `debug:autowiring <name>`,",
|
||||
" `debug:config <bundle>`, `config:dump-reference <bundle>`: what exists and how",
|
||||
" it is configured.",
|
||||
"- `bin/console lint:container`, plus `lint:twig templates/` and",
|
||||
" `lint:yaml config/` where those packages are installed: validate before running.",
|
||||
"- Read the installed source and docblocks under `vendor/`.",
|
||||
"- Docs: https://symfony.com/doc/current/ (switch to the version matching",
|
||||
" `composer.json` if it differs).",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"CLAUDE.md": {
|
||||
"contents": [
|
||||
"# CLAUDE.md",
|
||||
"",
|
||||
"@AGENTS.md",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"config/packages/cache.yaml": {
|
||||
"contents": [
|
||||
"framework:",
|
||||
" cache:",
|
||||
" # Unique name of your app: used to compute stable namespaces for cache keys.",
|
||||
" #prefix_seed: your_vendor_name/app_name",
|
||||
"",
|
||||
" # The \"app\" cache stores to the filesystem by default.",
|
||||
" # The data in this cache should persist between deploys.",
|
||||
" # Other options include:",
|
||||
"",
|
||||
" # Redis",
|
||||
" #app: cache.adapter.redis",
|
||||
" #default_redis_provider: redis://localhost",
|
||||
"",
|
||||
" # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)",
|
||||
" #app: cache.adapter.apcu",
|
||||
"",
|
||||
" # Namespaced pools use the above \"app\" backend by default",
|
||||
" #pools:",
|
||||
" #my.dedicated.cache: null",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"config/packages/framework.yaml": {
|
||||
"contents": [
|
||||
"# see https://symfony.com/doc/current/reference/configuration/framework.html",
|
||||
"framework:",
|
||||
" secret: '%env(APP_SECRET)%'",
|
||||
"",
|
||||
" # Note that the session will be started ONLY if you read or write from it.",
|
||||
" session: true",
|
||||
"",
|
||||
" #esi: true",
|
||||
" #fragments: true",
|
||||
"",
|
||||
"when@test:",
|
||||
" framework:",
|
||||
" test: true",
|
||||
" session:",
|
||||
" storage_factory_id: session.storage.factory.mock_file",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"config/preload.php": {
|
||||
"contents": [
|
||||
"<?php",
|
||||
"",
|
||||
"foreach (glob(dirname(__DIR__).'/var/cache/prod/*.preload.php') ?: [] as $file) {",
|
||||
" require $file;",
|
||||
"}",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"config/routes/framework.yaml": {
|
||||
"contents": [
|
||||
"when@dev:",
|
||||
" _errors:",
|
||||
" resource: '@FrameworkBundle/Resources/config/routing/errors.php'",
|
||||
" prefix: /_error",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"config/services.yaml": {
|
||||
"contents": [
|
||||
"# yaml-language-server: $schema=../vendor/symfony/dependency-injection/Loader/schema/services.schema.json",
|
||||
"",
|
||||
"# This file is the entry point to configure your own services.",
|
||||
"# Files in the packages/ subdirectory configure your dependencies.",
|
||||
"# See also https://symfony.com/doc/current/service_container/import.html",
|
||||
"",
|
||||
"# Put parameters here that don't need to change on each machine where the app is deployed",
|
||||
"# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration",
|
||||
"parameters:",
|
||||
"",
|
||||
"services:",
|
||||
" # default configuration for services in *this* file",
|
||||
" _defaults:",
|
||||
" autowire: true # Automatically injects dependencies in your services.",
|
||||
" autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.",
|
||||
"",
|
||||
" # makes classes in src/ available to be used as services",
|
||||
" # this creates a service per class whose id is the fully-qualified class name",
|
||||
" App\\:",
|
||||
" resource: '../src/'",
|
||||
"",
|
||||
" # add more service definitions when explicit configuration is needed",
|
||||
" # please note that last definitions always *replace* previous ones",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"public/index.php": {
|
||||
"contents": [
|
||||
"<?php",
|
||||
"",
|
||||
"use App\\Kernel;",
|
||||
"",
|
||||
"require_once dirname(__DIR__).'/vendor/autoload_runtime.php';",
|
||||
"",
|
||||
"return static function (array $context) {",
|
||||
" return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);",
|
||||
"};",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"src/Controller/.gitignore": {
|
||||
"contents": [
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"src/Kernel.php": {
|
||||
"contents": [
|
||||
"<?php",
|
||||
"",
|
||||
"namespace App;",
|
||||
"",
|
||||
"use Symfony\\Bundle\\FrameworkBundle\\Kernel\\MicroKernelTrait;",
|
||||
"use Symfony\\Component\\HttpKernel\\Kernel as BaseKernel;",
|
||||
"",
|
||||
"class Kernel extends BaseKernel",
|
||||
"{",
|
||||
" use MicroKernelTrait;",
|
||||
"",
|
||||
" /**",
|
||||
" * @return list<string> An array of allowed values for APP_ENV",
|
||||
" */",
|
||||
" private function getAllowedEnvs(): array",
|
||||
" {",
|
||||
" return ['prod', 'dev', 'test'];",
|
||||
" }",
|
||||
"}",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
}
|
||||
},
|
||||
"ref": "5295b2b1ef2170b272383b2b0ae0b66702883822"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,9 @@
|
||||
"config/": "%CONFIG_DIR%/",
|
||||
"public/": "%PUBLIC_DIR%/",
|
||||
"src/": "%SRC_DIR%/",
|
||||
".editorconfig": ".editorconfig"
|
||||
".editorconfig": ".editorconfig",
|
||||
"AGENTS.md": "AGENTS.md",
|
||||
"CLAUDE.md": "CLAUDE.md"
|
||||
},
|
||||
"composer-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
@@ -69,6 +71,129 @@
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"AGENTS.md": {
|
||||
"contents": [
|
||||
"# AGENTS.md",
|
||||
"",
|
||||
"This is a Symfony project. Check `composer.json` for the exact Symfony/PHP version",
|
||||
"in use, and read `symfony.lock` to see which recipes ran. Don't assume Doctrine,",
|
||||
"Twig, API Platform, Messenger, or Lock are installed unless one of those says so.",
|
||||
"",
|
||||
"## Ask before generating",
|
||||
"",
|
||||
"If the task doesn't specify, ask rather than guess:",
|
||||
"",
|
||||
"- Persistence: Doctrine ORM, Doctrine ODM, or none?",
|
||||
"- Interface: server-rendered (Twig), API (Serializer, maybe API Platform), or both?",
|
||||
"- Auth: SecurityBundle, and which authenticator?",
|
||||
"",
|
||||
"If you can't ask (no interactive channel), state the assumption you're making and",
|
||||
"pick the smallest option (e.g. no persistence layer) rather than scaffolding a",
|
||||
"full stack nobody asked for.",
|
||||
"",
|
||||
"## Adding features: Flex, not hand-wiring",
|
||||
"",
|
||||
"Install new capabilities with `composer require <package>` (e.g. `symfony/lock`,",
|
||||
"`symfony/messenger`, `orm-pack`) and let the Flex recipe register the bundle and",
|
||||
"generate its config. Don't hand-edit `config/bundles.php` or hand-write a bundle's",
|
||||
"base config; that's what the recipe is for. Don't skip a good-fit component just",
|
||||
"because it isn't installed yet; installing it is one command.",
|
||||
"",
|
||||
"## Conventions",
|
||||
"",
|
||||
"Follow https://symfony.com/doc/current/best_practices.html to write idiomatic",
|
||||
"Symfony:",
|
||||
"",
|
||||
"- Use PHP attributes for framework metadata, and not only on controllers:",
|
||||
" `#[Route]`, `#[MapRequestPayload]`, `#[IsGranted]` on actions, `#[Assert\\...]`",
|
||||
" on properties, `#[AsCommand]`, `#[AsEventListener]`, `#[AsMessageHandler]`, and",
|
||||
" `#[AsAlias]` / `#[AsTaggedItem]` / `#[Autoconfigure]` on services. No YAML or",
|
||||
" XML routing.",
|
||||
"- Rely on autowiring and autoconfiguration. Type-hint constructor arguments and",
|
||||
" let the container resolve them. Where a type-hint can't express it, stay in the",
|
||||
" class with `#[Autowire]` (parameters, env vars, expressions) or `#[Target]` (one",
|
||||
" of several implementations of an interface). A YAML service definition is the",
|
||||
" last resort, not the first.",
|
||||
"- Controllers extend `AbstractController`, stay thin, and delegate to services.",
|
||||
"- Use the framework for what it already does: Form for server-rendered forms,",
|
||||
" Validator for validation, Serializer for JSON, Messenger for async work,",
|
||||
" Security (voters, authenticators) for access control, Twig `path()`/`url()`",
|
||||
" instead of hardcoded URLs.",
|
||||
"- Before hand-writing infrastructure (locks, queues, caches, HTTP clients,",
|
||||
" mailers, schedulers) or reaching for a third-party library, check whether a",
|
||||
" Symfony component covers it. It usually does.",
|
||||
"",
|
||||
"Three specifics worth spelling out, because they are easy to get wrong:",
|
||||
"",
|
||||
"- Bind request data with `#[MapRequestPayload]` / `#[MapQueryString]` on action",
|
||||
" arguments, which wires up Serializer and Validator for you, instead of calling",
|
||||
" `json_decode()` or `SerializerInterface` by hand. If neither package is",
|
||||
" installed yet, `composer require` them rather than falling back to manual",
|
||||
" parsing.",
|
||||
"- Use constructor property promotion, and `readonly` for DTOs and value objects.",
|
||||
" Don't mark a service `readonly` if it might become `lazy: true`: a lazy proxy",
|
||||
" can't extend a `readonly` class.",
|
||||
"- Use `symfony/lock` (`LockFactory`) for mutual exclusion. A hand-built flag or",
|
||||
" lock file looks fine in review and is usually wrong under concurrency.",
|
||||
"",
|
||||
"## Everyday workflow",
|
||||
"",
|
||||
"- Run the app with `symfony serve -d`, and commands with `symfony console ...`",
|
||||
" (or `bin/console` when the Symfony CLI isn't available).",
|
||||
"- When something fails, read `var/log/dev.log` and the web profiler",
|
||||
" (`/_profiler`) before changing code.",
|
||||
"- If `maker-bundle` is installed, prefer `bin/console make:*` with every argument",
|
||||
" passed up front and `--no-interaction` where supported: makers prompt on a",
|
||||
" terminal by default, which hangs a non-interactive shell. If a maker still",
|
||||
" needs interactive input, hand-write the code instead.",
|
||||
"- If Doctrine ORM is installed, schema changes go through migrations",
|
||||
" (`bin/console make:migration`, then `doctrine:migrations:migrate`), never",
|
||||
" `doctrine:schema:update` or hand-written SQL.",
|
||||
"- `.env` is committed and holds defaults only. Real secrets belong in `.env.local`",
|
||||
" (git-ignored) or the secrets vault (`bin/console secrets:set`), read via",
|
||||
" `%env(...)%`.",
|
||||
"",
|
||||
"## Testing",
|
||||
"",
|
||||
"Install `symfony/test-pack` if it isn't already. Functional/HTTP tests extend",
|
||||
"`WebTestCase`; service-level tests extend `KernelTestCase`. Run",
|
||||
"`php bin/phpunit` (falls back to `vendor/bin/phpunit`). A feature isn't done",
|
||||
"until it has a test that exercises it the way a caller would, an HTTP request for",
|
||||
"a controller or a service call for a service, not just \"it didn't throw.\"",
|
||||
"",
|
||||
"## Code style",
|
||||
"",
|
||||
"Symfony's coding standard, the `@Symfony` php-cs-fixer ruleset (a PSR-12-derived",
|
||||
"superset). Run `vendor/bin/php-cs-fixer fix` if `friendsofphp/php-cs-fixer` is",
|
||||
"installed; it isn't part of the skeleton by default.",
|
||||
"",
|
||||
"## Discover, don't guess",
|
||||
"",
|
||||
"Framework APIs change between versions and your training data may be stale. Look",
|
||||
"things up in the project instead of relying on memory:",
|
||||
"",
|
||||
"- `bin/console about`: versions, environment, paths.",
|
||||
"- `bin/console debug:router`, `debug:container`, `debug:autowiring <name>`,",
|
||||
" `debug:config <bundle>`, `config:dump-reference <bundle>`: what exists and how",
|
||||
" it is configured.",
|
||||
"- `bin/console lint:container`, plus `lint:twig templates/` and",
|
||||
" `lint:yaml config/` where those packages are installed: validate before running.",
|
||||
"- Read the installed source and docblocks under `vendor/`.",
|
||||
"- Docs: https://symfony.com/doc/current/ (switch to the version matching",
|
||||
" `composer.json` if it differs).",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"CLAUDE.md": {
|
||||
"contents": [
|
||||
"# CLAUDE.md",
|
||||
"",
|
||||
"@AGENTS.md",
|
||||
""
|
||||
],
|
||||
"executable": false
|
||||
},
|
||||
"config/packages/cache.yaml": {
|
||||
"contents": [
|
||||
"framework:",
|
||||
@@ -212,7 +337,7 @@
|
||||
"executable": false
|
||||
}
|
||||
},
|
||||
"ref": "a47c48a1aeef8d67111d94e6bdf8aac2826b4f43"
|
||||
"ref": "5295b2b1ef2170b272383b2b0ae0b66702883822"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user