Skip to content

ext-typo3: add Composer integration section #90

@toderash

Description

@toderash

TYPO3 has been a fully Composer-based ecosystem since v10. ext-typo3.md is
currently silent on Composer integration, leaving extension authors with no
guidance on how to declare FAIR identity in their packages, and leaving build
tools and CI pipelines with no spec to implement against.

Partially addresses #88 (the undocumented JSON snippet in the Common section
is superseded by the material here).

Depends on:


Breaking change: extra.fair.package-meta rename

Before this section is merged, the FAIR Composer fork and fair-handler plugin
must be updated to rename the install-time verification extras from:

"extra": { "fair": { "did": "...", "checksum": "...", "signature": "..." } }

to:

"extra": { "fair": { "package-meta": { "did": "...", "checksum": "...", "signature": "..." } } }

extra.fair.package-meta is what PackageFactory embeds in Packagist/aggregator
responses for FairDownloader and the plugin hooks to read at install time.
extra.fair.package-did (defined below) is what extension authors write in their
own composer.json to declare FAIR identity. These are distinct keys in distinct
contexts — the rename makes that unambiguous.

Projects will need to regenerate their lock file after upgrading to the updated
plugin or fork. Without regeneration, FairDownloader's null-guard for missing
extra.fair data means verification silently passes through rather than fails,
which is the worse failure mode.


1. extra.fair.package-did in an extension's composer.json

Extension authors SHOULD declare their FAIR package DID in
extra.fair.package-did:

{
  "name": "acme/my-extension",
  "type": "typo3-cms-extension",
  "extra": {
    "typo3/cms": {
      "extension-key": "my_extension"
    },
    "fair": {
      "package-did": "did:plc:abc123..."
    }
  }
}

This establishes the Composer → FAIR direction of the bidirectional link. The
FAIR → Composer direction is the composer-name field in the FAIR Metadata
Document. Both SHOULD be present for packages distributed through both systems.

The SHOULD (not MUST) level is intentional. Packages registered in FAIR without
a Composer distribution omit package-did. Packages on Packagist without a FAIR
registration omit composer-name. When both are present, build tools and CI
pipelines can discover FAIR support from either side without requiring a live
aggregator query, and can add signature verification steps that are not available
through standard Composer alone.


2. Consumer-side FairRepository configuration

A project consuming TYPO3 extensions via FAIR configures a fair repository in
its composer.json. Two forms are supported:

Explicit name mapping (recommended when the Composer name is known):

{
  "repositories": [
    {
      "type": "fair",
      "packages": {
        "acme/my-extension": "did:plc:abc123..."
      }
    }
  ]
}

DID list with vendor prefix (name derived from the metadata slug):

{
  "repositories": [
    {
      "type": "fair",
      "dids": ["did:plc:abc123..."],
      "vendor": "acme"
    }
  ]
}

In the second form the package name is derived as {vendor}/{slug} from the
FAIR Metadata Document. If vendor is omitted it defaults to fair.

Once AspireCloud's Packagist-compatible API is available, a single
type: composer repository entry pointing at AspireCloud replaces both of
these forms for most projects.


3. Dependency mapping

When generating a FAIR release record from a TYPO3 extension's composer.json,
build tools MUST map require entries as follows:

composer.json require FAIR release record
php: ">=8.1" requires: { "env:php": ">=8.1" }
typo3/cms-core: "^12.4 || ^13.0" requires: { "env:typo3": ">=12.4.0 <14.0.0" }
ext-json: "*" requires: { "env:php-json": "*" }
acme/other-ext: "^2.0" (has FAIR DID) requires: { "did:plc:...": ">=2.0.0 <3.0.0" }
paragonie/sodium_compat: "^2.0" (no DID) x-composer-requires: { "paragonie/sodium_compat": "^2.0" }

Rules:

  • phpenv:php
  • typo3/cms-coreenv:typo3. This is the only typo3/cms-* package that
    generates an env:typo3 entry. Other typo3/cms-* packages are covered by
    this constraint and MUST NOT generate additional env: entries.
  • ext-{name}env:php-{name}
  • Packagist packages with a known FAIR DID → DID key in requires. Build tools
    SHOULD query the aggregator's reverse lookup endpoint to resolve names to DIDs.
  • Everything else → x-composer-requires

Composer constraint syntax (^, ~, || ranges) MUST be normalized to semver
range syntax when writing FAIR release records.

The compatibility field (#89) follows the same mapping rules, using the tested
ceiling rather than the required floor:

composer.json FAIR compatibility
Tested up to PHP 8.3 "env:php": ">=8.1 <=8.3"
Tested up to TYPO3 13.4 "env:typo3": ">=12.4.0 <=13.4.0"

4. Author identity

When generating a FAIR Metadata Document from composer.json:

  • Each entry in authors with a name maps to a FAIR author object.
    homepage and email are carried over if present.
  • extra.fair.package-did identifies the package. If the publishing entity
    differs from the listed authors (e.g. an organization account), this
    distinction is recorded in the DID document, not in composer.json.

5. Common section cleanup

The current Common section contains this undocumented snippet:

keywords: [],
compatibility: [],
typo3: {
   extension-key: "key-name"
}

This is not valid JSON and none of the three fields are defined anywhere in the
spec. Proposed resolution:

  • extension-key is shown in proper context in the extra.fair.package-did
    example above (as extra."typo3/cms".extension-key). The snippet should be
    removed and replaced with a reference to the Composer integration section.
  • compatibility maps to the compatibility property on the Release Document
    (spec: add compatibility property to Release Document #89). The Common section should note this with a reference rather than
    redeclaring it.
  • keywords is an existing optional field on the Metadata Document (core spec).
    The Common section should note it is available without redefining it, or omit
    it if there is nothing TYPO3-specific to add.

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussionNeeds discussion beforehanddocumentationImprovements or additions to documentation
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions