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
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
Model
query
the model to queryModelIdType | undefined
id
the record's ID to query
Instance signature
ModelInstance
instance
the instance to queryModelRelationKey | undefined
relation
the 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 ModelInstance
instance
an instance to create
Through instance signature
I extends ModelInstance
throughInstance
an instance to create throughK extends ModelRelationKey
throughRelation
a relation ofthroughInstance
to create throughRI extends ModelInstance
instance
an instance to create
update
Prepare context for an instance update.
Example
import { update } from '@foscia/core';
action().use(update(post));
Arguments
I extends ModelInstance
instance
an 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 ModelInstance
instance
an 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 ModelInstance
instance
an 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 ModelInstance
instance
an instance of model to update relation onModelRelationKey<M>
relation
a relation to updateModelInferPropValue<R>
value
an 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 ModelInstance
instance
an instance of model to update relation onModelRelationKey<M>
relation
a 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 ModelInstance
instance
an instance of model to update relation onModelRelationKey<M>
relation
a relation to updateModelInferPropValue<R> | ModelInferPropValue<R>[number]
value
one 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 ModelInstance
instance
an instance of model to update relation onModelRelationKey<M>
relation
a relation to updateModelInferPropValue<R> | ModelInferPropValue<R>[number]
value
one 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 ModelInstance
instance
an instance of model to update relation onModelRelationKey<M>
relation
a relation to updateModelInferPropValue<R> | ModelInferPropValue<R>[number]
value
one or many instance to set as the relation's valueActionName.UPDATE_RELATION | ActionName.ATTACH_RELATION | ActionName.DETACH_RELATION
actionName
the 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 ModelInstance
instance
an 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 ModelInstance
instance
an instance of model to serializeModelRelationKey<M>
relation
a 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>>
...relations
a 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>
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
HTTP GET method shortcut for the makeRequest
function.
Example
import { makeGet } from '@foscia/http';
action().use(
makeGet('https://example.com', {
/* config */
}),
);
Arguments
string
pathOrBaseURL
a path or base URL for the requestHttpRequestConfig | undefined
config
a 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
string
pathOrBaseURL
a path or base URL for the requestHttpRequestConfig['body'] | undefined
body
a request bodyHttpRequestConfig | undefined
config
a 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
string
pathOrBaseURL
a path or base URL for the requestHttpRequestConfig['body'] | undefined
body
a request bodyHttpRequestConfig | undefined
config
a 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
string
pathOrBaseURL
a path or base URL for the requestHttpRequestConfig['body'] | undefined
body
a request bodyHttpRequestConfig | undefined
config
a 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
string
pathOrBaseURL
a path or base URL for the requestHttpRequestConfig['body'] | undefined
body
a request bodyHttpRequestConfig | undefined
config
a 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
string
pathOrBaseURL
a path or base URL for the requestHttpRequestConfig | undefined
config
a 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
HttpRequestConfig
config
a 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 | Dictionary
key
a key for the param or a params objectunknown | undefined
value
a 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>
controllerOrSignal
an 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>>
...fieldset
a 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>
model
the model to select the fieldsets forArrayableVariadic<ModelKey<M>>
...fieldset
a 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 | Dictionary
key
a key for the filter or a filter objectunknown | undefined
value
a 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>
key
the key(s) for the sortArrayable<'asc' | 'desc'> = 'asc'
direction
the 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>
...keys
the 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>
...keys
the 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
unknown
page
a pagination value which match your implementation