denosyscore / framework
DenoSys framework runtime core
Requires
- php: ^8.4.1
- ext-fileinfo: *
- ext-pdo: *
- doctrine/inflector: ^2.1
- filp/whoops: ^2.18
- graham-campbell/result-type: ^1.1
- illuminate/collections: ^12.0
- laminas/laminas-diactoros: ^3.6
- laminas/laminas-httphandlerrunner: ^2.12
- league/flysystem: ^3.35.3
- league/flysystem-local: ^3.30
- monolog/monolog: ^3.9
- nesbot/carbon: ^3.10
- nyholm/psr7: ^1.8
- psr/container: ^2.0
- psr/event-dispatcher: ^1.0
- psr/http-factory: ^1.1
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^3.0
- psr/simple-cache: ^3.0
- ramsey/uuid: ^4.7
- symfony/console: ^7.4
- symfony/filesystem: ^7.4.23
- symfony/mailer: ^8.0
- vlucas/phpdotenv: ^5.5
Requires (Dev)
- deptrac/deptrac: ^4.7
- fakerphp/faker: ^1.24
- friendsofphp/php-cs-fixer: ^3.89
- mockery/mockery: ^1.6
- pestphp/pest: ^4.1
- pestphp/pest-plugin-stressless: ^4.0
- pestphp/pest-plugin-type-coverage: ^4.0
- phpmd/phpmd: ^2.15
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.1
- squizlabs/php_codesniffer: ^4.0
- symfony/var-dumper: ^8.0
Suggests
None
Provides
None
Conflicts
- aws/aws-sdk-php: <3.371.4
- guzzlehttp/guzzle: <7.15.2 || >=8.0.0,<8.0.1
- guzzlehttp/psr7: <2.12.3
- mtdowling/jmespath.php: <2.9.1
Replaces
- denosyscore/auth: v0.11.1
- denosyscore/cache: v0.11.1
- denosyscore/console: v0.11.1
- denosyscore/container: v0.11.1
- denosyscore/contracts: v0.11.1
- denosyscore/database: v0.11.1
- denosyscore/encryption: v0.11.1
- denosyscore/events: v0.11.1
- denosyscore/filesystem: v0.11.1
- denosyscore/hashing: v0.11.1
- denosyscore/http: v0.11.1
- denosyscore/queue: v0.11.1
- denosyscore/rate-limiter: v0.11.1
- denosyscore/routing: v0.11.1
- denosyscore/session: v0.11.1
- denosyscore/validation: v0.11.1
- denosyscore/view: v0.11.1
- dev-main / 0.11.x-dev
- v0.11.1
- v0.11.0
- v0.10.0
- v0.9.2
- v0.9.1
- v0.9.0
- v0.8.1
- v0.8.0
- v0.7.0
- v0.6.1
- v0.6.0
- v0.5.2
- v0.5.1
- v0.5.0
- v0.4.2
- v0.4.1
- v0.4.0
- v0.3.0
- v0.2.1
- v0.2.0
- v0.1.0
- dev-ci/split-credentials
- dev-ci/release-with-gh-cli
- dev-codex/console-mail-distribution
- dev-codex/fix-mailer-helper
- dev-codex/env-helper-process-values
- dev-codex/mail-provider
- dev-codex/form-mail-integration
- dev-codex/form-request-lifecycle
- dev-codex/queue-console-minor-constraints
- dev-codex/optional-env-files
This package is auto-updated.
Last update: 2026-11-12 06:24:59 UTC
README
DenoSys framework runtime core package.
Installation
composer require denosyscore/framework
Recommended App Skeleton
Use the official app skeleton for new projects:
composer create-project denosyscore/app my-app
What This Package Provides
Denosys\Applicationruntime core- Bootstrap/config/environment/routing glue under
src/ - Global framework helpers via
support/helpers.php - Every DenoSys component, developed in this repository under
packages/
Starting with 0.10.0 this repository is the DenoSys monorepo. The framework
package replaces every component, so an application that requires the
framework installs all components from this one package, at the same version.
Each component is also published on its own (for example
denosyscore/database) from a read-only split repository, for code that needs
only that component. Framework code and
public component APIs are still available under their Denosys\ namespaces.
If an application imports a third-party library directly, declare that library
in the application's own Composer requirements. PHP 8.4.1 or newer is required.
Environment files
EnvironmentManager::load($directory, $files) treats missing files in the
ordered filename list as optional. It loads the first present file according
to dotenv's normal precedence and emits no PHP warning when none are present.
The directory itself must exist. Run composer test to verify this contract
locally.
The global env() helper reads an explicit $_ENV value first and falls back
to the process environment through getenv(). Process overrides therefore work
in CLI configurations that do not populate $_ENV. Missing keys return the
provided default; the usual boolean and null string values are cast.
Mail provider
Register Denosys\Framework\Providers\MailServiceProvider with Application::withProviders()
when an application needs Symfony\Component\Mailer\MailerInterface. The
provider binds a lazy TransportInterface and mailer. Set mail.dsn for a
Symfony-supported transport, or configure mail.default as smtp or
sendmail with mail.mailers.smtp.* or mail.mailers.sendmail.path.
The global mailer() helper resolves the provider's MailerInterface binding;
it is available after registering the provider. Call send() with a Symfony
Email instance or inject MailerInterface into an application service.
Unsupported drivers throw when the mailer is resolved; they never silently
discard messages. A working transport and sender address are required before
sending account or other transactional mail.
Framework 0.7.0 requires Console 0.4.0, whose make:mail command generates
Symfony MIME Email messages accepted by this provider. Its former Markdown
option is removed because no Markdown renderer is registered by the framework.
Form requests in route handlers
The framework's registered route invocation strategy constructs a type-hinted
Denosys\Http\FormRequest subclass from the current PSR-7 request, supplies
the current authenticated user and route arguments, supplies the framework
container, and calls validate() before the handler. A denied
authorize() or invalid field rule prevents handler invocation and propagates
through the configured exception pipeline. Each invocation uses its own
request, including when the strategy and handler are reused.
Form-request subclasses should retain the package's Request constructor
contract. This behavior is provided by the framework bridge; the standalone
routing package remains independent of HTTP form requests.
HTTP routing errors
The default router returns PSR responses for routing HTTP exceptions, including 404 for unknown paths and 405 for unsupported methods. Its global HTTP exception middleware runs inside CORS so those responses retain CORS headers. Unexpected exceptions continue through the configured exception pipeline.
Framework 0.6.0 and later require database 0.4.1 or newer within that release line; CI verifies minimum and current published component combinations.
Filesystem configuration
The framework's ConfigurationInterface extends the shared
Denosys\Contracts\Config\ConfigurationReaderInterface. During application
bootstrap, the reader binding resolves the current configuration binding,
including after it is replaced. A prepared replacement container passed to
Application::setContainer() receives the reader binding if it lacks one.
FilesystemServiceProvider reads the shared interface and uses the existing
path.storage binding, keeping default local files in the storage app
directory. Framework 0.5.1 requires filesystem 0.3.2 and contracts 0.2.4 or newer
within their respective release lines. Release contracts before filesystem,
then framework, before updating a consumer's Composer lockfile.
Framework 0.5.2 raises the filesystem and Symfony Filesystem/HTTP Client
minimums to patched releases without changing the framework API.
Repository layout
| Path | Contents |
|---|---|
src/, support/, tests/ |
The framework package itself |
packages/<name>/ |
One component per directory, each with its own composer.json, README, tests and PHPStan baseline |
src/Framework/ |
Framework-owned integration: service providers (Providers/), the HTTP kernel, routing integration and framework console commands |
bin/package-ci |
Installs one package on its own, with sibling packages from this checkout, and runs its checks; layers checks package boundaries |
Every package directory is published to the read-only repository
denosyscore/<name> by the Split packages workflow. Pull requests opened
there are closed with a pointer back here.
Working on a package
bin/package-ci install packages/database bin/package-ci check database bin/package-ci quickstart database
install writes a git-ignored composer.monorepo.json that resolves sibling
packages from packages/, so a change is tested against the other packages at
the same commit. A package that uses a class it does not require fails here,
even though the root autoloader would hide it.
Package boundaries
Packages are grouped into tiers in composer.json under extra.denosys.tiers:
foundation (contracts, container, events), infrastructure (database, cache,
encryption, hashing, filesystem), HTTP (http, routing, session, validation,
rate-limiter) and features (auth, queue, view, console). A package may require
only packages in its own or a lower tier, without cycles, and its code may use
only the DenoSys packages it requires. Packages contain no service providers:
the framework's providers in src/Framework/Providers wire them together.
bin/package-ci layers
Repository workflows
- CI: framework tests, static analysis, an audit and the package boundary check. Each package is installed alone and its tests, PHPStan baseline and README quick start are run. Database tests also run against MySQL, MariaDB and PostgreSQL, and there is an HTTP and session integration check.
- Split packages: publishes
packages/*to the package repositories on every push tomainand on version tags. It needs theSPLIT_TOKENsecret. - Release: creates the GitHub release for a tag.
- Dependabot: weekly Composer updates for the root and every package, and GitHub Actions updates.
Releases
All packages share one version line (0.10). To release:
- Make sure CI passes on
main. - Push an annotated tag from that commit, for example
git tag -a v0.10.1 -m v0.10.1 && git push origin v0.10.1. - The framework release is published here. Split packages tags the package repositories: a minor release (
vX.Y.0) tags every package, and a patch release tags only packages whose directory changed since the previous tag. - Confirm the versions on Packagist before updating consumers.
Between releases, a package's requirements on other DenoSys packages use the current line (^0.10). When opening a new minor line, update extra.branch-alias in the root and every package, and those requirements, together.