Skip to main content

Actions enhancers

Note​

Many actions enhancers are available. Each may:

  • version: requires a minimal version of Foscia packages
  • only: be available in a specific use case (JSON:API, REST, HTTP, etc.)
  • provide: provide a given context to next enhancers or runners
  • require: require a given context from previous enhancers or runners

Examples of this guide will omit imports of your action factories or models to provide shorter examples.

@foscia/core​

when​

See Conditionals on actions core concepts.

context​

Merge the given context into the action's current context. The context is not deeply merged.

This is the most basic context enhancer. It is used by a lot of Foscia enhancers.

Example​

import { context } from '@foscia/core';

action().use(
context({
/* additional context */
}),
);

Arguments​

  • {} contextToMerge a context object to merge into the action's current context

query​

version: v0.6.3+provides: Model, Instance?, ID?, Relation?

Query the given model, instance or instance's relation.

Example​

import { query } from '@foscia/core';

// Query model.
action().use(query(Post));
// Query model's record by ID.
action().use(query(Post, '123'));
// Query model's instance.
action().use(query(myPost));
// Query model's instance's relation.
action().use(query(myPost, 'comments'));

Arguments​

Model signature​
Instance signature​

create​

requires: Serializerprovides: Model, Instance, ID

Prepare context for an instance creation (directly or through a parent relationships).

Example​

import { create } from '@foscia/core';

// Create post.
const post = new Post();
action().use(create(post));

// Create comment through existing post "comments" relation.
const comment = new Comment();
action().use(create(post, 'comments', post));

Arguments​

Instance signature​
Through instance signature​
version: v0.9.3+

update​

requires: Serializerprovides: Model, Instance, ID

Prepare context for an instance update.

Example​

import { update } from '@foscia/core';

action().use(update(post));

Arguments​

save​

requires: Serializerprovides: Model, Instance, ID

Prepare context for an instance creation or update depending on its existence state. Calls update if the instance exists, otherwise call create.

Example​

import { save } from '@foscia/core';

action().use(save(post));

Arguments​

destroy​

provides: Model, Instance, ID

Prepare context for an instance deletion.

Example​

import { destroy } from '@foscia/core';

action().use(destroy(post));

Arguments​

associate​

version: v0.8.0+requires: Serializerprovides: Model, Instance, ID, Relation

Prepare context for an instance's hasOne relation associate operation.

Example​

import { associate } from '@foscia/core';

action().use(associate(post, 'author', user));

Arguments​

dissociate​

version: v0.8.0+requires: Serializerprovides: Model, Instance, ID, Relation

Prepare context for an instance's hasOne relation dissociate operation.

Example​

import { dissociate } from '@foscia/core';

action().use(dissociate(post, 'author'));

Arguments​

attach​

version: v0.8.0+requires: Serializerprovides: Model, Instance, ID, Relation

Prepare context for an instance's hasMany relation attach operation.

Example​

import { attach } from '@foscia/core';

action().use(attach(post, 'tags', [tag1, tag2]));

Arguments​

detach​

version: v0.8.0+requires: Serializerprovides: Model, Instance, ID, Relation

Prepare context for an instance's hasMany relation detach operation.

Example​

import { detach } from '@foscia/core';

action().use(detach(post, 'tags', [tag1, tag2]));

Arguments​

updateRelation​

version: v0.8.0+requires: Serializerprovides: Model, Instance, ID, Relation

Prepare context for an instance's hasOne or hasMany relation update.

Example​

import { ActionName, updateRelation } from '@foscia/core';

action().use(updateRelation(post, 'author', user));
action().use(updateRelation(post, 'tags', [tag1, tag2]));
action().use(updateRelation(post, 'tags', [tag1, tag2], ActionName.ATTACH_RELATION));

Arguments​

instanceData​

requires: Serializer

Serialize the given instance as the context's data.

Example​

import { instanceData } from '@foscia/core';

action().use(instanceData(post));

Arguments​

relationData​

version: v0.6.1+requires: Serializer

Serialize the given instance's relation as the context's data.

Example​

import { relationData } from '@foscia/core';

action().use(relationData(post, 'tags'));

Arguments​

include​

requires: Model

Eager load the given relations for the current model definition. It accepts deep relations through dot notation. The new relations will be merged with the previous ones.

Example​

import { include } from '@foscia/core';

action().use(include('author'));
action().use(include('author', 'comments', 'comments.reactions'));
action().use(include(['author', 'comments', 'comments.reactions']));

Arguments​

onRunning​

Register a running hook callback on action. Callback may be async.

Example​

import { onRunning } from '@foscia/jsonapi';

action().use(
onRunning((event) => {
/* Do something */
}),
);

Arguments​

  • (event: { context: {}; runner: Function }) => Awaitable<void> callback callback to run on event

onSuccess​

Register a success hook callback on action. Callback may be async.

Example​

import { onSuccess } from '@foscia/jsonapi';

action().use(
onSuccess((event) => {
/* Do something */
}),
);

Arguments​

  • (event: { context: {}; result: unknown }) => Awaitable<void> callback callback to run on event

onError​

Register a error hook callback on action. Callback may be async.

Example​

import { onError } from '@foscia/jsonapi';

action().use(
onError((event) => {
/* Do something */
}),
);

Arguments​

  • (event: { context: {}; error: unknown }) => Awaitable<void> callback callback to run on event

onFinally​

Register a finally hook callback on action. Callback may be async.

Example​

import { onFinally } from '@foscia/jsonapi';

action().use(
onFinally((event) => {
/* Do something */
}),
);

Arguments​

  • (event: { context: {} }) => Awaitable<void> callback callback to run on event

@foscia/http​

makeGet​

only: HTTP

HTTP GET method shortcut for the makeRequest function.

Example​

import { makeGet } from '@foscia/http';

action().use(
makeGet('https://example.com', {
/* config */
}),
);

Arguments​

makePost​

only: HTTP

HTTP POST method shortcut for the makeRequest function.

Example​

import { makePost } from '@foscia/http';

action().use(
makePost(
'https://example.com',
{ data: 'foobar' },
{
/* config */
},
),
);

Arguments​

makePut​

only: HTTP

HTTP PUT method shortcut for the makeRequest function.

Example​

import { makePut } from '@foscia/http';

action().use(
makePut(
'https://example.com',
{ data: 'foobar' },
{
/* config */
},
),
);

Arguments​

makePatch​

only: HTTP

HTTP PATCH method shortcut for the makeRequest function.

Example​

import { makePatch } from '@foscia/http';

action().use(
makePatch(
'https://example.com',
{ data: 'foobar' },
{
/* config */
},
),
);

Arguments​

makeDelete​

only: HTTP

HTTP DELETE method shortcut for the makeRequest function.

Example​

import { makeDelete } from '@foscia/http';

action().use(
makeDelete(
'https://example.com',
{ data: 'foobar' },
{
/* config */
},
),
);

Arguments​

makeRequest​

only: HTTP

Prepare a generic HTTP request. If given path starts with scheme (HTTPS, etc.), it will be used as the base URL of action, otherwise it will only be used as path.

Example​

import { makeRequest } from '@foscia/http';

action().use(
makeRequest('https://example.com', {
/* config */
}),
);

Arguments​

configureRequest​

version: v0.7.2+only: HTTP

Configure an HTTP request used by the HTTP adapter. Some configuration options will be merged when possible (object query params, headers, transformers, etc.).

This enhancer can be used to configure a full request object or preconfigure some common options (e.g. headers and transformers).

Passing a Fetch request object as request option will ignore any other configuration and request object will be directly passed to the adapter. Transformers will still be applied, but other automatic transformation or data passing (params, body, etc.) won't be applied.

Example​

import {configureRequest} from '@foscia/http';

// Configure a request object.
action().use(configureRequest({
baseURL: 'https://example.com/api',
path: 'posts/1',
body: {
title: 'Hello World!',
},
}));
// Preconfigure common options.
action().use(configureRequest({
headers: {
Authorization: 'Bearer ...',
},
}));
// Configure with a custom fetch request object.
action().use(configureRequest({
request: new Request('https://example.com/api/posts/1', {
/* fetch request init */
}),
}));

Arguments​

param​

only: HTTP

Set the given query param on the request. The new params will be merged with the previous ones.

Example​

import { param } from '@foscia/http';

action().use(param('foo', 'foo')); // Key and value.
action().use(param({ bar: 'bar' })); // Object.

Arguments​

  • string | Dictionary key a key for the param or a params object
  • unknown | undefined value a value for the param

abortSignal​

only: HTTP

Configure an abort signal on the request to make it abortable.

Example​

import { abortSignal } from '@foscia/http';

const abortController = new AbortController();

action().use(abortSignal(abortController));

Arguments​

  • Optional<AbortController | AbortSignal> controllerOrSignal an abort controller or signal instance to configure (or undefined/null to cancel a previous configuration)

@foscia/jsonapi​

fields​

only: JSON:APIrequires: Model

Select the given JSON:API fieldsets for the current context's model. The new fieldsets will be merged with the previous ones.

Example​

import { fields } from '@foscia/jsonapi';

action().use(fields('title'));
action().use(fields('title', 'description'));
action().use(fields(['title', 'description']));

Arguments​

fieldsFor​

only: JSON:API

Select the given JSON:API fieldsets for the given model. The new fieldsets will be merged with the previous ones.

Example​

import { fieldsFor } from '@foscia/jsonapi';

action().use(fieldsFor(Post, 'title'));
action().use(fieldsFor(Post, 'title', 'description'));
action().use(fieldsFor(Post, ['title', 'description']));

Arguments​

filterBy​

only: JSON:API

Filter the JSON:API resource by the given key and value. When key is an object, it will spread the object as a filter values map. The new filter will be merged with the previous ones.

Example​

import { filterBy } from '@foscia/jsonapi';

action().use(filterBy('isPublished', true));

Arguments​

  • string | Dictionary key a key for the filter or a filter object
  • unknown | undefined value a value for the filter

sortBy​

only: JSON:API

Sort the JSON:API resource by the given keys and directions. The new sort will be merged with the previous ones. Sorts priority are kept.

Example​

import { sortBy } from '@foscia/jsonapi';

action().use(sortBy('createdAt'));
action().use(sortBy('createdAt', 'desc'));
action().use(sortBy(['name', 'createdAt'], ['asc', 'asc']));
action().use(sortBy({ name: 'asc', createdAt: 'asc' }));

Arguments​

  • Arrayable<string> | Dictionary<SortDirection> key the key(s) for the sort
  • Arrayable<'asc' | 'desc'> = 'asc' direction the direction(s) for the sort

sortByAsc​

only: JSON:API

Shortcut for the sortBy function with an asc direction.

Example​

import { sortByAsc } from '@foscia/jsonapi';

action().use(sortByAsc('createdAt'));

Arguments​

  • ArrayableVariadic<string> ...keys the key(s) for the sort

sortByDesc​

only: JSON:API

Shortcut for the sortBy function with a desc direction.

Example​

import { sortByDesc } from '@foscia/jsonapi';

action().use(sortByDesc('createdAt'));

Arguments​

  • ArrayableVariadic<string> ...keys the key(s) for the sort

paginate​

only: JSON:API

Paginate the JSON:API resource by the given params. JSON:API specification on pagination is agnostic, so page params may be anything used by your implementation.

Example​

import { paginate } from '@foscia/jsonapi';

action().use(paginate({ number: 1, size: 10 }));

Arguments​

  • unknown page a pagination value which match your implementation