@@ -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
2528const 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