Skip to content
This repository was archived by the owner on Sep 9, 2024. It is now read-only.

Commit 2e159fa

Browse files
authored
feat: folder support (#40)
* folder support * improve naming * fix tests
1 parent 6a45a44 commit 2e159fa

File tree

4 files changed

+64
-22
lines changed

4 files changed

+64
-22
lines changed

src/middlewares/localFs/index.spec.ts

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,18 @@ describe('localFsMiddleware', () => {
9999
describe('getMedia', () => {
100100
it('should get media files', async () => {
101101
(listRepoFiles as jest.Mock).mockResolvedValue([
102-
'mediaFolder/asset1.jpg',
103-
'mediaFolder/asset2.jpg',
104-
'mediaFolder/asset3.jpg',
102+
{
103+
file: 'mediaFolder/asset1.jpg',
104+
isDirectory: false
105+
},
106+
{
107+
file: 'mediaFolder/asset2.jpg',
108+
isDirectory: false
109+
},
110+
{
111+
file: 'mediaFolder/asset3.jpg',
112+
isDirectory: false
113+
}
105114
]);
106115

107116
const json = jest.fn();
@@ -126,23 +135,35 @@ describe('localFsMiddleware', () => {
126135
{
127136
path: 'mediaFolder/asset1.jpg',
128137
url: 'mediaFolder/asset1.jpg',
138+
isDirectory: false,
129139
},
130140
{
131141
path: 'mediaFolder/asset2.jpg',
132142
url: 'mediaFolder/asset2.jpg',
143+
isDirectory: false,
133144
},
134145
{
135146
path: 'mediaFolder/asset3.jpg',
136147
url: 'mediaFolder/asset3.jpg',
148+
isDirectory: false,
137149
},
138150
]);
139151
});
140152

141153
it('should translate media path to public path even when media path is absolute', async () => {
142154
(listRepoFiles as jest.Mock).mockResolvedValue([
143-
'mediaFolder/asset1.jpg',
144-
'mediaFolder/asset2.jpg',
145-
'mediaFolder/asset3.jpg',
155+
{
156+
file: 'mediaFolder/asset1.jpg',
157+
isDirectory: false
158+
},
159+
{
160+
file: 'mediaFolder/asset2.jpg',
161+
isDirectory: false
162+
},
163+
{
164+
file: 'mediaFolder/asset3.jpg',
165+
isDirectory: false
166+
}
146167
]);
147168

148169
const json = jest.fn();
@@ -168,23 +189,35 @@ describe('localFsMiddleware', () => {
168189
{
169190
path: 'mediaFolder/asset1.jpg',
170191
url: '/publicFolder/asset1.jpg',
192+
isDirectory: false,
171193
},
172194
{
173195
path: 'mediaFolder/asset2.jpg',
174196
url: '/publicFolder/asset2.jpg',
197+
isDirectory: false,
175198
},
176199
{
177200
path: 'mediaFolder/asset3.jpg',
178201
url: '/publicFolder/asset3.jpg',
202+
isDirectory: false,
179203
},
180204
]);
181205
});
182206

183207
it('should translate media path to public path', async () => {
184208
(listRepoFiles as jest.Mock).mockResolvedValue([
185-
'mediaFolder/asset1.jpg',
186-
'mediaFolder/asset2.jpg',
187-
'mediaFolder/asset3.jpg',
209+
{
210+
file: 'mediaFolder/asset1.jpg',
211+
isDirectory: false
212+
},
213+
{
214+
file: 'mediaFolder/asset2.jpg',
215+
isDirectory: false
216+
},
217+
{
218+
file: 'mediaFolder/asset3.jpg',
219+
isDirectory: false
220+
}
188221
]);
189222

190223
const json = jest.fn();
@@ -210,14 +243,17 @@ describe('localFsMiddleware', () => {
210243
{
211244
path: 'mediaFolder/asset1.jpg',
212245
url: '/publicFolder/asset1.jpg',
246+
isDirectory: false,
213247
},
214248
{
215249
path: 'mediaFolder/asset2.jpg',
216250
url: '/publicFolder/asset2.jpg',
251+
isDirectory: false,
217252
},
218253
{
219254
path: 'mediaFolder/asset3.jpg',
220255
url: '/publicFolder/asset3.jpg',
256+
isDirectory: false,
221257
},
222258
]);
223259
});

src/middlewares/localFs/index.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ export function localFsMiddleware({ repoPath, logger }: FsOptions) {
4141
case 'entriesByFolder': {
4242
const payload = body.params as EntriesByFolderParams;
4343
const { folder, extension, depth } = payload;
44-
const entries = await listRepoFiles(repoPath, folder, extension, depth).then(files =>
44+
const entries = await listRepoFiles(repoPath, folder, extension, depth).then(items =>
4545
entriesFromFiles(
4646
repoPath,
47-
files.map(file => ({ path: file })),
47+
items.map(item => ({ path: item.file })),
4848
),
4949
);
5050
res.json(entries);
@@ -90,11 +90,12 @@ export function localFsMiddleware({ repoPath, logger }: FsOptions) {
9090
}
9191
case 'getMedia': {
9292
const { mediaFolder, publicFolder = mediaFolder } = body.params as GetMediaParams;
93-
const files = await listRepoFiles(repoPath, mediaFolder, '', 1);
93+
const fsItems = await listRepoFiles(repoPath, mediaFolder, '', 1);
9494
res.json(
95-
files.map(file => ({
96-
path: file.replace(/\\/g, '/'),
97-
url: file.replace(/\\/g, '/').replace(mediaFolder.replace(/^\//g, ''), publicFolder),
95+
fsItems.map(item => ({
96+
path: item.file.replace(/\\/g, '/'),
97+
url: item.file.replace(/\\/g, '/').replace(mediaFolder.replace(/^\//g, ''), publicFolder),
98+
isDirectory: item.isDirectory,
9899
})),
99100
);
100101
break;

src/middlewares/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,8 @@ export type DeleteFilesParams = {
6464
commitMessage: string;
6565
};
6666
};
67+
68+
export type FsItem = {
69+
file: string;
70+
isDirectory: boolean;
71+
};

src/middlewares/utils/fs.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import path from 'path';
22
import { promises as fs } from 'fs';
33

4-
async function listFiles(dir: string, extension: string, depth: number): Promise<string[]> {
4+
import type { FsItem } from '../types';
5+
6+
async function listFiles(dir: string, extension: string, depth: number): Promise<FsItem[]> {
57
if (depth <= 0) {
68
return [];
79
}
@@ -11,12 +13,10 @@ async function listFiles(dir: string, extension: string, depth: number): Promise
1113
const files = await Promise.all(
1214
dirents.map(dirent => {
1315
const res = path.join(dir, dirent.name);
14-
return dirent.isDirectory()
15-
? listFiles(res, extension, depth - 1)
16-
: [res].filter(f => f.endsWith(extension));
16+
return {file: [res].filter(f => f.endsWith(extension))[0], isDirectory: dirent.isDirectory()} as FsItem;
1717
}),
1818
);
19-
return ([] as string[]).concat(...files);
19+
return ([] as FsItem[]).concat(...files);
2020
} catch (e) {
2121
return [];
2222
}
@@ -29,7 +29,7 @@ export async function listRepoFiles(
2929
depth: number,
3030
) {
3131
const files = await listFiles(path.join(repoPath, folder), extension, depth);
32-
return files.map(f => f.slice(repoPath.length + 1));
32+
return files.map(f => {return {file: f.file.slice(repoPath.length + 1), isDirectory: f.isDirectory} as FsItem});
3333
}
3434

3535
export async function writeFile(filePath: string, content: Buffer | string) {
@@ -54,7 +54,7 @@ export async function move(from: string, to: string) {
5454
const sourceDir = path.dirname(from);
5555
const destDir = path.dirname(to);
5656
const allFiles = await listFiles(sourceDir, '', 100);
57-
await Promise.all(allFiles.map(file => moveFile(file, file.replace(sourceDir, destDir))));
57+
await Promise.all(allFiles.map(item => moveFile(item.file, item.file.replace(sourceDir, destDir))));
5858
}
5959

6060
export async function getUpdateDate(repoPath: string, filePath: string) {

0 commit comments

Comments
 (0)