Saloon integration
Implement third-party HTTP API SDKs in the phpdevkits style with SaloonPHP. Covers the connector + resources + DTOs + requests layout, fixture-driven Pest testing with PII redaction, and the live-recording workflow. Use when building a new Saloon-based SDK (e.g. forge-sdk, a future stripe-sdk), adding a new resource to one, debugging a fixture-related test failure, or recovering from a spec-vs-runtime API surprise.From its SKILL.md
npx -y skills add fbarrento/laravel-agent-kit --skill saloon-integrationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.5 KB, ~1.0k tokens by cl100k_base, as published. Nobody here has run it
Saloon Integration (phpdevkits style)
Use this skill when working inside a SaloonPHP-based SDK in this repo's
shape — single Connector extending Saloon's Connector, organized by
Resources/ + Requests/ + Data/ + Enums/ + Exceptions/, with
recorded Saloon fixtures driving Pest tests at 100% coverage.
For general Pest / factory conventions that aren't Saloon-specific (no
it(), factories under tests/Factories/, exception-test styles), see
the pest-package-tests skill — this skill assumes those and only
covers the Saloon side.
Quick start
A minimal slice (one resource, one request, one DTO, one fixture-backed test):
// src/Data/Widget.php
final readonly class Widget implements JsonSerializable {
public function __construct(public string $id, public string $name) {}
public static function from(array $data): self { /* hydration + validation */ }
public function jsonSerialize(): array { /* snake_case */ }
}
// src/Requests/GetWidget.php
final class GetWidget extends Request {
protected Method $method = Method::GET;
public function __construct(private readonly int|string $id) {}
#[Override] public function resolveEndpoint(): string {
return sprintf('/widgets/%s', $this->id);
}
}
// src/Resources/WidgetResource.php
final class WidgetResource extends BaseResource {
public function get(): Widget {
$data = $this->connector->send(new GetWidget($this->id))->json('data');
return Widget::from($data);
}
}
// tests/Unit/Resources/WidgetResourceTest.php
test('get() returns a hydrated Widget', function (): void {
$mockClient = new MockClient([
GetWidget::class => new WidgetFixture('widgets/get'),
]);
$sdk = new MySdk('token')->withMockClient($mockClient);
expect($sdk->widget(1)->get())->toBeInstanceOf(Widget::class);
});
The WidgetFixture is a project-local subclass of a base
Tests\Utils\<SdkName>Fixture that adds resource-specific redaction
rules — see TESTING.md.
Rule index
- Architecture → rules/architecture.md — namespace layout, connector responsibilities, exception hierarchy, org-context / nested-resource chains.
- Resources → rules/resources.md — collection
vs. item resources,
ParsesPagefor cursor pagination,iterate()helpers, action methods, write-DTO patterns. - DTOs → rules/data.md — readonly output DTOs
(
from()/jsonSerialize()), input DTOs (toArray()stripping nulls), when to add enums. - Requests → rules/requests.md —
Requestclass shape,HasJsonBodybody trait, query params viadefaultQuery(), common Saloon API gotchas. - Testing & fixtures → rules/testing.md —
ForgeFixture-style PII redaction, noMockResponse::make(), no hand-crafted fixtures, lifecycle tests with try/finally cleanup. - Recording workflow → rules/recording.md —
.envsetup, Saloon auto-record default, poisoned-fixture recovery, cursor-walk recording. - Pitfalls → rules/pitfalls.md — common
spec-vs-runtime mismatches, Saloon traps (
#[Override]ondefaultBody(), MockClient class-vs-sequence mode, clone helpers dropping the mock), coverage attribution quirks.
How to apply
- Confirm you're in a SaloonPHP-based SDK matching the namespace layout in rules/architecture.md. If not, this skill doesn't apply — fall back to upstream Saloon docs.
- Identify which slice you're building (a new resource? new endpoint on an existing resource?). Read the matching rule file before writing code.
- For new resources, scaffold the DTO + factory first, then the request class, then the resource, then the test. Run the test once with no fixture to record from the live API.
- Whenever Forge's actual response surprises you, append to
docs/FINDINGS.mdwith the date — see rules/pitfalls.md for the entry template.
What ships with it: 7 files
41.7 KB alongside SKILL.md
rules/
- architecture.md5.1 KB
- data.md6.7 KB
- pitfalls.md6.3 KB
- recording.md5.5 KB
- requests.md4.6 KB
- resources.md5.9 KB
- testing.md7.6 KB