Skip to content

Commit

Permalink
feat(public/fs): allows sources to be array returning functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed May 20, 2019
1 parent 0f6a9c6 commit 1c5786b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 26 deletions.
36 changes: 18 additions & 18 deletions src/public/fs/copy.ts
@@ -1,7 +1,7 @@
import path from 'path';
import fs from 'fs-extra';
import { absolute, exists } from '~/utils/file';
import { IFsUpdateOptions } from './types';
import { IFsUpdateOptions, TSource } from './types';
import expose, { TExposedOverload } from '~/utils/expose';
import confirm from '~/utils/confirm';
import logger from '~/utils/logger';
Expand All @@ -13,24 +13,20 @@ export type TCopyFilterFn =

export default expose(copy) as TExposedOverload<
typeof copy,
| [string | string[] | Promise<string | string[]>, string]
| [string | string[] | Promise<string | string[]>, string, IFsUpdateOptions]
| [string | string[] | Promise<string | string[]>, string, TCopyFilterFn]
| [
string | string[] | Promise<string | string[]>,
string,
IFsUpdateOptions | undefined,
TCopyFilterFn
]
| [TSource, string]
| [TSource, string, IFsUpdateOptions]
| [TSource, string, TCopyFilterFn]
| [TSource, string, IFsUpdateOptions | undefined, TCopyFilterFn]
>;

// TODO allow to take an option to duplicate folder structure on dest from a base + don't allow it when src is upwards instead of nested in that folder
function copy(
src: string | string[] | Promise<string | string[]>,
src: TSource,
dest: string,
filter?: TCopyFilterFn
): () => Promise<void>;
function copy(
src: string | string[] | Promise<string | string[]>,
src: TSource,
dest: string,
options?: IFsUpdateOptions,
filter?: TCopyFilterFn
Expand All @@ -40,14 +36,18 @@ function copy(
* It is an *exposed* function: call `copy.fn()`, which takes the same arguments, in order to execute on call.
* @returns An asynchronous function -hence, calling `copy` won't have any effect until the returned function is called.
*/
function copy(
src: string | string[] | Promise<string | string[]>,
dest: string,
...args: any[]
): () => Promise<void> {
function copy(src: TSource, dest: string, ...args: any[]): () => Promise<void> {
return async () => {
src = await src;
src = typeof src === 'function' ? await src() : await src;

if (Array.isArray(src)) {
// Check dest is a folder
if (await exists(dest)) {
const stat = await fs.stat(dest);
if (!stat.isDirectory()) {
throw Error('Destination must be a folder for an array of sources');
}
}
for (let source of src) {
await trunk(source, path.join(dest, path.parse(source).base), args);
}
Expand Down
5 changes: 3 additions & 2 deletions src/public/fs/mkdir.ts
Expand Up @@ -6,7 +6,7 @@ import { parallel } from 'promist';
import logger from '~/utils/logger';
import chalk from 'chalk';
import expose from '~/utils/expose';
import { IFsCreateDeleteOptions } from './types';
import { IFsCreateDeleteOptions, TSource } from './types';

export default expose(mkdir);
/**
Expand All @@ -17,11 +17,12 @@ export default expose(mkdir);
* @returns An asynchronous function -hence, calling `mkdir` won't have any effect until the returned function is called.
*/
function mkdir(
paths: string | string[],
paths: TSource,
options: IFsCreateDeleteOptions = {}
): () => Promise<void> {
return async () => {
const cwd = process.cwd();
paths = typeof paths === 'function' ? await paths() : await paths;
paths = Array.isArray(paths) ? paths : [paths];
paths = paths.map((path) => absolute({ path, cwd }));

Expand Down
14 changes: 11 additions & 3 deletions src/public/fs/move.ts
@@ -1,7 +1,7 @@
import path from 'path';
import fs from 'fs-extra';
import { absolute, exists } from '~/utils/file';
import { IFsUpdateOptions } from './types';
import { IFsUpdateOptions, TSource } from './types';
import expose from '~/utils/expose';
import confirm from '~/utils/confirm';
import logger from '~/utils/logger';
Expand All @@ -14,13 +14,21 @@ export default expose(move);
* @returns An asynchronous function -hence, calling `move` won't have any effect until the returned function is called.
*/
function move(
src: string | string[] | Promise<string | string[]>,
src: TSource,
dest: string,
options: IFsUpdateOptions = {}
): () => Promise<void> {
return async () => {
src = await src;
src = typeof src === 'function' ? await src() : await src;

if (Array.isArray(src)) {
// Check dest is a folder
if (await exists(dest)) {
const stat = await fs.stat(dest);
if (!stat.isDirectory()) {
throw Error('Destination must be a folder for an array of sources');
}
}
for (let source of src) {
await trunk(source, path.join(dest, path.parse(source).base), options);
}
Expand Down
6 changes: 3 additions & 3 deletions src/public/fs/remove.ts
Expand Up @@ -6,7 +6,7 @@ import { parallel } from 'promist';
import logger from '~/utils/logger';
import chalk from 'chalk';
import expose from '~/utils/expose';
import { IFsCreateDeleteOptions } from './types';
import { IFsCreateDeleteOptions, TSource } from './types';

export default expose(remove);
/**
Expand All @@ -17,12 +17,12 @@ export default expose(remove);
* @returns An asynchronous function -hence, calling `remove` won't have any effect until the returned function is called.
*/
function remove(
paths: string | string[] | Promise<string | string[]>,
paths: TSource,
options: IFsCreateDeleteOptions = {}
): () => Promise<void> {
return async () => {
const cwd = process.cwd();
paths = await paths;
paths = typeof paths === 'function' ? await paths() : await paths;
paths = Array.isArray(paths) ? paths : [paths];
paths = paths.map((path) => absolute({ path, cwd }));

Expand Down
6 changes: 6 additions & 0 deletions src/public/fs/types.ts
@@ -1,3 +1,9 @@
export type TSource =
| string
| string[]
| Promise<string[]>
| (() => string[] | Promise<string[]>);

/**
* Options taken by read *fs* functions.
*/
Expand Down

0 comments on commit 1c5786b

Please sign in to comment.