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