1- import type { CollectionInfo , CollectionSource , Draft07 , CollectionItemBase , PageCollectionItemBase , ResolvedCollectionSource , Draft07DefinitionProperty } from '@nuxt/content'
1+ import type { CollectionInfo , Draft07 , CollectionItemBase , PageCollectionItemBase , ResolvedCollectionSource , Draft07DefinitionProperty } from '@nuxt/content'
22import { hash } from 'ohash'
33import { pathMetaTransform } from './path-meta'
44import { minimatch } from 'minimatch'
55import { join , dirname , parse } from 'pathe'
66import type { DatabaseItem } from 'nuxt-studio/app'
7- import { withoutLeadingSlash } from 'ufo'
7+ import { parseSourceBase } from 'nuxt-studio/app/utils'
8+ import { withLeadingSlash , withoutLeadingSlash } from 'ufo'
89
910export const getCollectionByFilePath = ( path : string , collections : Record < string , CollectionInfo > ) : CollectionInfo | undefined => {
1011 let matchedSource : ResolvedCollectionSource | undefined
@@ -34,15 +35,6 @@ export function generateStemFromFsPath(path: string) {
3435 return withoutLeadingSlash ( join ( dirname ( path ) , parse ( path ) . name ) )
3536}
3637
37- // TODO handle several sources case
38- export function generateIdFromFsPath ( path : string , collectionInfo : CollectionInfo ) {
39- const { fixed } = parseSourceBase ( collectionInfo . source [ 0 ] ! )
40-
41- const pathWithoutFixed = path . substring ( fixed . length )
42-
43- return join ( collectionInfo . name , collectionInfo . source [ 0 ] ?. prefix || '' , pathWithoutFixed )
44- }
45-
4638export function getOrderedSchemaKeys ( schema : Draft07 ) {
4739 const shape = Object . values ( schema . definitions ) [ 0 ] ?. properties || { }
4840 const keys = new Set ( [
@@ -67,7 +59,24 @@ export function getCollectionSource(id: string, collection: CollectionInfo) {
6759 const path = rest . join ( '/' )
6860
6961 const matchedSource = collection . source . find ( ( source ) => {
70- const include = minimatch ( path , source . include , { dot : true } )
62+ // Id is built like this: {collection.name}/{source.prefix}/{name}
63+ // In some cases the prefix is different from the fsPath (source.include fixed part)
64+ // In this case we need to remove the prefix from the path and add the fixed part of the source.include to get the fsPath
65+
66+ let fsPath = path
67+
68+ // First we need to ensure the path is starting with the source prefix in order to be sure the collection is the correct one
69+ if ( source . prefix && withLeadingSlash ( path ) . startsWith ( source . prefix ) ) {
70+ const [ fixPart ] = source . include . includes ( '*' ) ? source . include . split ( '*' ) : [ '' , source . include ]
71+ const fixed = ( fixPart || '' ) . replace ( / ^ \/ / , '' )
72+
73+ const prefix = ( source . prefix || '' ) . replace ( / ^ \/ / , '' )
74+ const pathWithoutPrefix = path . replace ( prefix || '' , '' )
75+
76+ fsPath = join ( fixed , pathWithoutPrefix )
77+ }
78+
79+ const include = minimatch ( fsPath , source . include , { dot : true } )
7180 const exclude = source . exclude ?. some ( exclude => minimatch ( path , exclude ) )
7281
7382 return include && ! exclude
@@ -81,9 +90,15 @@ export function generateFsPathFromId(id: string, source: CollectionInfo['source'
8190 const path = rest . join ( '/' )
8291
8392 const { fixed } = parseSourceBase ( source )
93+ const normalizedFixed = fixed . replace ( / \/ $ / , '' )
94+
95+ // If path already starts with the fixed part, return as is
96+ if ( normalizedFixed && path . startsWith ( normalizedFixed ) ) {
97+ return path
98+ }
8499
85- const pathWithoutFixed = path . substring ( fixed . length )
86- return join ( fixed , pathWithoutFixed )
100+ // Otherwise, join fixed part with path
101+ return join ( fixed , path )
87102}
88103
89104export function getCollectionInfo ( id : string , collections : Record < string , CollectionInfo > ) {
@@ -99,14 +114,6 @@ export function getCollectionInfo(id: string, collections: Record<string, Collec
99114 }
100115}
101116
102- export function parseSourceBase ( source : CollectionSource ) {
103- const [ fixPart , ...rest ] = source . include . includes ( '*' ) ? source . include . split ( '*' ) : [ '' , source . include ]
104- return {
105- fixed : fixPart || '' ,
106- dynamic : '*' + rest . join ( '*' ) ,
107- }
108- }
109-
110117export function createCollectionDocument ( collection : CollectionInfo , id : string , document : CollectionItemBase ) {
111118 const parsedContent = [
112119 pathMetaTransform ,
0 commit comments