Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
8777404
feat: move API docs outside of Next site
backlineint Jan 21, 2025
982e9c6
feat: port all examples from getResource docs to Typedoc version
backlineint Jan 21, 2025
02c22f9
feat: example of ignoring something from tsdoc docs
backlineint Jan 21, 2025
16c6e0b
feat: example of marking something as deprecated
backlineint Jan 21, 2025
61488cd
docs: add additional detail to getResource entry
backlineint Jan 22, 2025
27cd1b7
docs: initial revisions to getResourceFromContext typedoc
backlineint Jan 23, 2025
1509e09
docs: add remaining examples to getResourceFromContext typedoc
backlineint Jan 23, 2025
32d40b1
docs: add examples for getResourceByPath
backlineint Jan 24, 2025
d666e5f
docs: add reference examples to getResourceCollection
backlineint Jan 27, 2025
b06eb64
docs: add reference example for getResourceCollectionFromContext
backlineint Jan 27, 2025
af6086a
docs: add reference examples to next-drupal createResource
backlineint Jan 27, 2025
9000395
docs: add reference examples to createFileResource
backlineint Jan 29, 2025
a01008b
docs: add reference examples to updateResource
backlineint Jan 29, 2025
f763ddc
docs: add reference examples to deleteResource
backlineint Jan 29, 2025
2e8d778
docs: add reference examples to getStaticPathsFromContext
backlineint Jan 29, 2025
4c5f95a
docs: add reference examples to translatePath
backlineint Jan 29, 2025
cbe0eab
docs: add reference examples to translatePathFromContext
backlineint Jan 29, 2025
6162143
docs: add reference examples to getPathFromContext
backlineint Jan 29, 2025
92d936e
docs: add reference examples for getEntryForResourceType
backlineint Jan 29, 2025
e16c976
docs: add reference examples for preview method
backlineint Jan 29, 2025
26582a5
docs: add reference examples to getAccessToken
backlineint Jan 29, 2025
a7c852d
docs: add reference examples to getMenu
backlineint Jan 29, 2025
7a61575
docs: add reference examples to getView
backlineint Jan 29, 2025
2015920
docs: add reference examples to getSearchIndex
backlineint Jan 29, 2025
63d1e3b
docs: add reference examples to buildUrl
backlineint Jan 29, 2025
ace7dac
docs: add reference examples to fetch
backlineint Jan 29, 2025
4d27b15
docs: add reference examples for deserialize
backlineint Jan 29, 2025
8a8d762
docs: update 2.0 announcement, including contributors
backlineint Jan 30, 2025
b0633e4
docs: correctly filter list of contributors in 2.x announcement
backlineint Jan 30, 2025
0e3158f
docs: update to umami demo guide
backlineint Jan 31, 2025
e267f77
docs: minor updates to GraphQL auth entry
backlineint Feb 3, 2025
2ca5e46
docs: remove todo
backlineint Feb 4, 2025
3da32e4
docs: updates to draft mode quick start
backlineint Feb 5, 2025
35c5f6e
docs: tweaks to oauth client docs to allow for revisions
backlineint Feb 6, 2025
6783a36
docs: updates to on-demand validation quick start
backlineint Feb 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ yarn-error.log*
/drupal/web/phpunit.xml
/drupal/web/sites/default/settings.local.php
/drupal-*
/local-next-drupal
1 change: 1 addition & 0 deletions packages/next-drupal/src/deprecated/get-access-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { AccessToken } from "../types"

const CACHE_KEY = "NEXT_DRUPAL_ACCESS_TOKEN"

/** @deprecated */
export async function getAccessToken(): Promise<AccessToken> {
if (!process.env.DRUPAL_CLIENT_ID || !process.env.DRUPAL_CLIENT_SECRET) {
return null
Expand Down
1 change: 1 addition & 0 deletions packages/next-drupal/src/jsonapi-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface JsonApiLinks {
[key: string]: string | Record<string, string>
}

/** @hidden */
export class JsonApiErrors extends Error {
errors: JsonApiError[] | string
statusCode: number
Expand Down
57 changes: 52 additions & 5 deletions packages/next-drupal/src/next-drupal-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,21 @@ export class NextDrupalBase {
/**
* Fetches a resource from the given input URL or path.
*
* @param {RequestInfo} input The input URL or path.
* @param {FetchOptions} init The fetch options.
* @param {RequestInfo} input The url to fetch from.
* @param {FetchOptions} init The fetch options with `withAuth`.
* If `withAuth` is set, `fetch` will fetch an `Authorization` header before making the request.
* @returns {Promise<Response>} The fetch response.
* @remarks
* To provide your own custom fetcher, see the fetcher docs.
* @example
* ```ts
* const url = drupal.buildUrl("/jsonapi/node/article", {
* sort: "-created",
* "fields[node--article]": "title,path",
* })
*
* const response = await drupal.fetch(url.toString())
* ```
*/
async fetch(
input: RequestInfo,
Expand Down Expand Up @@ -269,9 +281,35 @@ export class NextDrupalBase {
/**
* Builds a URL with the given path and search parameters.
*
* @param {string} path The URL path.
* @param {EndpointSearchParams} searchParams The search parameters.
* @param {string} path The path for the url. Example: "/example"
* @param {string | Record<string, string> | URLSearchParams | JsonApiParams} searchParams Optional query parameters.
* @returns {URL} The constructed URL.
* @example
* ```ts
* const drupal = new DrupalClient("https://example.com")
*
* // https://drupal.org
* drupal.buildUrl("https://drupal.org").toString()
*
* // https://example.com/foo
* drupal.buildUrl("/foo").toString()
*
* // https://example.com/foo?bar=baz
* client.buildUrl("/foo", { bar: "baz" }).toString()
* ```
*
* Build a URL from `DrupalJsonApiParams`
* ```ts
* const params = {
* getQueryObject: () => ({
* sort: "-created",
* "fields[node--article]": "title,path",
* }),
* }
*
* // https://example.com/jsonapi/node/article?sort=-created&fields%5Bnode--article%5D=title%2Cpath
* drupal.buildUrl("/jsonapi/node/article", params).toString()
* ```
*/
buildUrl(path: string, searchParams?: EndpointSearchParams): URL {
const url = new URL(path, this.baseUrl)
Expand Down Expand Up @@ -407,10 +445,19 @@ export class NextDrupalBase {
}

/**
* Gets an access token using the provided client ID and secret.
* Retrieve an access token.
*
* @param {NextDrupalAuthClientIdSecret} clientIdSecret The client ID and secret.
* @returns {Promise<AccessToken>} The access token.
* @remarks
* If options is not provided, `DrupalClient` will use the `clientId` and `clientSecret` configured in `auth`.
* @example
* ```ts
* const accessToken = await drupal.getAccessToken({
* clientId: "7034f4db-7151-466f-a711-8384bddb9e60",
* clientSecret: "d92Fm^ds",
* })
* ```
*/
async getAccessToken(
clientIdSecret?: NextDrupalAuthClientIdSecret
Expand Down
218 changes: 201 additions & 17 deletions packages/next-drupal/src/next-drupal-pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,29 @@ export class NextDrupalPages extends NextDrupal {
}

/**
* Gets the entry point for a given resource type.
* Get the JSON:API entry for a resource type.
*
* @param {string} resourceType The resource type.
* @param {Locale} locale The locale.
* @param {string} resourceType The resource type. Example: `node--article`.
* @param {Locale} locale Optional. The locale to fetch the index. Example: `es` or `fr`.
* @returns {Promise<string>} The entry point URL.
* @remarks
* By default, when retrieving resources in `getResource` or `getResourceCollection`,
* the `DrupalClient` make a request to Drupal to fetch the JSON:API resource entry.
*
* Example: if you provide `node--article`, `DrupalClient` will make a request to
* `http://example.com/jsonapi/node/article`.
*
* If you would like to infer the entry from the resource type, use the useDefaultResourceTypeEntry option:
* ```ts
* const drupal = new DrupalClient(process.env.NEXT_PUBLIC_DRUPAL_BASE_URL, {
* useDefaultResourceTypeEntry: true,
* })
* ```
* @example
* ```ts
* // https://example.com/jsonapi/node/article
* const url = await drupal.getEntryForResourceType(`node--article`)
* ```
*/
async getEntryForResourceType(
resourceType: string,
Expand All @@ -88,10 +106,89 @@ export class NextDrupalPages extends NextDrupal {
/**
* Gets a resource from the context.
*
* @param {string | DrupalTranslatedPath} input The input path or translated path.
* @param {GetStaticPropsContext} context The static props context.
* @param {string | DrupalTranslatedPath} input Either a resource type (e.g. "node--article") or a translated path from translatePath().
* @param {GetStaticPropsContext} context The Next.js context from getStaticProps.
* @param {Object} options Options for the request.
* @param {PathPrefix} [options.pathPrefix] The path prefix to use for the request (defaults to "/").
* @param {boolean} [options.isVersionable] Whether the resource is versionable (defaults to false for all entity types except nodes).
* @returns {Promise<T>} The fetched resource.
* @remarks
* The localized resource will be fetched based on the `locale` and `defaultLocale` values from `context`.
*
* If you pass in a `DrupalTranslatedPath` for input, `getResourceFromContext` will take the `type` and `id` from the path and make a `getResource` call to Drupal:
* ```ts
* export async function getStaticProps(context) {
* const path = await drupal.translatePathFromContext(context)
*
* const node = await drupal.getResourceFromContext(path, context)
*
* return {
* props: {
* node,
* },
* }
* }
* ```
*
* If you pass in a `string` input, such as `node--article`, `getResourceFromContext` will make a subrequest call to Drupal to translate the path and then fetch the resource.
* You will need both the [Subrequests](https://drupal.org/project/subrequests) and [Decoupled Router](https://drupal.org/project/decoupled_router) modules:
* ```ts
* export async function getStaticProps(context) {
* const node = await drupal.getResourceFromContext("node--article", context)
*
* return {
* props: {
* node,
* },
* }
* }
* ```
* @examples
* Fetch a resource from context.
* ```ts title=pages/[[...slug]].tsx
* export async function getStaticProps(context) {
* const node = await drupal.getResourceFromContext("node--page", context)
*
* return {
* props: {
* node,
* },
* }
* }
* ```
* Fetch a resource from context in a sub directory.
* ```ts title=pages/articles/[[...slug]].tsx
* export async function getStaticProps(context) {
* const node = await drupal.getResourceFromContext("node--page", context, {
* pathPrefix: "/articles",
* })
*
* return {
* props: {
* node,
* },
* }
* }
* ```
* Using DrupalNode type:
* ```ts
* import { DrupalNode } from "next-drupal"
*
* const node = await drupal.getResourceFromContext<DrupalNode>(
* "node--page",
* context
* )
* ```
* Using DrupalTaxonomyTerm type:
* ```ts
* import { DrupalTaxonomyTerm } from "next-drupal"
*
* const term = await drupal.getResourceFromContext<DrupalTaxonomyTerm>(
* "taxonomy_term--tags",
* context
* )
* ```
* @see {@link https://next-drupal.org/docs/typescript} for more built-in types.
*/
async getResourceFromContext<T extends JsonApiResource>(
input: string | DrupalTranslatedPath,
Expand Down Expand Up @@ -179,10 +276,37 @@ export class NextDrupalPages extends NextDrupal {
/**
* Gets a collection of resources from the context.
*
* @param {string} type The type of the resources.
* @param {GetStaticPropsContext} context The static props context.
* @param {string} type The type of the resources. Example: `node--article` or `user--user`.
* @param {GetStaticPropsContext} context The static props context from getStaticProps or getServerSideProps.
* @param {Object} options Options for the request.
* - deserialize: Set to false to return the raw JSON:API response
* @returns {Promise<T>} The fetched collection of resources.
* @remarks
* The localized resources will be fetched based on the `locale` and `defaultLocale` values from `context`.
* @example
* Get all articles from context
* ```
* export async function getStaticProps(context) {
* const articles = await drupal.getResourceCollectionFromContext(
* "node--article",
* context
* )
*
* return {
* props: {
* articles,
* },
* }
* }
* ```
* Using TypeScript with DrupalNode for a node entity type
* ```
* import { DrupalNode } from "next-drupal"
* const nodes = await drupal.getResourceCollectionFromContext<DrupalNode[]>(
* "node--article",
* context
* )
* ```
*/
async getResourceCollectionFromContext<T = JsonApiResource[]>(
type: string,
Expand Down Expand Up @@ -227,9 +351,17 @@ export class NextDrupalPages extends NextDrupal {
/**
* Translates a path from the context.
*
* @param {GetStaticPropsContext} context The static props context.
* @param {GetStaticPropsContext} context The context from `getStaticProps` or `getServerSideProps`.
* @param {Object} options Options for the request.
* @returns {Promise<DrupalTranslatedPath | null>} The translated path.
* @requires Decoupled Router module
* @example
* Get info about a path from `getStaticProps` context
* ```ts
* export async function getStaticProps(context) {
* const path = await drupal.translatePathFromContext(context)
* }
* ```
*/
async translatePathFromContext(
context: GetStaticPropsContext,
Expand All @@ -251,11 +383,18 @@ export class NextDrupalPages extends NextDrupal {
}

/**
* Gets the path from the context.
* Return the path (slug) from getStaticProps or getServerSideProps context.
*
* @param {GetStaticPropsContext} context The static props context.
* @param {GetStaticPropsContext} context The context from `getStaticProps` or `getServerSideProps`.
* @param {Object} options Options for the request.
* @returns {string} The constructed path.
* @example
* Get the path (slug) from `getStaticProps` context
* ```ts
* export async function getStaticProps(context) {
* const slug = await drupal.getPathFromContext(context)
* }
* ```
*/
getPathFromContext(
context: GetStaticPropsContext,
Expand All @@ -275,10 +414,33 @@ export class NextDrupalPages extends NextDrupal {
/**
* Gets static paths from the context.
*
* @param {string | string[]} types The types of the resources.
* @param {GetStaticPathsContext} context The static paths context.
* @param {Object} options Options for the request.
* @returns {Promise<GetStaticPathsResult<{ slug: string[] }>["paths"]>} The fetched static paths.
* @param {string | string[]} types The resource types. Example: `node--article` or `["taxonomy_term--tags", "user--user"]`.
* @param {GetStaticPathsContext} context The context from `getStaticPaths`.
* @param {object} options Options for the request.
* @returns {Promise<GetStaticPathsResult<{ slug: string[] }>["paths"]>} The static paths.
* @example
* Return static paths for `node--page` resources
* ```ts
* export async function getStaticPaths(context) {
* return {
* paths: await drupal.getStaticPathsFromContext("node--page", context),
* fallback: "blocking",
* }
* }
* ```
*
* Return static paths for `node--page` and `node--article` resources
* ```ts
* export async function getStaticPaths(context) {
* return {
* paths: await drupal.getStaticPathsFromContext(
* ["node--page", "node--article"],
* context
* ),
* fallback: "blocking",
* }
* }
* ```
*/
async getStaticPathsFromContext(
types: string | string[],
Expand Down Expand Up @@ -414,11 +576,33 @@ export class NextDrupalPages extends NextDrupal {
}

/**
* Handles preview mode.
* Handle preview mode for resources.
*
* @param {NextApiRequest} request The API request.
* @param {NextApiResponse} response The API response.
* @param {NextApiRequest} request The `request` from an API route.
* @param {NextApiResponse} response The `response` from an API route.
* @param {Object} options Options for the request.
* @returns {Promise<void>}
* @remarks
* The `preview` method should be called in an API route.
* Remember to set a `previewSecret` on the client.
* ```ts
* // lib/drupal.ts
* export const drupal = new DrupalClient(
* process.env.NEXT_PUBLIC_DRUPAL_BASE_URL,
* {
* previewSecret: process.env.DRUPAL_PREVIEW_SECRET,
* }
* )
* ```
* @example
* ```ts
* // pages/api/preview.ts
* import { drupal } from "lib/drupal"
*
* export default async function handler(req, res) {
* return await drupal.preview(req, res)
* }
* ```
*/
async preview(
request: NextApiRequest,
Expand Down
Loading
Loading