Skip to content

Commit d097337

Browse files
committed
feat(next-drupal): add new method to support App Router's generateStaticParams()
The App Router's new generateStaticParams() replaces Pages Router's getStaticProps(). The new getResourceCollectionPathSegments() method supports generateStaticParams() by returning a list of path segments. This new method replaces the old getStaticPathsFromContext() method. Fixes #665
1 parent 9556704 commit d097337

File tree

5 files changed

+828
-15
lines changed

5 files changed

+828
-15
lines changed

packages/next-drupal/src/next-drupal.ts

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ import type {
1212
JsonApiCreateFileResourceBody,
1313
JsonApiCreateResourceBody,
1414
JsonApiOptions,
15+
JsonApiParams,
1516
JsonApiResource,
17+
JsonApiResourceWithPath,
1618
JsonApiResponse,
1719
JsonApiUpdateResourceBody,
1820
JsonApiWithAuthOption,
1921
JsonApiWithCacheOptions,
2022
JsonDeserializer,
2123
Locale,
2224
NextDrupalOptions,
25+
PathPrefix,
2326
} from "./types"
2427

2528
const DEFAULT_API_PREFIX = "/jsonapi"
@@ -426,6 +429,112 @@ export class NextDrupal extends NextDrupalBase {
426429
return options.deserialize ? this.deserialize(json) : json
427430
}
428431

432+
async getResourceCollectionPathSegments(
433+
types: string | string[],
434+
options?: {
435+
pathPrefix?: PathPrefix
436+
params?: JsonApiParams
437+
} & JsonApiWithAuthOption &
438+
(
439+
| {
440+
locales: Locale[]
441+
defaultLocale: Locale
442+
}
443+
| {
444+
locales?: undefined
445+
defaultLocale?: never
446+
}
447+
)
448+
): Promise<
449+
{
450+
path: string
451+
type: string
452+
locale: Locale
453+
segments: string[]
454+
}[]
455+
> {
456+
options = {
457+
withAuth: this.withAuth,
458+
pathPrefix: "",
459+
params: {},
460+
...options,
461+
}
462+
463+
if (typeof types === "string") {
464+
types = [types]
465+
}
466+
467+
const paths = await Promise.all(
468+
types.map(async (type) => {
469+
// Use sparse fieldset to expand max size.
470+
// Note we don't need status filter here since this runs non-authenticated (by default).
471+
const params = {
472+
[`fields[${type}]`]: "path",
473+
...options?.params,
474+
}
475+
476+
const locales = options?.locales?.length ? options.locales : [undefined]
477+
478+
return Promise.all(
479+
locales.map(async (locale) => {
480+
let opts: Parameters<NextDrupal["getResourceCollection"]>[1] = {
481+
params,
482+
withAuth: options.withAuth,
483+
}
484+
if (locale) {
485+
opts = {
486+
...opts,
487+
deserialize: true,
488+
locale,
489+
defaultLocale: options.defaultLocale,
490+
}
491+
}
492+
const resources = await this.getResourceCollection<
493+
JsonApiResourceWithPath[]
494+
>(type, opts)
495+
496+
return (
497+
resources
498+
.map((resource) => {
499+
return resource?.path?.alias === this.frontPage
500+
? /* c8 ignore next */ "/"
501+
: resource?.path?.alias
502+
})
503+
// Remove results with no path aliases.
504+
.filter(Boolean)
505+
.map((path) => {
506+
let segmentPath = path
507+
508+
// Trim the pathPrefix off the front of the path.
509+
if (
510+
options.pathPrefix &&
511+
(segmentPath.startsWith(
512+
`${options.pathPrefix}/`
513+
) /* c8 ignore next */ ||
514+
segmentPath === options.pathPrefix)
515+
) {
516+
segmentPath = segmentPath.slice(options.pathPrefix.length)
517+
}
518+
519+
// Convert the trimmed path into an array of path segments.
520+
const segments = segmentPath.split("/").filter(Boolean)
521+
522+
return {
523+
path,
524+
type,
525+
locale,
526+
segments,
527+
}
528+
})
529+
)
530+
})
531+
)
532+
})
533+
)
534+
535+
return paths.flat(2)
536+
}
537+
429538
async translatePath(
430539
path: string,
431540
options?: JsonApiWithAuthOption

0 commit comments

Comments
 (0)