REST and GraphQL payload URLs are derived from the request that produced the response. A simulator listening on a random port returns repository, issue, pull request, commit, ref, branch, and organization URLs that point back at that same host and port.
apiUrl controls the mounted API root and is included in API URLs:
import {type InitialState, simulation} from 'simulacat-core';
const initialState: InitialState = {
users: [],
organizations: [{login: 'acme'}],
repositories: [{owner: 'acme', name: 'awesome-repo'}],
branches: [],
blobs: []
};
const app = simulation({
apiUrl: '/api/v3',
initialState
});
const server = await app.listen(0);
try {
const baseUrl = `http://127.0.0.1:${server.port}`;
const repository = await fetch(`${baseUrl}/api/v3/repos/acme/awesome-repo`)
.then((response) => response.json());
console.log(JSON.stringify(repository));
} finally {
await server.ensureClose();
}
A request to /api/v3/repos/acme/awesome-repo returns API links under
/api/v3/... and web links under /... on the request host.
Fixture URL fields are overrides. When a fixture explicitly seeds a URL, the
projectors preserve it; when the field is omitted, the adapters derive it from
the request. Nullable URL fields can still be set to null deliberately.
import {simulation} from 'simulacat-core';
const app = simulation({
initialState: {
users: [],
organizations: [{login: 'acme'}],
repositories: [
{
owner: 'acme',
name: 'awesome-repo',
html_url: 'https://docs.example.test/acme/awesome-repo',
mirror_url: null
}
],
branches: [],
blobs: []
}
});
const server = await app.listen(0);
try {
const repository = await fetch(`http://127.0.0.1:${server.port}/repos/acme/awesome-repo`)
.then((response) => response.json());
console.log(JSON.stringify(repository));
} finally {
await server.ensureClose();
}
If a request has no usable Host header, Simulacat Core uses the absolute
SIMULACAT_GITHUB_API_URL environment variable as a fallback base. Normal HTTP
requests should not need that fallback because the request host is preferred.