-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8bd6754
commit ee886bd
Showing
12 changed files
with
946 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
import { IterableElement, ValueOf } from 'type-fest' | ||
|
||
import { castArray } from './lib/castArray' | ||
|
||
/** | ||
* Parameters for the Prismic REST API V2. | ||
* | ||
* @see https://prismic.io/docs/technologies/introduction-to-the-content-query-api | ||
*/ | ||
export interface QueryParams { | ||
/** | ||
* The secure token for accessing the API (only needed if your repository is set to private). | ||
* | ||
* @see https://user-guides.prismic.io/en/articles/1036153-generating-an-access-token | ||
*/ | ||
accessToken?: string | ||
|
||
/** | ||
* The `pageSize` parameter defines the maximum number of documents that the API will return for your query. | ||
* | ||
* @see https://prismic.io/docs/technologies/search-parameters-reference-rest-api#pagesize | ||
*/ | ||
pageSize?: number | ||
|
||
/** | ||
* The `page` parameter defines the pagination for the result of your query. | ||
* | ||
* @see https://prismic.io/docs/technologies/search-parameters-reference-rest-api#page | ||
*/ | ||
page?: number | ||
|
||
/** | ||
* The `after` parameter can be used along with the orderings option. It will remove all the documents except for those after the specified document in the list. | ||
* | ||
* @see https://prismic.io/docs/technologies/search-parameters-reference-rest-api#after | ||
*/ | ||
after?: string | ||
|
||
/** | ||
* The `fetch` parameter is used to make queries faster by only retrieving the specified field(s). | ||
* | ||
* @see https://prismic.io/docs/technologies/search-parameters-reference-rest-api#fetch | ||
*/ | ||
fetch?: string | string[] | ||
|
||
/** | ||
* The `fetchLinks` parameter allows you to retrieve a specific content field from a linked document and add it to the document response object. | ||
* | ||
* @see https://prismic.io/docs/technologies/search-parameters-reference-rest-api#fetchlinks | ||
*/ | ||
fetchLinks?: string | string[] | ||
|
||
/** | ||
* The `graphQuery` parameter allows you to specify which fields to retrieve and what content to retrieve from Linked Documents / Content Relationships. | ||
* | ||
* @see https://prismic.io/docs/technologies/graphquery-rest-api | ||
*/ | ||
graphQuery?: string | ||
|
||
/** | ||
* The `lang` option defines the language code for the results of your query. | ||
* | ||
* @see https://prismic.io/docs/technologies/search-parameters-reference-rest-api#lang | ||
*/ | ||
lang?: string | ||
|
||
/** | ||
* The `orderings` parameter orders the results by the specified field(s). You can specify as many fields as you want. | ||
* | ||
* @see https://prismic.io/docs/technologies/search-parameters-reference-rest-api#orderings | ||
*/ | ||
orderings?: Ordering | string | (Ordering | string)[] | ||
} | ||
|
||
/** | ||
* Arguments for `buildQueryURL` to construct a Query URL. | ||
*/ | ||
type BuildQueryURLParams = { | ||
/** | ||
* Ref used to query documents. | ||
* | ||
* @see https://prismic.io/docs/technologies/introduction-to-the-content-query-api#prismic-api-ref | ||
*/ | ||
ref: string | ||
|
||
/** | ||
* One or more predicates to filter documents for the query. | ||
* | ||
* @see https://prismic.io/docs/technologies/query-predicates-reference-rest-api | ||
*/ | ||
predicates?: string | string[] | ||
} | ||
|
||
/** | ||
* An `orderings` parameter that orders the results by the specified field. | ||
* | ||
* @see https://prismic.io/docs/technologies/search-parameters-reference-rest-api#orderings | ||
*/ | ||
type Ordering = { | ||
field: string | ||
direction?: 'asc' | 'desc' | ||
} | ||
|
||
/** | ||
* Parameters in this map have been renamed from the official Prismic REST API | ||
* V2 specification for better developer ergonomics. | ||
* | ||
* These parameters are renamed to their mapped value. | ||
*/ | ||
const RENAMED_PARAMS = { | ||
accessToken: 'access_token', | ||
} as const | ||
|
||
/** | ||
* Parameter keys in this list are not actual Prismic REST API V2 parameters. | ||
* They are used for other API inputs and functionality. | ||
* | ||
* These parameters are *not* included in URL builder products. | ||
* | ||
* This list should match parameters included in `BuildQueryURLParams`. | ||
*/ | ||
const NON_PARAM_ARGS = ['ref', 'predicates'] as const | ||
|
||
/** | ||
* A valid parameter name for the Prismic REST API V2. | ||
*/ | ||
type ValidParamName = | ||
| Exclude< | ||
keyof QueryParams, | ||
keyof typeof RENAMED_PARAMS | IterableElement<typeof NON_PARAM_ARGS> | ||
> | ||
| ValueOf<typeof RENAMED_PARAMS> | ||
|
||
/** | ||
* Converts an Ordering to a string that is compatible with Prismic's REST API. | ||
* If the value provided is already a string, no conversion is performed. | ||
* | ||
* @param ordering Ordering to convert. | ||
* | ||
* @returns String representation of the Ordering. | ||
*/ | ||
const castOrderingToString = (ordering: Ordering | string): string => | ||
typeof ordering === 'string' | ||
? ordering | ||
: [ordering.field, ordering.direction].join(' ') | ||
|
||
export type BuildQueryURLArgs = QueryParams & BuildQueryURLParams | ||
|
||
/** | ||
* Build a Prismic REST API V2 URL to request documents from a repository. The | ||
* paginated response for this URL includes documents matching the parameters. | ||
* | ||
* A ref is required to make a request. Request the `endpoint` URL to retrieve a | ||
* list of available refs. | ||
* | ||
* Type the JSON response with `Query`. | ||
* | ||
* @see https://prismic.io/docs/technologies/introduction-to-the-content-query-api#prismic-api-ref | ||
* @see https://prismic.io/docs/technologies/query-predicates-reference-rest-api | ||
* | ||
* @param endpoint Endpoint to the repository's REST API. | ||
* @param args Arguments to filter and scope the query. | ||
* | ||
* @returns URL that can be used to request documents from the repository. | ||
*/ | ||
export const buildQueryURL = ( | ||
endpoint: string, | ||
args: BuildQueryURLArgs, | ||
): string => { | ||
const { ref, predicates, ...params } = args | ||
|
||
const url = new URL(`documents/search`, `${endpoint}/`) | ||
url.searchParams.set('ref', ref) | ||
|
||
if (predicates) { | ||
for (const predicate of castArray(predicates)) { | ||
url.searchParams.append('q', `[${predicate}]`) | ||
} | ||
} | ||
|
||
// Iterate over each parameter and add it to the URL. In some cases, the | ||
// parameter value needs to be transformed to fit the REST API. | ||
for (const k in params) { | ||
const name = (RENAMED_PARAMS[k as keyof typeof RENAMED_PARAMS] ?? | ||
k) as ValidParamName | ||
|
||
let value: string | string[] | null | undefined | ||
|
||
switch (name) { | ||
case 'orderings': { | ||
const scopedValue = params[name] | ||
|
||
if (scopedValue) { | ||
const v = castArray(scopedValue) | ||
.map((ordering) => castOrderingToString(ordering)) | ||
.join(',') | ||
|
||
value = `[${v}]` | ||
} | ||
|
||
break | ||
} | ||
} | ||
|
||
if (value != null) { | ||
url.searchParams.set(name, castArray(value).join(',')) | ||
} | ||
} | ||
|
||
return url.toString() | ||
} |
Oops, something went wrong.