Skip to content

Commit 4eb8f47

Browse files
dittyromasindresorhus
dittyroma
andauthoredJun 13, 2021
Add directoryMode option (#44)
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
1 parent 694ddb2 commit 4eb8f47

File tree

7 files changed

+58
-6
lines changed

7 files changed

+58
-6
lines changed
 

‎fs.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ exports.utimesSync = (path, atime, mtime) => {
5757
}
5858
};
5959

60-
exports.makeDir = path => makeDir(path, {fs}).catch(error => {
60+
exports.makeDir = (path, options) => makeDir(path, {...options, fs}).catch(error => {
6161
throw new CpFileError(`Cannot create directory \`${path}\`: ${error.message}`, error);
6262
});
6363

64-
exports.makeDirSync = path => {
64+
exports.makeDirSync = (path, options) => {
6565
try {
66-
makeDir.sync(path, {fs});
66+
makeDir.sync(path, {...options, fs});
6767
} catch (error) {
6868
throw new CpFileError(`Cannot create directory \`${path}\`: ${error.message}`, error);
6969
}

‎index.d.ts

+7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ declare namespace cpFile {
66
@default true
77
*/
88
readonly overwrite?: boolean;
9+
10+
/**
11+
[Permissions](https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation) for created directories.
12+
13+
@default 0o777
14+
*/
15+
readonly directoryMode?: number;
916
}
1017

1118
interface ProgressData {

‎index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const cpFileAsync = async (source, destination, options, progressEmitter) => {
1212
progressEmitter.size = stat.size;
1313

1414
const readStream = await fs.createReadStream(source);
15-
await fs.makeDir(path.dirname(destination));
15+
await fs.makeDir(path.dirname(destination), {mode: options.directoryMode});
1616
const writeStream = fs.createWriteStream(destination, {flags: options.overwrite ? 'w' : 'wx'});
1717

1818
readStream.on('data', () => {
@@ -94,7 +94,7 @@ module.exports.sync = (source, destination, options) => {
9494

9595
const stat = fs.statSync(source);
9696
checkSourceIsFile(stat, source);
97-
fs.makeDirSync(path.dirname(destination));
97+
fs.makeDirSync(path.dirname(destination), {mode: options.directoryMode});
9898

9999
const flags = options.overwrite ? null : fsConstants.COPYFILE_EXCL;
100100
try {

‎index.test-d.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {expectType} from 'tsd';
1+
import {expectError, expectType} from 'tsd';
22
import cpFile = require('.');
33
import {ProgressEmitter, ProgressData} from '.';
44

@@ -8,6 +8,16 @@ expectType<Promise<void> & ProgressEmitter>(
88
expectType<Promise<void> & ProgressEmitter>(
99
cpFile('source/unicorn.png', 'destination/unicorn.png', {overwrite: false})
1010
);
11+
expectType<Promise<void> & ProgressEmitter>(
12+
cpFile('source/unicorn.png', 'destination/unicorn.png', {
13+
directoryMode: 0o700
14+
})
15+
);
16+
expectError(
17+
await cpFile('source/unicorn.png', 'destination/unicorn.png', {
18+
directoryMode: '700'
19+
})
20+
);
1121
expectType<Promise<void>>(
1222
cpFile('source/unicorn.png', 'destination/unicorn.png').on(
1323
'progress',
@@ -29,3 +39,13 @@ expectType<void>(
2939
overwrite: false
3040
})
3141
);
42+
expectType<void>(
43+
cpFile.sync('source/unicorn.png', 'destination/unicorn.png', {
44+
directoryMode: 0o700
45+
})
46+
);
47+
expectError(
48+
cpFile.sync('source/unicorn.png', 'destination/unicorn.png', {
49+
directoryMode: '700'
50+
})
51+
);

‎readme.md

+7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ Default: `true`
5959

6060
Overwrite existing destination file.
6161

62+
##### directoryMode
63+
64+
Type: `number`\
65+
Default: `0o777`
66+
67+
[Permissions](https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation) for created directories. Not supported on Windows.
68+
6269
### cpFile.on('progress', handler)
6370

6471
Progress reporting. Only available when using the async method.

‎test/async.js

+9
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ test('do not overwrite when disabled', async t => {
8080
t.is(error.code, 'EEXIST', error.message);
8181
});
8282

83+
test('create directories with specified mode', async t => {
84+
const directory = t.context.destination;
85+
const destination = `${directory}/${uuidv4()}`;
86+
const directoryMode = 0o700;
87+
await cpFile('license', destination, {directoryMode});
88+
const stat = fs.statSync(directory);
89+
t.is(stat.mode & directoryMode, directoryMode);
90+
});
91+
8392
test('do not create `destination` on unreadable `source`', async t => {
8493
const error = await t.throwsAsync(cpFile('node_modules', t.context.destination));
8594
t.is(error.name, 'CpFileError', error.message);

‎test/sync.js

+9
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ test('do not overwrite when disabled', t => {
8181
t.is(fs.readFileSync(t.context.destination, 'utf8'), '');
8282
});
8383

84+
test('create directories with specified mode', t => {
85+
const directory = t.context.destination;
86+
const destination = `${directory}/${uuidv4()}`;
87+
const directoryMode = 0o700;
88+
cpFile.sync('license', destination, {directoryMode});
89+
const stat = fs.statSync(directory);
90+
t.is(stat.mode & directoryMode, directoryMode);
91+
});
92+
8493
test('do not create `destination` on unreadable `source`', t => {
8594
t.throws(
8695
() => {

0 commit comments

Comments
 (0)
Please sign in to comment.