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
{}contextToMergea context object to merge into the action's current context
query
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
Modelquerythe model to queryModelIdType | undefinedidthe record's ID to query
Instance signature
ModelInstanceinstancethe instance to queryModelRelationKey | undefinedrelationthe optional instance's relation to query
create
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
I extends ModelInstanceinstancean instance to create
Through instance signature
I extends ModelInstancethroughInstancean instance to create throughK extends ModelRelationKeythroughRelationa relation ofthroughInstanceto create throughRI extends ModelInstanceinstancean instance to create
update
Prepare context for an instance update.
Example
import { update } from '@foscia/core';
action().use(update(post));
Arguments
I extends ModelInstanceinstancean instance of model to update
save
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
I extends ModelInstanceinstancean instance of model to save
destroy
Prepare context for an instance deletion.
Example
import { destroy } from '@foscia/core';
action().use(destroy(post));
Arguments
I extends ModelInstanceinstancean instance of model to delete
associate
Prepare context for an instance's hasOne relation associate operation.
Example
import { associate } from '@foscia/core';
action().use(associate(post, 'author', user));
Arguments
I extends ModelInstanceinstancean instance of model to update relation onModelRelationKey<M>relationa relation to updateModelInferPropValue<R>valuean instance to associate
dissociate
Prepare context for an instance's hasOne relation dissociate operation.
Example
import { dissociate } from '@foscia/core';
action().use(dissociate(post, 'author'));
Arguments
I extends ModelInstanceinstancean instance of model to update relation onModelRelationKey<M>relationa relation to update
attach
Prepare context for an instance's hasMany relation attach operation.
Example
import { attach } from '@foscia/core';
action().use(attach(post, 'tags', [tag1, tag2]));
Arguments
I extends ModelInstanceinstancean instance of model to update relation onModelRelationKey<M>relationa relation to updateModelInferPropValue<R> | ModelInferPropValue<R>[number]valueone or many instance to attach
detach
Prepare context for an instance's hasMany relation detach operation.
Example
import { detach } from '@foscia/core';
action().use(detach(post, 'tags', [tag1, tag2]));
Arguments
I extends ModelInstanceinstancean instance of model to update relation onModelRelationKey<M>relationa relation to updateModelInferPropValue<R> | ModelInferPropValue<R>[number]valueone or many instance to detach
updateRelation
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
I extends ModelInstanceinstancean instance of model to update relation onModelRelationKey<M>relationa relation to updateModelInferPropValue<R> | ModelInferPropValue<R>[number]valueone or many instance to set as the relation's valueActionName.UPDATE_RELATION | ActionName.ATTACH_RELATION | ActionName.DETACH_RELATIONactionNamethe action name to run (defaults toActionName.UPDATE_RELATION)
instanceData
Serialize the given instance as the context's data.
Example
import { instanceData } from '@foscia/core';
action().use(instanceData(post));
Arguments
I extends ModelInstanceinstancean instance of model to serialize
relationData
Serialize the given instance's relation as the context's data.
Example
import { relationData } from '@foscia/core';
action().use(relationData(post, 'tags'));
Arguments
I extends ModelInstanceinstancean instance of model to serializeModelRelationKey<M>relationa relation to serialize
include
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
ArrayableVariadic<ModelRelationDotKey<M>>...relationsa relation or a set of relation to eager load
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>callbackcallback 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>callbackcallback 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>callbackcallback 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>callbackcallback to run on event
@foscia/http
makeGet
HTTP GET method shortcut for the makeRequest function.
Example
import { makeGet } from '@foscia/http';
action().use(
makeGet('https://example.com', {
/* config */
}),
);
Arguments
stringpathOrBaseURLa path or base URL for the requestHttpRequestConfig | undefinedconfiga request configuration object
makePost
HTTP POST method shortcut for the makeRequest function.
Example
import { makePost } from '@foscia/http';
action().use(
makePost(
'https://example.com',
{ data: 'foobar' },
{
/* config */
},
),
);
Arguments
stringpathOrBaseURLa path or base URL for the requestHttpRequestConfig['body'] | undefinedbodya request bodyHttpRequestConfig | undefinedconfiga request configuration object
makePut
HTTP PUT method shortcut for the makeRequest function.
Example
import { makePut } from '@foscia/http';
action().use(
makePut(
'https://example.com',
{ data: 'foobar' },
{
/* config */
},
),
);
Arguments
stringpathOrBaseURLa path or base URL for the requestHttpRequestConfig['body'] | undefinedbodya request bodyHttpRequestConfig | undefinedconfiga request configuration object
makePatch
HTTP PATCH method shortcut for the makeRequest function.
Example
import { makePatch } from '@foscia/http';
action().use(
makePatch(
'https://example.com',
{ data: 'foobar' },
{
/* config */
},
),
);
Arguments
stringpathOrBaseURLa path or base URL for the requestHttpRequestConfig['body'] | undefinedbodya request bodyHttpRequestConfig | undefinedconfiga request configuration object
makeDelete
HTTP DELETE method shortcut for the makeRequest function.
Example
import { makeDelete } from '@foscia/http';
action().use(
makeDelete(
'https://example.com',
{ data: 'foobar' },
{
/* config */
},
),
);
Arguments
stringpathOrBaseURLa path or base URL for the requestHttpRequestConfig['body'] | undefinedbodya request bodyHttpRequestConfig | undefinedconfiga request configuration object
makeRequest
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
stringpathOrBaseURLa path or base URL for the requestHttpRequestConfig | undefinedconfiga request configuration object
configureRequest
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
HttpRequestConfigconfiga request configuration object
param
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 | Dictionarykeya key for the param or a params objectunknown | undefinedvaluea value for the param
abortSignal
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>controllerOrSignalan abort controller or signal instance to configure (or undefined/null to cancel a previous configuration)
@foscia/jsonapi
fields
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
ArrayableVariadic<ModelKey<M>>...fieldseta field or a set of field to select for the current context's model
fieldsFor
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
M extends ModelClass<D>modelthe model to select the fieldsets forArrayableVariadic<ModelKey<M>>...fieldseta field or a set of field to select for the given model
filterBy
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 | Dictionarykeya key for the filter or a filter objectunknown | undefinedvaluea value for the filter
sortBy
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>keythe key(s) for the sortArrayable<'asc' | 'desc'> = 'asc'directionthe direction(s) for the sort
sortByAsc
Shortcut for the sortBy function with an asc direction.
Example
import { sortByAsc } from '@foscia/jsonapi';
action().use(sortByAsc('createdAt'));
Arguments
ArrayableVariadic<string>...keysthe key(s) for the sort
sortByDesc
Shortcut for the sortBy function with a desc direction.
Example
import { sortByDesc } from '@foscia/jsonapi';
action().use(sortByDesc('createdAt'));
Arguments
ArrayableVariadic<string>...keysthe key(s) for the sort
paginate
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
unknownpagea pagination value which match your implementation