Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

Package icon

npm package @xima-media/tca-api-client

CI npm Node License

The frontend half of the TYPO3 extension TCA API. The TCA API serves the records of a TYPO3 site as JSON and writes an OpenAPI spec of them; this package turns that spec into types and makes typed requests with them. The two belong together: without the TCA API there is no spec.

✨ Features

  • Client: typed GET, POST, PATCH, DELETE on top of openapi-fetch; every failed request throws an ApiError
  • Helpers for the TCA API's formats: Hydra lists and range filters
  • CLI for the types: generate them from the spec, compare them in CI, check the code against them

🔥 Installation

Requirements: a TYPO3 project with the TCA API, Node.js 18+.

npm install @xima-media/tca-api-client openapi-fetch
npm install --save-dev openapi-typescript
npm install --save-dev svelte-check   # optional, for `check` in Svelte projects
Folder Holds Runs in
src/ the client the browser
src/helpers/ Hydra lists, range filters the browser
cli/ the tca-api-client command Node

💡 Usage

1. Spec and types. The TCA API writes the spec, the package the types. Commit the types; their diff shows every API change.

vendor/bin/typo3 tca-api:openapi <site> --output var/api/openapi.json
npx tca-api-client generate var/api/openapi.json src/api/schema.d.ts

2. Client. Create it once, typed by the generated types:

import { createApiClient } from '@xima-media/tca-api-client'

/** @type {import('openapi-fetch').Client<import('./schema').paths>} */
export const api = createApiClient({ baseUrl: '' })

baseUrl can be a function, read on every request, e.g. for a language prefix. headers are sent with every request.

3. Requests. Paths, parameters and fields autocomplete from the types.

import { ApiError, dayRange, hydraPage, today } from '@xima-media/tca-api-client'

const { data } = await api.GET('/_api/events', { params: { query: { start_date: dayRange(today()), page: 1 } } })
const { items, total, nextPage } = hydraPage(data)

try {
  await api.PATCH('/_api/offers/{uid}', { params: { path: { uid: 12 } }, body: { title: '' } })
} catch (error) {
  if (error instanceof ApiError && error.status === 422) errors = error.fieldErrors() // { title: ['…'] }
}
Export Does
createApiClient({ baseUrl, headers }) an openapi-fetch client that throws ApiError on every response that is not ok; a FormData body is sent as multipart/form-data
ApiError status, url, message and title from the API's error body; on a 422 violations and fieldErrors() per field
hydraItems(data), hydraPage(data) rows, or { items, total, nextPage }, of a list, with or without the hydra: prefix
dayRange(from?, to?), today() two YYYY-MM-DD days as { gte, lte } in Unix seconds, the format of the range filter

Array parameters are named as the spec writes them ('type[]'), because PHP reads repeated keys as a list only with [].

4. CI. Both commands exit with 1 on a finding.

Command Fails when
tca-api-client compare <openapi.json> <schema.d.ts> the committed types differ from the spec; prints the diff
tca-api-client check <source dir> [--ext svelte,js] [--exclude dir] [--tsconfig file] the code does not fit the types; runs svelte-check, default --ext svelte

The types are only as good as the spec. Where the spec and a real response disagree, the fix belongs in the TCA API.

🧑‍💻 Contributing

Please have a look at CONTRIBUTING.md.

⭐ License

This project is licensed under GNU General Public License 2.0 (or later).

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages