teunmooij

query

by teunmooij
payload-tools
APIs & SDKs
v1
^1.6.22
MIT

Overview

Summary generated from the README

Provides strongly typed Filter and Query types built on Payload's Where system, plus a toFilter helper to turn predefined queries into filters using runtime data such as the current user. A selectPlugin adds a select query parameter to REST endpoints, and a select function trims results from the internal API. Written for Payload 1.x.

Features

  • Typed Filter type that checks paths, operators and operands against your collection type
  • Query type with function operands resolved later from request or user data
  • toFilter helper to build reusable filters from predefined queries
  • selectPlugin enables a select query parameter on chosen collections and globals
  • select function picks fields from documents returned by the internal API

Use cases

  • Restrict queries to documents authored by the current user with a reusable typed query
  • Return only needed fields from REST responses to reduce payload size
  • Catch invalid query fields or operators at compile time in TypeScript projects

From the author

Payload typesafe query utility

Installation

npm i payload-query

142

Stars

15

Forks

13

Open Issues

2 years ago

Last Updated

0

Weekly Downloads

v1.0.2

npm Version

18.7 KB

Unpacked Size

1

Dependencies

Repository stars

Trends appear after 7 days of data. Daily snapshots have not started yet.

Shared by 5 plugins in teunmooij/payload-tools.

npm weekly downloads

Trends appear after 7 days of data. Daily snapshots have not started yet.

Each point is npm's rolling 7-day download count.

Health Score

38/100Fair

Composite score based on GitHub activity, stars, npm downloads, publish recency, dependency count, and package size.

Badge for your README

Payload Directory health badge
Markdown
[![Payload Directory](https://payloaddirectory.dev/badge/611765581-query.svg)](https://payloaddirectory.dev/plugins/611765581-query)
HTML
<a href="https://payloaddirectory.dev/plugins/611765581-query"><img src="https://payloaddirectory.dev/badge/611765581-query.svg" alt="Payload Directory"></a>
Updated Jul 17, 2024Created Mar 9, 2023Published Apr 18, 2023

README

author snyk downloads npm version license

payload-query

Easy to use query utility for your Payload cms.

Main features:

  • create type safe queries
  • predefine queries to be constructed with data passed in later (e.g. request data)
  • select output fields on REST and Internal API.

Installation

With yarn:

yarn add payload-query

With npm:

npm install payload-query

Usage - Filter

payload-query is built on top of Payload's query system.

All examples below assume you have a collection that generates a type as follows:

type User = {
  id: string;
  name: string;
};

type Post = {
  color: 'mint' | 'dark-grey' | 'white';
  author: string | User;
  featured: boolean;
};

Filter type

The Filter type is a strongly typed version of Payload's Where type and can be directly used everywhere where the Where type is used. By providing your collection type as type it will tell you exactly which paths, operators and operands you can use.

import { Filter } from 'payload-query';

const query: Filter<Post> = {
  color: {
    equals: 'mint',
  },
};

As you can see the query looks exactly as the ones you're already using, but there's one big difference: this one is fully type-checked. If you change the name of the color property, try to compare it to a value that's not part of the union or try an operator that's not supported for string fields, you'll get a typescript error.

Query type

Sometimes your query is slightly different every time you use it. For instance if you want to only find some documents where the current user is the author. In that cause easch user has a different query. For such situations you can use the Query type:

import { Query } from 'payload-query';

const query: Query<Post, User> = {
  author: {
    equals: user => user.id,
  },
};

With the Query type instead of providing a value as operand, you can instead provide a function that takes some data, typed by the 2nd type parameter, and returns a value. You can also still use values if you choose, as shown in the example below:

import { Query } from 'payload-query';

const query: Query<Post, User> = {
  and: [
    {
      color: {
        equals: 'mint',
      },
    },
    {
      author: {
        equals: user => user.id,
      },
    },
  ],
};

Query > Filter

When you have a Query, you of course need to turn it into a Filter before you can use it in Payload. For this payload-query provides a toFilter function.

import { toFilter } from 'payload-query';
import query = '...';

const data = { id: '123', name: 'Mike' };

const filter = toFilter(query, data);

or, if you want to reuse your query:

import { toFilter } from 'payload-query';
import query = '...';

const authorOnly = toFilter(query);

const filter = authorOnly({ id: '123', name: 'Mike' });

Circular objects

If your collection contains circular references, it is impossible to build the full paths to all possible fields. Therefore such collections cannot be used as type parameter to create a query type. If you run into this issue, there's 2 ways to solve it:

  • use Pick<MyCollection, 'field1'|'field2'> to only pick the fields you want to use in your query
  • use any as collection type (but you'll loose type safety).

Usage - Select

payload-query lets you define a selection of fields that you want in your query results, like a SELECT clause in a SQL statement, or a projection in a MongoDB query.

Select type

The select type defines which fields to select and has the following structure:

type Select<T> = Partial<Record<keyof T, boolean>>;

// To select only color of a post:
const select: Select<Post> = {
  color: true,
  id: false,
};

// Exclude the id field, include everything else
const select2: Select<Post> = { id: false };

By default the id field is selected and all others are not. To select a field, add it to the selection, with a value of true, to omit the id, include it with a value of false. Nested fields are not yet supported and are either all selected or not at all. If the select only contains fields with a value of false, all fields that are not part of the select will be included.

Select - REST api

When using the rest api, a select query parameter can be used to filter to output. To enable this, the selectPlugin must be first added to the payload config:

import { buildConfig } from 'payload/config';
import { selectPlugin } from 'payload-query';

export default buildConfig({
  plugins: [selectPlugin()],
  // The rest of your config goes here
});

The select plugin takes an optional Options parameter, which lets you define on which collections / globals you want to enable select. If omitted, it is enabled on all.

After the plugin is enabled you can use a select query parameter in the same way you would with the where parameter:

http://localhost:3000/api/posts?select[color]=true

Select - Internal api

When using the internal api, select can be used as follows:

import { select } from 'payload-query';

const doc = payload.findByID({ collection: 'posts', id: 123 });
const filtered = select({ color: true }, doc);

Or when using the same filter multiple times:

import { select } from 'payload-query';

const { docs } = payload.find({ collection: 'posts' });
const selectColor = select({ color: true });

const filtered = docs.map(doc => selectColor(doc));

Version history

See changelog

Similar plugins