Skip to content

findOrCreate

Category
Export size
min 2.35 kB · gzip 1.08 kB

A before:create (or around:create) hook that looks for an existing record before creating one.

It builds a query from the uniqueBy paths read out of context.data, runs find({ paginate: false }) on the target service, and if exactly one record matches, sets context.result to that record — short-circuiting the create. With zero matches (or array data) the create proceeds; with multiple matches the onMultiple option decides.

ts
  import {  } from 'feathers-utils/hooks';

Example

ts
import { findOrCreate } from 'feathers-utils/hooks'

app.service('tags').hooks({
  before: {
    create: [findOrCreate({ service: 'tags', uniqueBy: 'name' })]
  }
})

Type declaration

Show Type Declarations
ts
/**
 * The valid `uniqueBy` paths for a service's create data. Falls back to a plain
 * `string` when the create data type can't be inferred (e.g. an untyped app), so
 * the hook stays usable without a strongly-typed `feathers()` instance.
 */
type UniqueByPath<S> = NeverFallback<
  KeyOfOrDotNotation<InferCreateDataSingle<S>>,
  string
>
export interface FindOrCreateOptions<
  H extends HookContext = HookContext,
  Services extends H["app"]["services"] = H["app"]["services"],
  S extends keyof Services = keyof Services,
> {
  /** The service to search before creating. Must be a service registered on the app. */
  service: S
  /**
   * One or more property paths (dot-notation supported) read from `context.data` to build
   * the lookup query — the upsert "conflict target". A path whose value is `undefined` in
   * the data is skipped.
   */
  uniqueBy: MaybeArray<UniqueByPath<Services[S]>>
  /**
   * Optional function returning extra `find` params. `query` is merged with (and overridden
   * by) the `uniqueBy` values; `paginate` is always forced to `false`.
   */
  params?: (context: H) => InferFindParams<Services[S]>
  /**
   * What to do when more than one record matches the `uniqueBy` query.
   * - `'create'` (default): proceed to create a new record.
   * - `'throw'`: throw a `BadRequest`.
   * - `'first'`: short-circuit with the first match.
   *
   * @default 'create'
   */
  onMultiple?: "create" | "throw" | "first"
}
/**
 * A `before:create` (or `around:create`) hook that looks for an existing record before creating one.
 *
 * It builds a query from the `uniqueBy` paths read out of `context.data`, runs
 * `find({ paginate: false })` on the target service, and if **exactly one** record matches, sets
 * `context.result` to that record — short-circuiting the create. With zero matches (or array data)
 * the create proceeds; with multiple matches the `onMultiple` option decides.
 *
 * @example
 * ```ts
 *
 *
 * app.service('tags').hooks({
 *   before: {
 *     create: [findOrCreate({ service: 'tags', uniqueBy: 'name' })]
 *   }
 * })
 * ```
 *
 * @see https://utils.feathersjs.com/hooks/find-or-create.html
 */
export declare function findOrCreate<H extends HookContext = HookContext>(
  options: FindOrCreateOptions<H>,
): (context: H, next?: NextFunction) => Promise<void>
ArgumentTypeDescription
optionsFindOrCreateOptions<H>
typemethodsmulti
before, aroundcreateno

Released under the MIT License.