diff --git a/.github/pull_request_tempalet.md b/.github/pull_request_template.md
similarity index 100%
rename from .github/pull_request_tempalet.md
rename to .github/pull_request_template.md
diff --git a/.gitignore b/.gitignore
index 2e9c4f6..29f0943 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,24 +1,31 @@
-/vendor/
-node_modules/
-npm-debug.log
-yarn-error.log
-
-# Laravel 4 specific
-bootstrap/compiled.php
-app/storage/
-
-# Laravel 5 & Lumen specific
-public/storage
-public/hot
+/vendor
+composer.lock
+composer.phar
+.DS_Store
+/node_modules
+/public/storage
+/storage/*.key
+Thumbs.db
+/bower_components
-# Laravel 5 & Lumen specific with changed public path
-public_html/storage
-public_html/hot
-
-storage/*.key
.env
-.idea/
-Homestead.yaml
+.env.backup
+.idea
+.vscode
+
+.vagrant
Homestead.json
-/.vagrant
+Homestead.yaml
+npm-debug.log
+
+.phpunit.cache
.phpunit.result.cache
+/storage/.license
+/storage/fonts
+/storage/installing
+/storage/installed
+/log
+build
+package-lock.json
+yarn.lock
+/.sass-cache
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
new file mode 100644
index 0000000..dcc939f
--- /dev/null
+++ b/.scrutinizer.yml
@@ -0,0 +1,42 @@
+build:
+ nodes:
+ analysis:
+ project_setup:
+ override: true
+ tests:
+ override: [ php-scrutinizer-run ]
+ environment:
+ php:
+ version: 8.0
+
+checks:
+ php:
+ code_rating: true
+ remove_extra_empty_lines: true
+ remove_php_closing_tag: true
+ remove_trailing_whitespace: true
+ fix_use_statements:
+ remove_unused: true
+ preserve_multiple: false
+ preserve_blanklines: true
+ order_alphabetically: true
+ fix_php_opening_tag: true
+ fix_linefeed: true
+ fix_line_ending: true
+ fix_identation_4spaces: true
+ fix_doc_comments: true
+
+tools:
+ php_analyzer: true
+ php_code_coverage: true
+ php_code_sniffer:
+ config:
+ standard: PSR4
+ filter:
+ paths: [ 'src' ]
+ php_loc:
+ enabled: true
+ excluded_dirs: [ vendor ]
+ php_cpd:
+ enabled: true
+ excluded_dirs: [ vendor ]
diff --git a/.styleci.yml b/.styleci.yml
new file mode 100644
index 0000000..06256fb
--- /dev/null
+++ b/.styleci.yml
@@ -0,0 +1,4 @@
+preset: laravel
+
+disabled:
+ - not_operator_with_successor_space
diff --git a/common/helpers.php b/common/helpers.php
new file mode 100644
index 0000000..e69de29
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..d48c5c7
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,70 @@
+{
+ "name": "cslant/blog-api-package",
+ "description": "Send notification from Gitlab and Github events to Telegram",
+ "keywords": [
+ "cslant",
+ "laravel",
+ "cslant-blog-api-package",
+ "cslant-blog-api",
+ "cslant-blog",
+ "cslant-api",
+ "cslant-package",
+ "blog-api-package"
+ ],
+ "homepage": "https://github.com/cslant/blog-api-package",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Tan Nguyen",
+ "email": "tannp27@gmail.com",
+ "homepage": "https://tanhongit.com",
+ "role": "Developer"
+ }
+ ],
+ "autoload": {
+ "psr-4": {
+ "CSlant\\BlogApi\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "CSlant\\BlogApi\\Tests\\": "tests/"
+ }
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^v3.0",
+ "nunomaduro/collision": "^7.10",
+ "nunomaduro/larastan": "^2.9",
+ "orchestra/testbench": "^8.0",
+ "pestphp/pest": "^2.0",
+ "phpstan/extension-installer": "^1.3",
+ "phpstan/phpstan-deprecation-rules": "^1.1",
+ "phpstan/phpstan-phpunit": "^1.3"
+ },
+ "scripts": {
+ "analyse": "vendor/bin/phpstan analyse",
+ "format": "vendor/bin/php-cs-fixer fix --allow-risky=yes"
+ },
+ "support": {
+ "issues": "https://github.com/cslant/blog-api-package/issues"
+ },
+ "extra": {
+ "laravel": {
+ "providers": [
+ "CSlant\\BlogApi\\Providers\\BlogApiServiceProvider"
+ ]
+ }
+ },
+ "config": {
+ "sort-packages": true,
+ "allow-plugins": {
+ "pestphp/pest-plugin": true,
+ "phpstan/extension-installer": true
+ }
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true
+}
diff --git a/config/blog-api.php b/config/blog-api.php
new file mode 100644
index 0000000..3d8509d
--- /dev/null
+++ b/config/blog-api.php
@@ -0,0 +1,10 @@
+ [
+ /* Set route prefix for the blog API */
+ 'route_prefix' => $routePrefix,
+ ],
+];
diff --git a/lang/en/blog-api.php b/lang/en/blog-api.php
new file mode 100644
index 0000000..65283c3
--- /dev/null
+++ b/lang/en/blog-api.php
@@ -0,0 +1,5 @@
+ 'Hello from the blog API!',
+];
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
new file mode 100644
index 0000000..2d0db27
--- /dev/null
+++ b/phpstan-baseline.neon
@@ -0,0 +1,7 @@
+parameters:
+ ignoreErrors:
+ - message: '#Parameter \#1 \$prefix of static method Illuminate\\Support\\Facades\\Route::prefix\(\) expects string, mixed given\.#'
+ path: routes/blog-api.php
+
+ - message: '#Part \$routePrefix \(mixed\) of encapsed string cannot be cast to string\.#'
+ path: routes/blog-api.php
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..5da8159
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,11 @@
+includes:
+ - phpstan-baseline.neon
+
+parameters:
+ level: 9
+ paths:
+ - src
+ - routes
+ tmpDir: build/phpstan
+ checkOctaneCompatibility: true
+ checkModelProperties: true
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000..3b5640c
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ src/
+
+
+
+
+ tests
+
+
+
diff --git a/routes/blog-api.php b/routes/blog-api.php
new file mode 100644
index 0000000..166cb52
--- /dev/null
+++ b/routes/blog-api.php
@@ -0,0 +1,24 @@
+name("$routePrefix.")->group(function () {
+ Route::get('/hello', function () {
+ return response()->json([
+ 'message' => 'Hello from the blog API!',
+ ]);
+ });
+});
diff --git a/src/Models/Traits/IsIncrementing.php b/src/Models/Traits/IsIncrementing.php
new file mode 100644
index 0000000..8f136bf
--- /dev/null
+++ b/src/Models/Traits/IsIncrementing.php
@@ -0,0 +1,8 @@
+loadRoutesFrom($routePath);
+ }
+
+ $this->loadTranslationsFrom(__DIR__.'/../../lang', 'blog-api');
+
+ $this->registerCommands();
+
+ $this->registerAssetPublishing();
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register(): void
+ {
+ $configPath = __DIR__.'/../../config/blog-api.php';
+ $this->mergeConfigFrom($configPath, 'blog-api');
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array|null
+ */
+ public function provides(): ?array
+ {
+ return ['blog-api'];
+ }
+
+ /**
+ * @return void
+ */
+ protected function registerCommands(): void
+ {
+ $this->commands([
+ //
+ ]);
+ }
+
+ /**
+ * @return void
+ */
+ protected function registerAssetPublishing(): void
+ {
+ $configPath = __DIR__.'/../../config/blog-api.php';
+ $this->publishes([
+ $configPath => config_path('blog-api.php'),
+ ], 'config');
+
+ $this->publishes([
+ __DIR__.'/../../lang' => resource_path('lang/packages/blog-api'),
+ ], 'lang');
+ }
+}
diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php
new file mode 100644
index 0000000..55bdbe1
--- /dev/null
+++ b/tests/IntegrationTest.php
@@ -0,0 +1,7 @@
+