Skip to content

Commit

Permalink
refactor: general improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
IgorShadurin committed Jan 19, 2023
1 parent 0fe404c commit bedfb9b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 68 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ Upload an entire directory with files in Node.js
await fdp.directory.upload('my-new-pod', '/Users/fdp/MY_LOCAL_DIRECTORY', { isRecursive: true })
```

Upload an entire directory with files in browser
Upload an entire directory with files in browser.

Create input element with `webkitdirectory` property. With this property entire directory can be chosen instead of a file.

Expand Down
13 changes: 8 additions & 5 deletions src/directory/directory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ import { assertPodName, getExtendedPodsListByAccountData } from '../pod/utils'
import { isNode } from '../shim/utils'
import {
assertBrowserFilesWithPath,
FileInfo,
filterBrowserRecursiveFiles,
filterDotFiles,
browserFileListToFileInfoList,
getDirectoriesToCreate,
getNodeFileContent,
getNodeFileInfoList,
getUploadPath,
BrowserFileInfo,
NodeFileInfo,
} from './utils'
import { uploadData } from '../file/handler'
import { assertNodeFileInfo, isBrowserFileInfo } from './types'

/**
* Directory related class
Expand Down Expand Up @@ -108,7 +110,7 @@ export class Directory {
throw new Error('Directory uploading with path as string is available in Node.js only')
}

let files: FileInfo[]
let files: (BrowserFileInfo | NodeFileInfo)[]

if (isNodePath) {
files = await getNodeFileInfoList(filesSource, Boolean(options.isRecursive))
Expand All @@ -117,7 +119,7 @@ export class Directory {
files = browserFileListToFileInfoList(filesSource)

if (!options.isRecursive) {
files = filterBrowserRecursiveFiles(files)
files = filterBrowserRecursiveFiles(files as BrowserFileInfo[])
}
}

Expand All @@ -143,11 +145,12 @@ export class Directory {
let bytes

if (isNodePath) {
assertNodeFileInfo(file)
bytes = getNodeFileContent(file.fullPath)
} else if (!isNodePath && file.browserFile) {
} else if (!isNodePath && isBrowserFileInfo(file)) {
bytes = await readBrowserFileAsBytes(file.browserFile)
} else {
throw new Error("Directory uploading: one of the browser's files is empty")
throw new Error('Directory uploading: one of the files is not correct')
}

const uploadPath = getUploadPath(file, options.isIncludeDirectoryName!)
Expand Down
23 changes: 23 additions & 0 deletions src/directory/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { isObject, isString } from '../utils/type'
import { BrowserFileInfo, NodeFileInfo } from './utils'

/**
* Checks that browser file info is correct
*/
export function isBrowserFileInfo(value: unknown): value is BrowserFileInfo {
const data = value as BrowserFileInfo

// check that `browserFile` is object, but not `File` to be able to check in node.js where `File` is available
return isObject(data.browserFile) && isString(data.relativePathWithBase) && isString(data.relativePath)
}

/**
* Asserts that node.js file info is correct
*/
export function assertNodeFileInfo(value: unknown): asserts value is NodeFileInfo {
const data = value as NodeFileInfo

if (!(isString(data.fullPath) && isString(data.relativePathWithBase) && isString(data.relativePath))) {
throw new Error('Incorrect node file info')
}
}
43 changes: 21 additions & 22 deletions src/directory/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,29 @@ import { isNode } from '../shim/utils'
import { getBaseName } from '../file/utils'

/**
* Type of file system: Node.js or browser
*/
export enum FileSystemType {
node,
browser,
}

/**
* Information about a file
* General information about a file
*/
export interface FileInfo {
// type of file system
fileSystemType: FileSystemType
// full path of the file. Empty for browser file
fullPath: string
// relative path of a file without base path. e.g `file.txt`
relativePath: string
// relative path of a file with base path. e.g `/all-files/file.txt`
relativePathWithBase: string
}

/**
* Information about browser file
*/
export interface BrowserFileInfo extends FileInfo {
// original browser file
browserFile?: File
browserFile: File
}

/**
* Information about Node.js file
*/
export interface NodeFileInfo extends FileInfo {
// full path of the file
fullPath: string
}

/**
Expand Down Expand Up @@ -241,9 +243,9 @@ export function getDirectoriesToCreate(paths: string[]): string[] {
}

/**
* Converts browser's `FileList` to `InfoList`
* Converts browser's `FileList` to `BrowserFileInfo` array
*/
export function browserFileListToFileInfoList(files: FileList): FileInfo[] {
export function browserFileListToFileInfoList(files: FileList): BrowserFileInfo[] {
if (files.length === 0) {
return []
}
Expand All @@ -261,8 +263,6 @@ export function browserFileListToFileInfoList(files: FileList): FileInfo[] {
const relativePath = file.webkitRelativePath.substring(parts[0].length + 1)

return {
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath,
relativePathWithBase: file.webkitRelativePath,
browserFile: file,
Expand All @@ -273,7 +273,7 @@ export function browserFileListToFileInfoList(files: FileList): FileInfo[] {
/**
* Gets files list with base path like in a browser's `File` object
*/
export async function getNodeFileInfoList(path: string, recursive: boolean): Promise<FileInfo[]> {
export async function getNodeFileInfoList(path: string, recursive: boolean): Promise<NodeFileInfo[]> {
const paths = await getNodePaths(path, recursive)
const pathLength = path.length + 1
const basePath = nodePath.basename(path)
Expand All @@ -283,7 +283,6 @@ export async function getNodeFileInfoList(path: string, recursive: boolean): Pro
const relativePathWithBase = nodePath.join(basePath, relativePath)

return {
fileSystemType: FileSystemType.node,
fullPath,
relativePath,
relativePathWithBase,
Expand Down Expand Up @@ -318,7 +317,7 @@ export function assertBrowserFilesWithPath(value: unknown): asserts value is Fil
/**
* Filters FileInfo items where filename starts with dot
*/
export function filterDotFiles(files: FileInfo[]): FileInfo[] {
export function filterDotFiles<T extends FileInfo>(files: T[]): T[] {
return files.filter(item => {
const basename = getBaseName(item.relativePath)

Expand All @@ -329,7 +328,7 @@ export function filterDotFiles(files: FileInfo[]): FileInfo[] {
/**
* Filters extra files found recursively which browser adds by default
*/
export function filterBrowserRecursiveFiles(files: FileInfo[]): FileInfo[] {
export function filterBrowserRecursiveFiles(files: BrowserFileInfo[]): BrowserFileInfo[] {
return files.filter(item => !item.relativePath.includes('/'))
}

Expand Down
48 changes: 8 additions & 40 deletions test/unit/directory/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
assertDirectoryName,
combine,
FileInfo,
FileSystemType,
filterBrowserRecursiveFiles,
filterDotFiles,
browserFileListToFileInfoList,
Expand All @@ -11,6 +9,7 @@ import {
getPathFromParts,
getPathParts,
getUploadPath,
NodeFileInfo,
} from '../../../src/directory/utils'
import path from 'path'
import { makeFileList } from '../../utils'
Expand All @@ -20,8 +19,6 @@ describe('directory/utils', () => {
const paths1 = [
{
input: {
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'file2.txt',
relativePathWithBase: 'test/file2.txt',
},
Expand All @@ -30,8 +27,6 @@ describe('directory/utils', () => {
},
{
input: {
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'file2.txt',
relativePathWithBase: 'test/file2.txt',
},
Expand All @@ -40,8 +35,6 @@ describe('directory/utils', () => {
},
{
input: {
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'test-1/file1.txt',
relativePathWithBase: 'test/test-1/file1.txt',
},
Expand All @@ -50,8 +43,6 @@ describe('directory/utils', () => {
},
{
input: {
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'test-1/file1.txt',
relativePathWithBase: 'test/test-1/file1.txt',
},
Expand All @@ -68,32 +59,27 @@ describe('directory/utils', () => {
it('filterBrowserRecursiveFiles', () => {
const paths1 = [
{
fileSystemType: FileSystemType.browser,
fullPath: '',
browserFile: {} as File,
relativePath: 'file1.txt',
relativePathWithBase: 'test/file1.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
browserFile: {} as File,
relativePath: 'file2.txt',
relativePathWithBase: 'test/file2.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
browserFile: {} as File,
relativePath: 'test-1/file1.txt',
relativePathWithBase: 'test/test-1/file1.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
browserFile: {} as File,
relativePath: 'test-1/.file1.txt',
relativePathWithBase: 'test/test-1/.file1.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
browserFile: {} as File,
relativePath: 'test-1/test-2/.DS_Store',
relativePathWithBase: 'test/test-1/test-2/.DS_Store',
},
Expand All @@ -108,37 +94,31 @@ describe('directory/utils', () => {
it('filterFileInfoStartingWithDot', () => {
const paths1 = [
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'file1.txt',
relativePathWithBase: 'test/file1.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'file2.txt',
relativePathWithBase: 'test/file2.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'test-1/file1.txt',
relativePathWithBase: 'test/test-1/file1.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: '.file1.txt',
relativePathWithBase: 'test/.file1.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'test-1/.file1.txt',
relativePathWithBase: 'test/test-1/.file1.txt',
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'test-1/test-2/.DS_Store',
relativePathWithBase: 'test/test-1/test-2/.DS_Store',
Expand Down Expand Up @@ -183,7 +163,7 @@ describe('directory/utils', () => {
expect(getDirectoriesToCreate([])).toEqual([])
})

it('getBrowserFileInfoList for browser', async () => {
it('browserFileListToFileInfoList', async () => {
const file1 = {
webkitRelativePath: 'test/file1.txt',
} as File
Expand All @@ -210,22 +190,16 @@ describe('directory/utils', () => {
const result1 = browserFileListToFileInfoList(files)
expect(result1).toEqual([
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'file1.txt',
relativePathWithBase: 'test/file1.txt',
browserFile: file1,
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'file2.txt',
relativePathWithBase: 'test/file2.txt',
browserFile: file2,
},
{
fileSystemType: FileSystemType.browser,
fullPath: '',
relativePath: 'test-1/file1.txt',
relativePathWithBase: 'test/test-1/file1.txt',
browserFile: file3,
Expand All @@ -239,42 +213,36 @@ describe('directory/utils', () => {
const listNoRecursive = await getNodeFileInfoList(fullPath, false)
const expectData1 = [
{
fileSystemType: FileSystemType.node,
fullPath: `${fullPath}/file1.txt`,
relativePath: 'file1.txt',
relativePathWithBase: 'directory-utils/file1.txt',
},
{
fileSystemType: FileSystemType.node,
fullPath: `${fullPath}/file2.txt`,
relativePath: 'file2.txt',
relativePathWithBase: 'directory-utils/file2.txt',
},
] as FileInfo[]
] as NodeFileInfo[]
expect(listNoRecursive).toEqual(expectData1)

const listRecursive = await getNodeFileInfoList(fullPath, true)
expect(listRecursive).toEqual([
{
fileSystemType: FileSystemType.node,
fullPath: `${fullPath}/dir1/dir1-1/file1-1-1.txt`,
relativePath: 'dir1/dir1-1/file1-1-1.txt',
relativePathWithBase: 'directory-utils/dir1/dir1-1/file1-1-1.txt',
},
{
fileSystemType: FileSystemType.node,
fullPath: `${fullPath}/dir2/file2-1.txt`,
relativePath: 'dir2/file2-1.txt',
relativePathWithBase: 'directory-utils/dir2/file2-1.txt',
},
{
fileSystemType: FileSystemType.node,
fullPath: `${fullPath}/file1.txt`,
relativePath: 'file1.txt',
relativePathWithBase: 'directory-utils/file1.txt',
},
{
fileSystemType: FileSystemType.node,
fullPath: `${fullPath}/file2.txt`,
relativePath: 'file2.txt',
relativePathWithBase: 'directory-utils/file2.txt',
Expand Down

0 comments on commit bedfb9b

Please sign in to comment.