Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:43:13 +08:00
commit f6d4a68978
178 changed files with 51030 additions and 0 deletions

View File

@@ -0,0 +1,468 @@
# Composer.json Validation Standards (TYPO3 v13)
**Source:** TYPO3 Core API Reference v13.4 - FileStructure/ComposerJson.html
**Purpose:** Complete validation rules for composer.json in TYPO3 extensions
## Mandatory Fields
### name
**Format:** `<vendor>/<dashed-extension-key>`
**Examples:**
```json
"name": "vendor-name/my-extension"
"name": "johndoe/some-extension"
```
**Validation:**
```bash
jq -r '.name' composer.json | grep -E '^[a-z0-9-]+/[a-z0-9-]+$' && echo "✅ Valid" || echo "❌ Invalid format"
```
### type
**Required Value:** `typo3-cms-extension` (for third-party extensions)
**Validation:**
```bash
jq -r '.type' composer.json | grep -q "typo3-cms-extension" && echo "✅ Correct type" || echo "❌ Wrong type"
```
### description
**Format:** Single-line summary describing what the extension does
**Requirements:**
- Clear, concise description of extension functionality
- Should identify the vendor/company for professional extensions
- Avoid vague descriptions like "An extension" or "Utility tools"
**Good Examples:**
```json
"description": "Adds image support to CKEditor5 RTE - by Netresearch"
"description": "TYPO3 extension for advanced content management by Vendor GmbH"
"description": "Provides custom form elements for newsletter subscription"
```
**Bad Examples:**
```json
"description": "Extension" // Too vague
"description": "Some tools" // Meaningless
"description": "" // Empty
```
**Validation:**
```bash
# Check description exists and is not empty
jq -r '.description' composer.json | grep -q . && echo "✅ Has description" || echo "❌ Missing description"
# Check description length (should be meaningful, >20 chars)
DESC_LEN=$(jq -r '.description | length' composer.json)
[[ $DESC_LEN -gt 20 ]] && echo "✅ Description is meaningful" || echo "⚠️ Description too short"
```
### license
**Recommended:** `GPL-2.0-only` or `GPL-2.0-or-later`
**Validation:**
```bash
jq -r '.license' composer.json | grep -qE "GPL-2.0-(only|or-later)" && echo "✅ GPL license" || echo "⚠️ Check license"
```
### require
**Minimum:** Must specify `typo3/cms-core` with version constraints
**Version Constraint Format:**
- `^12.4 || ^13.4` - Multiple major versions (recommended for v12/v13 compat)
- `^12.4` - Single major version
- `>=12.4` ❌ - NO upper bound (not recommended)
**Validation:**
```bash
# Check typo3/cms-core present
jq -r '.require["typo3/cms-core"]' composer.json | grep -q . && echo "✅ TYPO3 core required" || echo "❌ Missing typo3/cms-core"
# Check for upper bound (^ or specific upper version)
jq -r '.require["typo3/cms-core"]' composer.json | grep -qE '(\^|[0-9]+\.[0-9]+\.[0-9]+-[0-9]+\.[0-9]+\.[0-9]+)' && echo "✅ Has upper bound" || echo "⚠️ Missing upper bound"
```
### autoload
**Format:** PSR-4 mapping to Classes/ directory
**Example:**
```json
"autoload": {
"psr-4": {
"Vendor\\ExtensionName\\": "Classes/"
}
}
```
**Validation:**
```bash
jq -r '.autoload["psr-4"]' composer.json | grep -q "Classes" && echo "✅ PSR-4 autoload configured" || echo "❌ Missing autoload"
```
### extra.typo3/cms.extension-key
**Required:** Maps to underscored extension key
**Example:**
```json
"extra": {
"typo3/cms": {
"extension-key": "my_extension"
}
}
```
**Validation:**
```bash
jq -r '.extra."typo3/cms"."extension-key"' composer.json | grep -q . && echo "✅ Extension key defined" || echo "❌ Missing extension-key"
```
---
## Recommended Fields (Professional Extensions)
### authors
**Format:** Array of author objects with name, email, role, homepage
**Example:**
```json
"authors": [
{
"name": "Developer Name",
"email": "developer@company.com",
"role": "Developer",
"homepage": "https://www.company.com/"
}
]
```
**Required Sub-Fields:**
| Field | Format | Purpose |
|-------|--------|---------|
| `name` | String | Developer's full name |
| `email` | Email address | Contact email |
| `role` | String | `Developer`, `Maintainer`, `Lead Developer` |
| `homepage` | URL | Company or personal website |
**Validation:**
```bash
# Check authors array exists
jq -r '.authors' composer.json | grep -q "name" && echo "✅ Has authors" || echo "⚠️ Missing authors"
# Check authors have email
jq -r '.authors[].email' composer.json | grep -q "@" && echo "✅ Has author emails" || echo "⚠️ Missing author emails"
# Check authors have homepage
jq -r '.authors[].homepage' composer.json | grep -q "http" && echo "✅ Has author homepage" || echo "⚠️ Missing author homepage"
```
### homepage
**Format:** URL to project repository or documentation
**Example:**
```json
"homepage": "https://github.com/vendor/extension-name"
```
**Validation:**
```bash
jq -r '.homepage' composer.json | grep -qE "^https?://" && echo "✅ Has homepage" || echo "⚠️ Missing homepage"
```
### support
**Format:** Object with support channels
**Example:**
```json
"support": {
"issues": "https://github.com/vendor/extension/issues",
"source": "https://github.com/vendor/extension"
}
```
**Validation:**
```bash
jq -r '.support.issues' composer.json | grep -q "http" && echo "✅ Has issues URL" || echo "⚠️ Missing issues URL"
```
### keywords
**Format:** Array of relevant keywords for discoverability
**Example:**
```json
"keywords": [
"TYPO3",
"extension",
"content",
"management"
]
```
**Validation:**
```bash
jq -r '.keywords | length' composer.json | grep -qE '^[1-9]' && echo "✅ Has keywords" || echo "⚠️ Missing keywords"
```
---
## Complete Required Fields Checklist
**Mandatory (MUST have):**
- [ ] `name` - vendor/package format
- [ ] `type` - must be `typo3-cms-extension`
- [ ] `description` - clear, concise description
- [ ] `license` - SPDX identifier (GPL-2.0-or-later, AGPL-3.0-or-later)
- [ ] `require.typo3/cms-core` - with upper bound constraint
- [ ] `require.php` - PHP version constraint
- [ ] `autoload.psr-4` - mapping to Classes/
- [ ] `extra.typo3/cms.extension-key` - underscored extension key
**Recommended (SHOULD have):**
- [ ] `authors` - with name, email, role, homepage
- [ ] `homepage` - project repository URL
- [ ] `support.issues` - issue tracker URL
- [ ] `keywords` - for discoverability
---
## Deprecated Properties
### replace with typo3-ter vendor
**Status:** DEPRECATED - Legacy TER integration approach
**Detection:**
```bash
jq -r '.replace' composer.json | grep -q "typo3-ter" && echo "⚠️ Deprecated: typo3-ter in replace" || echo "✅ No deprecated replace"
```
### replace with "ext_key": "self.version"
**Status:** DEPRECATED - Legacy dependency specification
**Detection:**
```bash
jq -r '.replace' composer.json | grep -qE '"[a-z_]+": "self.version"' && echo "⚠️ Deprecated: self.version replace" || echo "✅ No self.version"
```
---
## TYPO3 v12-v13 Version Constraints
### Recommended Format
```json
"require": {
"typo3/cms-core": "^12.4 || ^13.4",
"php": "^8.1"
}
```
### PHP Version Constraints
```json
"require": {
"php": "^8.1" // TYPO3 v12: PHP 8.1-8.4
}
```
**Validation:**
```bash
# Check PHP constraint
jq -r '.require.php' composer.json | grep -qE '\^8\.[1-4]' && echo "✅ Valid PHP constraint" || echo "⚠️ Check PHP version"
```
---
## Synchronization with ext_emconf.php
**Critical:** `composer.json` and `ext_emconf.php` must have matching dependency constraints.
**Mapping:**
| composer.json | ext_emconf.php |
|--------------|----------------|
| `require.typo3/cms-core` | `constraints.depends.typo3` |
| `require.php` | `constraints.depends.php` |
| `require.*` | `constraints.depends.*` |
**Example Synchronization:**
composer.json:
```json
"require": {
"typo3/cms-core": "^12.4 || ^13.4",
"php": "^8.1",
"typo3/cms-fluid": "^12.4 || ^13.4"
}
```
ext_emconf.php:
```php
'constraints' => [
'depends' => [
'typo3' => '12.4.0-13.4.99',
'php' => '8.1.0-8.4.99',
'fluid' => '12.4.0-13.4.99',
],
],
```
---
## Complete Validation Script
```bash
#!/bin/bash
# validate-composer.sh
ERRORS=0
echo "=== Composer.json Validation ===="
# Check mandatory fields
jq -r '.name' composer.json > /dev/null 2>&1 || { echo "❌ Missing 'name'"; ((ERRORS++)); }
jq -r '.type' composer.json | grep -q "typo3-cms-extension" || { echo "❌ Wrong or missing 'type'"; ((ERRORS++)); }
jq -r '.description' composer.json | grep -q . || { echo "❌ Missing 'description'"; ((ERRORS++)); }
# Check description is meaningful (>20 chars)
DESC_LEN=$(jq -r '.description | length' composer.json 2>/dev/null)
[[ $DESC_LEN -lt 20 ]] && { echo "⚠️ Description too short (should be >20 chars)"; ((WARNINGS++)); }
# Check typo3/cms-core
jq -r '.require["typo3/cms-core"]' composer.json | grep -q . || { echo "❌ Missing typo3/cms-core"; ((ERRORS++)); }
# Check version constraints have upper bounds
jq -r '.require["typo3/cms-core"]' composer.json | grep -qE '(\^|[0-9]+\.[0-9]+\.[0-9]+-[0-9]+\.[0-9]+\.[0-9]+)' || { echo "⚠️ TYPO3 constraint missing upper bound"; ((ERRORS++)); }
# Check autoload
jq -r '.autoload["psr-4"]' composer.json | grep -q "Classes" || { echo "❌ Missing PSR-4 autoload"; ((ERRORS++)); }
# Check extension-key
jq -r '.extra."typo3/cms"."extension-key"' composer.json | grep -q . || { echo "❌ Missing extension-key"; ((ERRORS++)); }
# Check for deprecated replace
jq -r '.replace' composer.json 2>/dev/null | grep -q "typo3-ter\|self.version" && echo "⚠️ Deprecated replace property found"
echo ""
echo "Validation complete: $ERRORS critical errors"
exit $ERRORS
```
---
## Optional but Recommended Fields
### require-dev
**Purpose:** Development dependencies not needed in production
**Example:**
```json
"require-dev": {
"typo3/coding-standards": "^0.7",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.0"
}
```
### suggest
**Purpose:** Optional packages that enhance functionality
**Example:**
```json
"suggest": {
"typo3/cms-filelist": "For file browser functionality",
"typo3/cms-reactions": "For webhook support"
}
```
---
## Best Practices
1. **Packagist Publication:** Publishing to Packagist makes extensions available in TYPO3 Extension Repository automatically
2. **Documentation Rendering:** `composer.json` is **REQUIRED** for extensions with documentation on docs.typo3.org
3. **Version Constraint Strategy:**
- Use `^` for flexible upper bounds
- Specify both major version ranges for v12/v13 compatibility
- Always include upper bounds (avoid `>=` without upper limit)
4. **Namespace Alignment:** PSR-4 namespace should match vendor/extension structure
5. **Composer Priority:** Composer-based installations prioritize `composer.json` over `ext_emconf.php` for dependency resolution
---
## Common Violations and Fixes
### Missing extra.typo3/cms.extension-key
**Before:**
```json
{
"name": "vendor/my-extension",
"type": "typo3-cms-extension"
}
```
**After:**
```json
{
"name": "vendor/my-extension",
"type": "typo3-cms-extension",
"extra": {
"typo3/cms": {
"extension-key": "my_extension"
}
}
}
```
### Version Constraint Without Upper Bound
**Before:**
```json
"require": {
"typo3/cms-core": ">=12.4"
}
```
**After:**
```json
"require": {
"typo3/cms-core": "^12.4 || ^13.4"
}
```
### Deprecated replace Property
**Before:**
```json
"replace": {
"typo3-ter/my-extension": "self.version"
}
```
**After:**
```json
// Remove replace property entirely
```
---
## Additional Validation Commands
### Check all required dependencies have upper bounds
```bash
jq -r '.require | to_entries[] | select(.value | test(">=") and (test("\\^") | not)) | .key' composer.json
```
### Verify package type
```bash
jq -r '.type' composer.json | grep -q "typo3-cms-extension" && echo "✅" || echo "❌ Wrong package type"
```
### Check PSR-4 namespace format
```bash
jq -r '.autoload["psr-4"] | keys[]' composer.json | grep -E '^[A-Z][a-zA-Z0-9]*\\\\[A-Z][a-zA-Z0-9]*\\\\$' && echo "✅ Valid namespace" || echo "⚠️ Check namespace format"
```
### Validate JSON syntax
```bash
jq . composer.json > /dev/null && echo "✅ Valid JSON" || echo "❌ JSON syntax error"
```