Skip to content

Add TYPO3 extension support and package search endpoint#45

Merged
jdevalk merged 13 commits intomainfrom
typo3-plugin-package-search
Mar 20, 2026
Merged

Add TYPO3 extension support and package search endpoint#45
jdevalk merged 13 commits intomainfrom
typo3-plugin-package-search

Conversation

@jdevalk
Copy link
Copy Markdown
Member

@jdevalk jdevalk commented Mar 20, 2026

Summary

  • Add typo3-core and typo3-extension to the PackageType enum, aligning with the FAIR protocol extension registry (Add Typo3 support to Protocol Extension Registry fair-protocol#63)
  • Add GET /packages/{type} search endpoint with full-text search (tsvector + GIN), tag matching, and trigram fallback for fuzzy results
  • Add requires version filter — e.g. ?requires[typo3]=12.4 returns packages with a release requiring TYPO3 <= 12.4
  • Make DID document route type constraint dynamic via PackageType::values() so future types are automatically supported
  • Add migration with search indexes (tsvector GIN, trigram GiST on name/slug, B-tree on type)
  • Use PackageSearchRequest DTO (beacon-hq/bag) for request validation
  • Add TYPO3 extension seeder with 10 sample extensions for local testing

Search API

Endpoint: GET /packages/{type}

Parameters:

Param Type Description
q string (optional) Search query — matches name, slug, description, and tags
requires[key] string (optional) Version filter — e.g. requires[typo3]=12.4 or requires[php]=8.1. Returns packages with at least one release whose required version is <= the specified version
page int (optional, default 1) Page number
per_page int (optional, default 24, max 100) Results per page

Examples:

GET /packages/typo3-extension
GET /packages/typo3-extension?q=gallery
GET /packages/typo3-extension?q=seo&requires[typo3]=12.4
GET /packages/wp-plugin?q=forms&requires[php]=8.1
GET /packages/typo3-extension?per_page=10&page=2

Demo data

A Typo3ExtensionSeeder is included with 10 realistic TYPO3 extensions (News System, Powermail, Solr, Mask, etc.), each with tags and releases that include TYPO3 version requirements (11.5/12.4/13.4).

php artisan db:seed --class=Typo3ExtensionSeeder

Test plan

  • Start Docker and run php artisan migrate — new migration applies cleanly
  • Run php artisan test tests/Feature/API/FAIR/PackageSearchControllerTest.php — all 11 tests pass
  • Run php artisan test — no regressions (157 passed)
  • Seed test data: php artisan db:seed --class=Typo3ExtensionSeeder
  • curl /packages/typo3-extension returns listing of seeded extensions
  • curl /packages/typo3-extension?q=gallery returns matching results
  • curl "/packages/typo3-extension?requires[typo3]=12.4" filters by TYPO3 version

🤖 Generated with Claude Code

jdevalk and others added 2 commits March 20, 2026 14:42
Extend the FAIR package system with a typo3-plugin package type and a
new GET /packages/{type} search endpoint with full-text search, tag
matching, trigram fallback, and pagination.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
@jdevalk jdevalk force-pushed the typo3-plugin-package-search branch from 3b73f74 to 725b1ff Compare March 20, 2026 13:42
Eager load relations (releases, authors, tags, metas) in search queries
to avoid lazy loading violations. Remove explicit id from
withSpecificTags factory since HasUuids auto-generates it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
jdevalk and others added 6 commits March 20, 2026 15:14
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
10 realistic TYPO3 extensions with tags for local testing. Runs as part
of db:seed and skips if TYPO3 extensions already exist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
The requires field now only includes 'php', making the factory
generic for all package types instead of WordPress-specific.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
Add typo3() state to PackageReleaseFactory that sets requires with
typo3 version (11.5/12.4/13.4) and PHP 8.1+. Use it in the TYPO3
extension seeder for realistic test data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
Aligns with the FAIR protocol extension registry (fairpm/fair-protocol#63)
which defines all three TYPO3 types: typo3-core, typo3-extension, typo3-theme.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
Copy link
Copy Markdown
Collaborator

@chuckadams chuckadams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall. Using DTOs isn't a hard requirement, but it does help keep the controller and service in sync as the protocol evolves.

Replace inline Laravel validation with a beacon-hq/bag DTO, keeping
the controller and service in sync as the protocol evolves. Uses
#[FromRouteParameter] for the type param and #[StripExtraParameters]
to match existing project conventions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
@SvenLie
Copy link
Copy Markdown

SvenLie commented Mar 20, 2026

I would like to filter for TYPO3 (and then it would be also possible for Wordpress) versions.

@jdevalk
Copy link
Copy Markdown
Member Author

jdevalk commented Mar 20, 2026

adding filter as suggested by @SvenLie

jdevalk and others added 3 commits March 20, 2026 17:09
Filter packages by platform version via ?requires[typo3]=12.4 or
?requires[php]=8.1. Matches packages with at least one release whose
required version is <= the specified version, using Postgres jsonb
and array comparison for dotted version strings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
Replace inline response()->json() with a PackageSearchResponse DTO
that transforms the paginator into the response structure, keeping
both input and output using the beacon-hq/bag DTO pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joost de Valk <joost@altha.nl>
Copy link
Copy Markdown

@SvenLie SvenLie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it. Thank you! :)

@jdevalk jdevalk merged commit 45de135 into main Mar 20, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants