aaronfrancis/docsync

Sync documentation from GitHub repositories and serve them in your Laravel application

Installs: 36

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/aaronfrancis/docsync

v0.1.0 2025-12-30 19:58 UTC

This package is auto-updated.

Last update: 2025-12-30 23:47:03 UTC


README

Latest Version on Packagist Tests Total Downloads PHP Version License

Sync documentation from GitHub repositories and serve them in your Laravel application.

Features

  • Git sparse checkout - Efficiently clones only the docs folder from repositories
  • Markdown parsing - CommonMark + GFM with Torchlight syntax highlighting
  • Navigation generation - Builds navigation trees from _meta.json files
  • Table of contents - Automatically extracts headings for TOC
  • Pagination - Previous/next page navigation
  • Caching - Built-in caching for production performance
  • Filament integration - Optional admin panel for managing documentation projects

Requirements

  • PHP 8.2+
  • Laravel 11 or 12
  • Torchlight account (for syntax highlighting)

Installation

composer require aaronfrancis/docsync

Publish the configuration and migration:

php artisan vendor:publish --tag=docsync-config
php artisan vendor:publish --tag=docsync-migrations
php artisan migrate

Configuration

// config/docsync.php

return [
    // Where synced docs are stored
    'storage_path' => storage_path('app/docs'),

    // Config key for GitHub token (for private repos)
    'github_token_key' => 'services.github.token',

    // Cache settings
    'cache' => [
        'enabled' => true,
        'ttl' => 3600, // 1 hour
    ],
];

Set your GitHub token in config/services.php:

'github' => [
    'token' => env('GITHUB_TOKEN'),
],

Usage

Creating Documentation Projects

Projects are stored in the database. Create them however you prefer:

use AaronFrancis\DocSync\Models\DocumentationProject;

DocumentationProject::create([
    'slug' => 'my-package',
    'name' => 'My Package',
    'description' => 'Documentation for my package',
    'repository_url' => 'https://github.com/org/repo',
    'branch' => 'main',
    'docs_path' => 'docs',
    'sort_order' => 0,
    'is_active' => true,
]);

Syncing Documentation

Sync all active projects:

php artisan docs:sync

Sync a specific project:

php artisan docs:sync --project=my-package

Scheduling Syncs

Add to your routes/console.php:

use Illuminate\Support\Facades\Schedule;

Schedule::command('docs:sync')
    ->hourly()
    ->withoutOverlapping()
    ->runInBackground();

Using the Service

use AaronFrancis\DocSync\Facades\DocSync;
// or inject: AaronFrancis\DocSync\Services\DocumentationService

// Get all packages
$packages = DocSync::getPackages();

// Get a single package
$package = DocSync::getPackage('my-package');

// Get navigation tree
$navigation = DocSync::getNavigation('my-package');

// Get a page
$page = DocSync::getPage('my-package', 'getting-started');

// Get table of contents from HTML
$toc = DocSync::getTableOfContents($page['content']);

// Get pagination (previous/next)
$pagination = DocSync::getPagination('my-package', 'getting-started');

// Get next steps (upcoming pages with descriptions)
$nextSteps = DocSync::getNextSteps('my-package', 'getting-started', 3);

// Clear cache
DocSync::clearCache(); // all
DocSync::clearCache('my-package'); // specific package

Documentation Structure

Your repository should have a docs folder (or whatever you configure) with:

docs/
├── _meta.json      # Navigation structure
├── index.md        # Landing page
├── getting-started.md
└── advanced/
    └── configuration.md

The _meta.json defines navigation:

{
  "pages": [
    { "slug": "index", "title": "Introduction" },
    { "slug": "getting-started", "title": "Getting Started" },
    {
      "slug": "advanced",
      "title": "Advanced",
      "children": [
        { "slug": "configuration", "title": "Configuration" }
      ]
    }
  ]
}

Markdown files support frontmatter:

---
title: Getting Started
description: Learn how to get started with the package
---

# Getting Started

Your content here...

Filament Integration

If you're using Filament, register the resource in your panel provider:

use AaronFrancis\DocSync\Filament\Resources\DocumentationProjectResource;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->resources([
            DocumentationProjectResource::class,
        ]);
}

This provides a full CRUD interface for managing documentation projects with sync actions.

Building Your Frontend

This package handles syncing and parsing—you build the frontend. Here's a basic controller example:

use AaronFrancis\DocSync\Facades\DocSync;

class DocsController extends Controller
{
    public function index()
    {
        return view('docs.index', [
            'packages' => DocSync::getPackages(),
        ]);
    }

    public function show(string $package, ?string $slug = null)
    {
        $currentPackage = DocSync::getPackage($package);
        abort_unless($currentPackage, 404);

        $page = DocSync::getPage($package, $slug);
        abort_unless($page, 404);

        return view('docs.show', [
            'page' => $page,
            'navigation' => DocSync::getNavigation($package),
            'toc' => DocSync::getTableOfContents($page['content']),
            'pagination' => DocSync::getPagination($package, $slug),
            'packages' => DocSync::getPackages(),
            'currentPackage' => $currentPackage,
        ]);
    }
}

Testing

composer test

Code Style

composer format

License

MIT License. See LICENSE for details.