diff --git a/Makefile b/Makefile
index 84a42c12..5fd77d4e 100644
--- a/Makefile
+++ b/Makefile
@@ -52,6 +52,9 @@ test-cache: phpunit
test-clock: PHPUNIT_TESTSUITE=clock
test-clock: phpunit
+test-cookie: PHPUNIT_TESTSUITE=cookie
+test-cookie: phpunit
+
test-cqrs: PHPUNIT_TESTSUITE=cqrs
test-cqrs: phpunit
diff --git a/bard.json b/bard.json
index 8837d7fa..a3d28056 100644
--- a/bard.json
+++ b/bard.json
@@ -13,6 +13,10 @@
"path": "src/SonsOfPHP/Component/Clock",
"repository": "git@github.com:SonsOfPHP/clock.git"
},
+ {
+ "path": "src/SonsOfPHP/Component/Cookie",
+ "repository": "git@github.com:SonsOfPHP/cookie.git"
+ },
{
"path": "src/SonsOfPHP/Component/Cqrs",
"repository": "git@github.com:SonsOfPHP/cqrs.git"
@@ -101,6 +105,10 @@
"path": "src/SonsOfPHP/Contract/Common",
"repository": "git@github.com:SonsOfPHP/common-contract.git"
},
+ {
+ "path": "src/SonsOfPHP/Contract/Cookie",
+ "repository": "git@github.com:SonsOfPHP/cookie-contract.git"
+ },
{
"path": "src/SonsOfPHP/Contract/Cqrs",
"repository": "git@github.com:SonsOfPHP/cqrs-contract.git"
diff --git a/composer.json b/composer.json
index d42f8f7f..40bf6b78 100644
--- a/composer.json
+++ b/composer.json
@@ -47,7 +47,8 @@
"psr/log-implementation": "^1.0 || ^2.0 || ^3.0",
"sonsofphp/logger-implementation": "0.3.x-dev",
"sonsofphp/pager-implementation": "0.3.x-dev",
- "psr/link-implementation": "^1.0 || ^2.0"
+ "psr/link-implementation": "^1.0 || ^2.0",
+ "sonsofphp/cookie-implementation": "0.3.x-dev"
},
"require": {
"php": ">=8.1",
@@ -74,7 +75,8 @@
"twig/twig": "^3.0",
"ext-intl": "*",
"doctrine/collections": "^2",
- "doctrine/orm": "^2"
+ "doctrine/orm": "^2",
+ "sonsofphp/cookie-contract": "0.3.x-dev"
},
"replace": {
"sonsofphp/bard": "self.version",
@@ -110,13 +112,16 @@
"sonsofphp/money-twig": "self.version",
"sonsofphp/pager-doctrine-collections": "self.version",
"sonsofphp/pager-doctrine-dbal": "self.version",
- "sonsofphp/pager-doctrine-orm": "self.version"
+ "sonsofphp/pager-doctrine-orm": "self.version",
+ "sonsofphp/cookie": "self.version",
+ "sonsofphp/cookie-contract": "self.version"
},
"autoload": {
"psr-4": {
"SonsOfPHP\\Bard\\": "src/SonsOfPHP/Bard/src",
"SonsOfPHP\\Component\\Cache\\": "src/SonsOfPHP/Component/Cache",
"SonsOfPHP\\Component\\Clock\\": "src/SonsOfPHP/Component/Clock",
+ "SonsOfPHP\\Component\\Cookie\\": "src/SonsOfPHP/Component/Cookie",
"SonsOfPHP\\Component\\Cqrs\\": "src/SonsOfPHP/Component/Cqrs",
"SonsOfPHP\\Bundle\\Cqrs\\": "src/SonsOfPHP/Bundle/Cqrs",
"SonsOfPHP\\Bridge\\Symfony\\Cqrs\\": "src/SonsOfPHP/Bridge/Symfony/Cqrs",
@@ -139,6 +144,7 @@
"SonsOfPHP\\Bridge\\Doctrine\\ORM\\Pager\\": "src/SonsOfPHP/Bridge/Doctrine/ORM/Pager",
"SonsOfPHP\\Component\\Version\\": "src/SonsOfPHP/Component/Version",
"SonsOfPHP\\Contract\\Common\\": "src/SonsOfPHP/Contract/Common",
+ "SonsOfPHP\\Contract\\Cookie\\": "src/SonsOfPHP/Contract/Cookie",
"SonsOfPHP\\Contract\\Cqrs\\": "src/SonsOfPHP/Contract/Cqrs",
"SonsOfPHP\\Contract\\EventSourcing\\": "src/SonsOfPHP/Contract/EventSourcing",
"SonsOfPHP\\Contract\\FeatureToggle\\": "src/SonsOfPHP/Contract/FeatureToggle",
@@ -152,6 +158,7 @@
"src/SonsOfPHP/Bard/Tests",
"src/SonsOfPHP/Component/Cache/Tests",
"src/SonsOfPHP/Component/Clock/Tests",
+ "src/SonsOfPHP/Component/Cookie/Tests",
"src/SonsOfPHP/Component/Cqrs/Tests",
"src/SonsOfPHP/Bundle/Cqrs/Tests",
"src/SonsOfPHP/Bridge/Symfony/Cqrs/Tests",
diff --git a/mkdocs.yml b/mkdocs.yml
index b8b29ee1..9c0fc364 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -79,6 +79,7 @@ nav:
- components/index.md
- Cache: components/cache/index.md
- Clock: components/clock/index.md
+ - Cookie: components/cookie/index.md
- CQRS:
- components/cqrs/index.md
- Event Dispatcher: components/event-dispatcher/index.md
@@ -118,5 +119,6 @@ nav:
- Contracts:
- contracts/index.md
- Common: contracts/common/index.md
+ - Cookie: contracts/cookie/index.md
- Cqrs: contracts/cqrs/index.md
- Pager: contracts/pager/index.md
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 5ab54b33..db3a9659 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -30,6 +30,10 @@
src/SonsOfPHP/Component/Clock/Tests
+
+ src/SonsOfPHP/Component/Cookie/Tests
+
+
src/SonsOfPHP/Bridge/*/Cqrs/Tests
diff --git a/src/SonsOfPHP/Component/Cookie/.gitattributes b/src/SonsOfPHP/Component/Cookie/.gitattributes
new file mode 100644
index 00000000..84c7add0
--- /dev/null
+++ b/src/SonsOfPHP/Component/Cookie/.gitattributes
@@ -0,0 +1,4 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
diff --git a/src/SonsOfPHP/Component/Cookie/.gitignore b/src/SonsOfPHP/Component/Cookie/.gitignore
new file mode 100644
index 00000000..5414c2c6
--- /dev/null
+++ b/src/SonsOfPHP/Component/Cookie/.gitignore
@@ -0,0 +1,3 @@
+composer.lock
+phpunit.xml
+vendor/
diff --git a/src/SonsOfPHP/Component/Cookie/Cookie.php b/src/SonsOfPHP/Component/Cookie/Cookie.php
new file mode 100644
index 00000000..5b97ca82
--- /dev/null
+++ b/src/SonsOfPHP/Component/Cookie/Cookie.php
@@ -0,0 +1,163 @@
+
+ */
+class Cookie implements CookieInterface
+{
+ public function __construct(
+ private string $name,
+ private string $value = '',
+ private array $options = ['expires' => 0, 'secure' => false, 'httponly' => false],
+ ) {}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withName(string $name): static
+ {
+ if ($name === $this->name) {
+ return $this;
+ }
+
+ $that = clone $this;
+ $that->name = $name;
+
+ return $that;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withValue(string $value): static
+ {
+ if ($value === $this->value) {
+ return $this;
+ }
+
+ $that = clone $this;
+ $that->value = $value;
+
+ return $that;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withPath(string $path): static
+ {
+ if (array_key_exists('path', $this->options) && $path === $this->options['path']) {
+ return $this;
+ }
+
+ $that = clone $this;
+ $that->options['path'] = $path;
+
+ return $that;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withDomain(string $domain): static
+ {
+ if (array_key_exists('domain', $this->options) && $domain === $this->options['domain']) {
+ return $this;
+ }
+
+ $that = clone $this;
+ $that->options['domain'] = $domain;
+
+ return $that;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withSecure(bool $secure): static
+ {
+ if (array_key_exists('secure', $this->options) && $secure === $this->options['secure']) {
+ return $this;
+ }
+
+ $that = clone $this;
+ $that->options['secure'] = $secure;
+
+ return $that;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withHttpOnly(bool $httpOnly): static
+ {
+ if (array_key_exists('httponly', $this->options) && $httpOnly === $this->options['httponly']) {
+ return $this;
+ }
+
+ $that = clone $this;
+ $that->options['httponly'] = $httpOnly;
+
+ return $that;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withSameSite(string $sameSite): static
+ {
+ if (array_key_exists('samesite', $this->options) && $sameSite === $this->options['samesite']) {
+ return $this;
+ }
+
+ if (!in_array(strtolower($sameSite), ['none', 'lax', 'strict'])) {
+ throw new \InvalidArgumentException('Invalid value for $sameSite');
+ }
+
+ $that = clone $this;
+ $that->options['samesite'] = $sameSite;
+
+ return $that;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function withExpires(\DateTimeImmutable|int|string $expires): static
+ {
+ if (is_string($expires)) {
+ $expires = (new \DateTimeImmutable($expires))->format('U');
+ } elseif ($expires instanceof \DateTimeImmutable) {
+ $expires = $expires->format('U');
+ }
+
+ if (array_key_exists('expires', $this->options) && $expires === $this->options['expires']) {
+ return $this;
+ }
+
+ $that = clone $this;
+ $that->options['expires'] = $expires;
+
+ return $that;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function send(bool $raw = false): void
+ {
+ if (true === $raw) {
+ // raw dog those values
+ setrawcookie($this->name, $this->value, $this->options);
+ return;
+ }
+
+ setcookie($this->name, $this->value, $this->options);
+ }
+}
diff --git a/src/SonsOfPHP/Component/Cookie/LICENSE b/src/SonsOfPHP/Component/Cookie/LICENSE
new file mode 100644
index 00000000..39238382
--- /dev/null
+++ b/src/SonsOfPHP/Component/Cookie/LICENSE
@@ -0,0 +1,19 @@
+Copyright 2022 to Present Joshua Estes
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/SonsOfPHP/Component/Cookie/README.md b/src/SonsOfPHP/Component/Cookie/README.md
new file mode 100644
index 00000000..2245d139
--- /dev/null
+++ b/src/SonsOfPHP/Component/Cookie/README.md
@@ -0,0 +1,16 @@
+Sons of PHP - Cookie
+====================
+
+## Learn More
+
+* [Documentation][docs]
+* [Contributing][contributing]
+* [Report Issues][issues] and [Submit Pull Requests][pull-requests] in the [Mother Repository][mother-repo]
+* Get Help & Support using [Discussions][discussions]
+
+[discussions]: https://github.com/orgs/SonsOfPHP/discussions
+[mother-repo]: https://github.com/SonsOfPHP/sonsofphp
+[contributing]: https://docs.sonsofphp.com/contributing/
+[docs]: https://docs.sonsofphp.com/components/cookie/
+[issues]: https://github.com/SonsOfPHP/sonsofphp/issues?q=is%3Aopen+is%3Aissue+label%3ACookie
+[pull-requests]: https://github.com/SonsOfPHP/sonsofphp/pulls?q=is%3Aopen+is%3Apr+label%3ACookie
diff --git a/src/SonsOfPHP/Component/Cookie/Tests/CookieTest.php b/src/SonsOfPHP/Component/Cookie/Tests/CookieTest.php
new file mode 100644
index 00000000..2caf52dd
--- /dev/null
+++ b/src/SonsOfPHP/Component/Cookie/Tests/CookieTest.php
@@ -0,0 +1,104 @@
+assertInstanceOf(CookieInterface::class, $cookie);
+ }
+
+ /**
+ * @covers ::withName
+ */
+ public function testWithName(): void
+ {
+ $cookie = new Cookie('test');
+
+ $this->assertSame($cookie, $cookie->withName('test'));
+ $this->assertNotSame($cookie, $cookie->withName('test2'));
+ }
+
+ /**
+ * @covers ::withValue
+ */
+ public function testWithValue(): void
+ {
+ $cookie = new Cookie('test', 'value');
+
+ $this->assertSame($cookie, $cookie->withValue('value'));
+ $this->assertNotSame($cookie, $cookie->withValue('value2'));
+ }
+
+ /**
+ * @covers ::withPath
+ */
+ public function testWithPath(): void
+ {
+ $cookie = (new Cookie('test'))->withPath('/');
+
+ $this->assertSame($cookie, $cookie->withPath('/'));
+ $this->assertNotSame($cookie, $cookie->withPath('/testing'));
+ }
+
+ /**
+ * @covers ::withDomain
+ */
+ public function testWithDomain(): void
+ {
+ $cookie = (new Cookie('test'))->withDomain('sonsofphp.com');
+
+ $this->assertSame($cookie, $cookie->withDomain('sonsofphp.com'));
+ $this->assertNotSame($cookie, $cookie->withDomain('docs.sonsofphp.com'));
+ }
+
+ /**
+ * @covers ::withSecure
+ */
+ public function testWithSecure(): void
+ {
+ $cookie = new Cookie('test');
+
+ $this->assertSame($cookie, $cookie->withSecure(false));
+ $this->assertNotSame($cookie, $cookie->withSecure(true));
+ }
+
+ /**
+ * @covers ::withHttpOnly
+ */
+ public function testWithHttpOnly(): void
+ {
+ $cookie = new Cookie('test');
+
+ $this->assertSame($cookie, $cookie->withHttpOnly(false));
+ $this->assertNotSame($cookie, $cookie->withHttpOnly(true));
+ }
+
+ /**
+ * @covers ::withSameSite
+ */
+ public function testWithSameSite(): void
+ {
+ $cookie = (new Cookie('test'))->withSameSite('none');
+
+ $this->assertSame($cookie, $cookie->withSameSite('none'));
+ $this->assertNotSame($cookie, $cookie->withSameSite('strict'));
+ }
+}
diff --git a/src/SonsOfPHP/Component/Cookie/composer.json b/src/SonsOfPHP/Component/Cookie/composer.json
new file mode 100644
index 00000000..96bc1774
--- /dev/null
+++ b/src/SonsOfPHP/Component/Cookie/composer.json
@@ -0,0 +1,54 @@
+{
+ "name": "sonsofphp/cookie",
+ "type": "library",
+ "description": "Manage Cookies with ease",
+ "keywords": [
+ "cookie"
+ ],
+ "homepage": "https://github.com/SonsOfPHP/cookie",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Joshua Estes",
+ "email": "joshua@sonsofphp.com"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/SonsOfPHP/sonsofphp/issues",
+ "forum": "https://github.com/orgs/SonsOfPHP/discussions",
+ "docs": "https://docs.sonsofphp.com"
+ },
+ "autoload": {
+ "psr-4": {
+ "SonsOfPHP\\Component\\Cookie\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "require": {
+ "php": ">=8.1",
+ "sonsofphp/cookie-contract": "0.3.x-dev"
+ },
+ "provide": {
+ "sonsofphp/cookie-implementation": "0.3.x-dev"
+ },
+ "extra": {
+ "sort-packages": true,
+ "branch-alias": {
+ "dev-main": "0.3.x-dev"
+ }
+ },
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/JoshuaEstes"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/subscription/pkg/packagist-sonsofphp-sonsofphp"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/SonsOfPHP/Component/Pager/README.md b/src/SonsOfPHP/Component/Pager/README.md
index 79b97e64..94b314db 100644
--- a/src/SonsOfPHP/Component/Pager/README.md
+++ b/src/SonsOfPHP/Component/Pager/README.md
@@ -1,5 +1,5 @@
-Sons of PHP - Logger
-====================
+Sons of PHP - Pager
+===================
## Learn More
@@ -11,6 +11,6 @@ Sons of PHP - Logger
[discussions]: https://github.com/orgs/SonsOfPHP/discussions
[mother-repo]: https://github.com/SonsOfPHP/sonsofphp
[contributing]: https://docs.sonsofphp.com/contributing/
-[docs]: https://docs.sonsofphp.com/components/logger/
-[issues]: https://github.com/SonsOfPHP/sonsofphp/issues?q=is%3Aopen+is%3Aissue+label%3ALogger
-[pull-requests]: https://github.com/SonsOfPHP/sonsofphp/pulls?q=is%3Aopen+is%3Apr+label%3ALogger
+[docs]: https://docs.sonsofphp.com/components/pager/
+[issues]: https://github.com/SonsOfPHP/sonsofphp/issues?q=is%3Aopen+is%3Aissue+label%3APager
+[pull-requests]: https://github.com/SonsOfPHP/sonsofphp/pulls?q=is%3Aopen+is%3Apr+label%3APager
diff --git a/src/SonsOfPHP/Contract/Cookie/.gitattributes b/src/SonsOfPHP/Contract/Cookie/.gitattributes
new file mode 100644
index 00000000..3a01b372
--- /dev/null
+++ b/src/SonsOfPHP/Contract/Cookie/.gitattributes
@@ -0,0 +1,2 @@
+/.gitattributes export-ignore
+/.gitignore export-ignore
diff --git a/src/SonsOfPHP/Contract/Cookie/.gitignore b/src/SonsOfPHP/Contract/Cookie/.gitignore
new file mode 100644
index 00000000..d8a7996a
--- /dev/null
+++ b/src/SonsOfPHP/Contract/Cookie/.gitignore
@@ -0,0 +1,2 @@
+composer.lock
+vendor/
diff --git a/src/SonsOfPHP/Contract/Cookie/CookieExceptionInterface.php b/src/SonsOfPHP/Contract/Cookie/CookieExceptionInterface.php
new file mode 100644
index 00000000..90c06107
--- /dev/null
+++ b/src/SonsOfPHP/Contract/Cookie/CookieExceptionInterface.php
@@ -0,0 +1,10 @@
+
+ */
+interface CookieExceptionInterface {}
diff --git a/src/SonsOfPHP/Contract/Cookie/CookieInterface.php b/src/SonsOfPHP/Contract/Cookie/CookieInterface.php
new file mode 100644
index 00000000..36c59c0a
--- /dev/null
+++ b/src/SonsOfPHP/Contract/Cookie/CookieInterface.php
@@ -0,0 +1,55 @@
+
+ */
+interface CookieInterface
+{
+ /**
+ * Set's the cookie name
+ *
+ * If the $name is the same, it will return the same object, however if the
+ * $name is different than the current $name, it will return a new instance
+ * of cookie
+ */
+ public function withName(string $name): static;
+
+ /**
+ */
+ public function withValue(string $value): static;
+
+ /**
+ */
+ public function withPath(string $path): static;
+
+ /**
+ */
+ public function withDomain(string $domain): static;
+
+ /**
+ */
+ public function withSecure(bool $secure): static;
+
+ /**
+ */
+ public function withHttpOnly(bool $httpOnly): static;
+
+ /**
+ * @throws CookieExceptionInterface if argument is invalid
+ */
+ public function withSameSite(string $sameSite): static;
+
+ /**
+ * @throws CookieExceptionInterface
+ */
+ public function withExpires(\DateTimeImmutable|int|string $expires): static;
+
+ /**
+ * @throws CookieExceptionInterface is something went wrong
+ */
+ public function send(bool $raw = false): void;
+}
diff --git a/src/SonsOfPHP/Contract/Cookie/CookieManagerInterface.php b/src/SonsOfPHP/Contract/Cookie/CookieManagerInterface.php
new file mode 100644
index 00000000..66b8c859
--- /dev/null
+++ b/src/SonsOfPHP/Contract/Cookie/CookieManagerInterface.php
@@ -0,0 +1,17 @@
+
+ */
+interface CookieManagerInterface
+{
+ public function get(string $name): CookieInterface;
+
+ public function has(string $name): bool;
+
+ public function remove(string $name): bool;
+}
diff --git a/src/SonsOfPHP/Contract/Cookie/LICENSE b/src/SonsOfPHP/Contract/Cookie/LICENSE
new file mode 100644
index 00000000..39238382
--- /dev/null
+++ b/src/SonsOfPHP/Contract/Cookie/LICENSE
@@ -0,0 +1,19 @@
+Copyright 2022 to Present Joshua Estes
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/SonsOfPHP/Contract/Cookie/README.md b/src/SonsOfPHP/Contract/Cookie/README.md
new file mode 100644
index 00000000..4f25aaa6
--- /dev/null
+++ b/src/SonsOfPHP/Contract/Cookie/README.md
@@ -0,0 +1,16 @@
+Sons of PHP - Cookie Contract
+=============================
+
+## Learn More
+
+* [Documentation][docs]
+* [Contributing][contributing]
+* [Report Issues][issues] and [Submit Pull Requests][pull-requests] in the [Mother Repository][mother-repo]
+* Get Help & Support using [Discussions][discussions]
+
+[discussions]: https://github.com/orgs/SonsOfPHP/discussions
+[mother-repo]: https://github.com/SonsOfPHP/sonsofphp
+[contributing]: https://docs.sonsofphp.com/contributing/
+[docs]: https://docs.sonsofphp.com/contracts/cookie/
+[issues]: https://github.com/SonsOfPHP/sonsofphp/issues?q=is%3Aopen+is%3Aissue+label%3ACookie
+[pull-requests]: https://github.com/SonsOfPHP/sonsofphp/pulls?q=is%3Aopen+is%3Apr+label%3ACookie
diff --git a/src/SonsOfPHP/Contract/Cookie/composer.json b/src/SonsOfPHP/Contract/Cookie/composer.json
new file mode 100644
index 00000000..6aed6a6c
--- /dev/null
+++ b/src/SonsOfPHP/Contract/Cookie/composer.json
@@ -0,0 +1,52 @@
+{
+ "name": "sonsofphp/cookie-contract",
+ "type": "library",
+ "description": "",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "homepage": "https://github.com/SonsOfPHP/cookie-contract",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Joshua Estes",
+ "email": "joshua@sonsofphp.com"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/SonsOfPHP/sonsofphp/issues",
+ "forum": "https://github.com/orgs/SonsOfPHP/discussions",
+ "docs": "https://docs.sonsofphp.com"
+ },
+ "autoload": {
+ "psr-4": {
+ "SonsOfPHP\\Contract\\Cookie\\": ""
+ }
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "require": {
+ "php": ">=8.1"
+ },
+ "extra": {
+ "sort-packages": true,
+ "branch-alias": {
+ "dev-main": "0.3.x-dev"
+ }
+ },
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/JoshuaEstes"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/subscription/pkg/packagist-sonsofphp-sonsofphp"
+ }
+ ]
+}
\ No newline at end of file