11import { getPathInfo } from '@sveltia/utils/file' ;
22import { compare , stripSlashes } from '@sveltia/utils/string' ;
3- import { getI18nConfig } from '$lib/services/contents/i18n' ;
43
54/**
6- * @import {
7- * AssetFolderInfo,
8- * EntryFolderInfo,
9- * InternalLocaleCode,
10- * InternalSiteConfig,
11- * } from '$lib/types/private';
5+ * @import { AssetFolderInfo, InternalSiteConfig } from '$lib/types/private';
6+ * @import { CollectionFile } from '$lib/types/public';
127 */
138
149/**
15- * Get all entry folders.
16- * @param { InternalSiteConfig } config Site configuration .
17- * @returns { EntryFolderInfo[] } Entry folders .
10+ * @typedef { object } GlobalFolders
11+ * @property { string } globalMediaFolder Normalized global `media_folder` option .
12+ * @property { string } globalPublicFolder Normalized global `public_folder` option .
1813 */
19- export const getAllEntryFolders = ( { collections } ) => {
20- const entryCollectionFolders = collections
21- . filter ( ( { folder } ) => typeof folder === 'string' )
22- . map ( ( collection ) => {
23- const { name : collectionName , folder } = collection ;
24- const folderPath = stripSlashes ( /** @type {string } */ ( folder ) ) ;
25- const { i18nEnabled, structure, allLocales } = getI18nConfig ( collection ) ;
26- const i18nRootMultiFolder = i18nEnabled && structure === 'multiple_folders_i18n_root' ;
27-
28- return {
29- collectionName,
30- folderPath,
31- folderPathMap : Object . fromEntries (
32- allLocales . map ( ( locale ) => [
33- locale ,
34- i18nRootMultiFolder ? `${ locale } /${ folderPath } ` : folderPath ,
35- ] ) ,
36- ) ,
37- } ;
38- } )
39- . sort ( ( a , b ) => compare ( a . folderPath ?? '' , b . folderPath ?? '' ) ) ;
40-
41- const fileCollectionFolders = collections
42- . filter ( ( { files } ) => Array . isArray ( files ) )
43- . map ( ( collection ) => {
44- const { name : collectionName , files } = collection ;
45-
46- return ( files ?? [ ] ) . map ( ( file ) => {
47- /** @type {Record<InternalLocaleCode, string> } */
48- const filePathMap = ( ( ) => {
49- const path = stripSlashes ( file . file ) ;
50-
51- if ( ! path . includes ( '{{locale}}' ) ) {
52- return { _default : path } ;
53- }
54-
55- const _i18n = getI18nConfig ( collection , file ) ;
56- const { allLocales, defaultLocale, omitDefaultLocaleFromFileName } = _i18n ;
5714
58- return Object . fromEntries (
59- allLocales . map ( ( locale ) => [
60- locale ,
61- omitDefaultLocaleFromFileName && locale === defaultLocale
62- ? path . replace ( '.{{locale}}' , '' )
63- : path . replace ( '{{locale}}' , locale ) ,
64- ] ) ,
65- ) ;
66- } ) ( ) ;
67-
68- return {
69- collectionName,
70- fileName : file . name ,
71- filePathMap,
72- } ;
73- } ) ;
74- } )
75- . flat ( 1 )
76- . sort ( ( a , b ) => compare ( Object . values ( a . filePathMap ) [ 0 ] , Object . values ( b . filePathMap ) [ 0 ] ) ) ;
77-
78- return [ ...entryCollectionFolders , ...fileCollectionFolders ] ;
79- } ;
15+ /**
16+ * Collection-level and file-level asset folders.
17+ * @type {AssetFolderInfo[] }
18+ * @see https://decapcms.org/docs/collection-folder/#media-and-public-folder
19+ */
20+ const assetFolders = [ ] ;
8021
8122/**
8223 * Replace `{{media_folder}}` and `{{public_folder}}` template tags.
@@ -103,8 +44,7 @@ const replaceTags = (folder, { globalMediaFolder, globalPublicFolder }) =>
10344 * collection file.
10445 * @param {string | undefined } args.baseFolder `folder` option for the collection or base directory
10546 * of the collection file.
106- * @param {string } args.globalMediaFolder Normalized global `media_folder` option.
107- * @param {string } args.globalPublicFolder Normalized global `public_folder` option.
47+ * @param {GlobalFolders } args.globalFolders Global folders information.
10848 * @returns {AssetFolderInfo } Normalized asset folder information.
10949 */
11050const normalizeAssetFolder = ( {
@@ -113,11 +53,8 @@ const normalizeAssetFolder = ({
11353 mediaFolder,
11454 publicFolder,
11555 baseFolder,
116- globalMediaFolder,
117- globalPublicFolder,
56+ globalFolders,
11857} ) => {
119- const globalFolders = { globalMediaFolder, globalPublicFolder } ;
120-
12158 mediaFolder = replaceTags ( mediaFolder , globalFolders ) ;
12259 publicFolder =
12360 publicFolder !== undefined ? replaceTags ( publicFolder , globalFolders ) : mediaFolder ;
@@ -139,6 +76,57 @@ const normalizeAssetFolder = ({
13976 } ;
14077} ;
14178
79+ /**
80+ * Add an asset folder for a collection or collection file if it’s not the same as the global
81+ * asset folder.
82+ * @param {any } args Arguments for {@link normalizeAssetFolder}.
83+ */
84+ const addFolderIfNeeded = ( args ) => {
85+ if ( args . mediaFolder === undefined ) {
86+ return ;
87+ }
88+
89+ const folder = normalizeAssetFolder ( args ) ;
90+ const { globalMediaFolder, globalPublicFolder } = args . globalFolders ;
91+
92+ if (
93+ ! folder . entryRelative &&
94+ folder . internalPath === globalMediaFolder &&
95+ folder . publicPath === globalPublicFolder
96+ ) {
97+ return ;
98+ }
99+
100+ assetFolders . push ( folder ) ;
101+ } ;
102+
103+ /**
104+ * Iterate through files in a file collection and add their folders.
105+ * @param {object } args Arguments.
106+ * @param {string } args.collectionName Collection name.
107+ * @param {CollectionFile[] } args.files Files in a file collection.
108+ * @param {GlobalFolders } args.globalFolders Global folders information.
109+ */
110+ const iterateFiles = ( { collectionName, files, globalFolders } ) => {
111+ files . forEach ( ( file ) => {
112+ const {
113+ name : fileName ,
114+ file : filePath ,
115+ media_folder : fileMediaFolder ,
116+ public_folder : filePublicFolder ,
117+ } = file ;
118+
119+ addFolderIfNeeded ( {
120+ collectionName,
121+ fileName,
122+ mediaFolder : fileMediaFolder ,
123+ publicFolder : filePublicFolder ,
124+ baseFolder : getPathInfo ( filePath ) . dirname ,
125+ globalFolders,
126+ } ) ;
127+ } ) ;
128+ } ;
129+
142130/**
143131 * Get all asset folders.
144132 * @param {InternalSiteConfig } config Site configuration.
@@ -178,35 +166,7 @@ export const getAllAssetFolders = (config) => {
178166 hasTemplateTags : false ,
179167 } ;
180168
181- /**
182- * Collection-level and file-level asset folders.
183- * @type {AssetFolderInfo[] }
184- * @see https://decapcms.org/docs/collection-folder/#media-and-public-folder
185- */
186- const assetFolders = [ ] ;
187-
188- /**
189- * Add an asset folder for a collection or collection file if it’s not the same as the global
190- * asset folder.
191- * @param {any } args Arguments for {@link normalizeAssetFolder}.
192- */
193- const addFolderIfNeeded = ( args ) => {
194- if ( args . mediaFolder === undefined ) {
195- return ;
196- }
197-
198- const folder = normalizeAssetFolder ( args ) ;
199-
200- if (
201- ! folder . entryRelative &&
202- folder . internalPath === globalMediaFolder &&
203- folder . publicPath === globalPublicFolder
204- ) {
205- return ;
206- }
207-
208- assetFolders . push ( folder ) ;
209- } ;
169+ const globalFolders = { globalMediaFolder, globalPublicFolder } ;
210170
211171 collections . forEach ( ( collection ) => {
212172 const {
@@ -228,33 +188,20 @@ export const getAllAssetFolders = (config) => {
228188 return ;
229189 }
230190
231- const normalizeFolderArgs = { collectionName, globalMediaFolder, globalPublicFolder } ;
232191 // When specifying a `path` on an entry collection, `media_folder` defaults to an empty string
233192 const mediaFolder = _mediaFolder === undefined && entryPath !== undefined ? '' : _mediaFolder ;
234193
235194 addFolderIfNeeded ( {
236- ... normalizeFolderArgs ,
195+ collectionName ,
237196 mediaFolder,
238197 publicFolder,
239198 baseFolder,
199+ globalFolders,
240200 } ) ;
241201
242- collectionFiles ?. forEach ( ( file ) => {
243- const {
244- name : fileName ,
245- file : filePath ,
246- media_folder : fileMediaFolder ,
247- public_folder : filePublicFolder ,
248- } = file ;
249-
250- addFolderIfNeeded ( {
251- ...normalizeFolderArgs ,
252- fileName,
253- mediaFolder : fileMediaFolder ,
254- publicFolder : filePublicFolder ,
255- baseFolder : getPathInfo ( filePath ) . dirname ,
256- } ) ;
257- } ) ;
202+ if ( collectionFiles ?. length ) {
203+ iterateFiles ( { collectionName, files : collectionFiles , globalFolders } ) ;
204+ }
258205 } ) ;
259206
260207 assetFolders . sort ( ( a , b ) => compare ( a . internalPath ?? '' , b . internalPath ?? '' ) ) ;
0 commit comments