Skip to content

Commit cb59f08

Browse files
committed
lint
1 parent 42a3e06 commit cb59f08

File tree

7 files changed

+246
-75
lines changed

7 files changed

+246
-75
lines changed
Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,27 @@
1-
# fs-ext
1+
# @wp-playground/fs-ext
22

3-
[![Build Status][ci-img]][ci-url]
4-
[![Coverage Status][cov-img]][cov-url]
5-
[![Windows Status][ci-win-img]][ci-win-url]
3+
A fork of [fs-ext](https://github.com/baudehlo/node-fs-ext) that ships prebuilt binaries for all major platforms and adds Windows-specific file locking APIs.
64

7-
Extras not included in Node's fs module.
5+
## Why this fork?
86

9-
**Note**:
7+
The original `fs-ext` package requires compilation during `npm install`, which can fail in environments without build tools. This fork:
108

11-
- From `v2.0.0` onwards, module doesn't override `fs` and `constants` Node.js core modules. Instead
12-
import functions and constants directly:
13-
14-
```js
15-
const { flock, constants } = require('fs-ext');
16-
// or
17-
const fsExt = require('fs-ext');
18-
// fsExt.flock
19-
// fsExt.constants
20-
```
21-
22-
- From `v1.0.0` onwards, fs.utime and fs.utimeSync have been removed.
23-
Use fs.utimes and fs.utimesSync instead.
9+
- **Ships prebuilt binaries** for macOS (x64, arm64), Linux (x64, arm64), and Windows (x64, arm64)
10+
- **Adds `LockFileEx`/`UnlockFileEx`** Windows APIs for byte-range file locking
11+
- **Supports Node.js 20+** and Electron
12+
- **Falls back to local compilation** if no prebuilt binary matches your platform
2413

2514
## Installation
2615

27-
Install via npm:
28-
2916
```sh
30-
npm install fs-ext
17+
npm install @wp-playground/fs-ext
3118
```
3219

3320
## Usage
3421

35-
fs-ext imports all of the methods from the core 'fs' module, so you don't
36-
need two objects.
37-
3822
```js
23+
const { flock, flockSync } = require('@wp-playground/fs-ext');
3924
const fs = require('fs');
40-
const { flock } = require('fs-ext');
4125

4226
const fd = fs.openSync('foo.txt', 'r');
4327
flock(fd, 'ex', (err) => {
@@ -48,8 +32,6 @@ flock(fd, 'ex', (err) => {
4832
});
4933
```
5034

51-
For an advanced example checkout `example.js`.
52-
5335
## API
5436

5537
### flock(fd, flags, [callback])
@@ -80,21 +62,6 @@ The supported commands are:
8062
- 'getlk' ( F_GETLK )
8163
- 'setlkw' ( F_SETLKW )
8264

83-
Requiring this module adds `FD_CLOEXEC` to the constants module, for use with F_SETFD,
84-
and also F_RDLCK, F_WRLCK and F_UNLCK for use with F_SETLK (etc).
85-
86-
File locking can be used like so:
87-
88-
```js
89-
const { fnctl, constants } = require('fs-ext');
90-
91-
fcntl(fd, 'setlkw', constants.F_WRLCK, (err) => {
92-
if (!err) {
93-
// Lock succeeded
94-
}
95-
});
96-
```
97-
9865
### fcntlSync(fd, flags)
9966

10067
Synchronous fcntl(2). Throws an exception on error.
@@ -112,12 +79,40 @@ plus offset bytes (usually negative or zero to seek to the end of the file).
11279

11380
### seekSync(fd, offset, whence)
11481

115-
Synchronous lseek(2). Throws an exception on error. Returns current
116-
file position.
82+
Synchronous lseek(2). Throws an exception on error. Returns current file position.
83+
84+
### lockFileEx(fd, flags, offsetLow, offsetHigh, lengthLow, lengthHigh, [callback]) - Windows only
85+
86+
Asynchronous LockFileEx. Locks a byte range in a file.
87+
88+
Flags:
89+
90+
- `0` - shared lock
91+
- `constants.LOCKFILE_EXCLUSIVE_LOCK` - exclusive lock
92+
- `constants.LOCKFILE_FAIL_IMMEDIATELY` - non-blocking (can be OR'd with above)
93+
94+
### lockFileExSync(fd, flags, offsetLow, offsetHigh, lengthLow, lengthHigh) - Windows only
95+
96+
Synchronous LockFileEx. Throws an exception on error.
97+
98+
### unlockFileEx(fd, offsetLow, offsetHigh, lengthLow, lengthHigh, [callback]) - Windows only
99+
100+
Asynchronous UnlockFileEx. Unlocks a byte range in a file.
101+
102+
### unlockFileExSync(fd, offsetLow, offsetHigh, lengthLow, lengthHigh) - Windows only
103+
104+
Synchronous UnlockFileEx. Throws an exception on error.
105+
106+
## Constants
107+
108+
Available via `require('@wp-playground/fs-ext').constants`:
109+
110+
- `LOCK_SH`, `LOCK_EX`, `LOCK_NB`, `LOCK_UN` - flock flags
111+
- `F_GETFD`, `F_SETFD`, `F_GETLK`, `F_SETLK`, `F_SETLKW` - fcntl commands
112+
- `F_RDLCK`, `F_WRLCK`, `F_UNLCK` - fcntl lock types
113+
- `FD_CLOEXEC` - close-on-exec flag
114+
- `LOCKFILE_EXCLUSIVE_LOCK`, `LOCKFILE_FAIL_IMMEDIATELY` - Windows LockFileEx flags
115+
116+
## License
117117

118-
[ci-img]: https://travis-ci.org/baudehlo/node-fs-ext.svg?branch=master
119-
[ci-url]: https://travis-ci.org/baudehlo/node-fs-ext
120-
[cov-img]: https://codecov.io/github/baudehlo/node-fs-ext/coverage.svg
121-
[cov-url]: https://codecov.io/github/baudehlo/node-fs-ext?branch=master
122-
[ci-win-img]: https://ci.appveyor.com/api/projects/status/pqbnutckk0n46uc8?svg=true
123-
[ci-win-url]: https://ci.appveyor.com/project/baudehlo/node-fs-ext/branch/master
118+
MIT

fs-ext-prebuilt/src/package/binding.gyp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,58 @@
55
"include_dirs" : [ "<!(node -e \"require('nan')\")" ],
66
"sources": [
77
"fs-ext.cc"
8+
],
9+
"cflags_cc!": [
10+
"-std=gnu++0x",
11+
"-std=gnu++11",
12+
"-std=gnu++14",
13+
"-std=gnu++17",
14+
"-std=c++11",
15+
"-std=c++14",
16+
"-std=c++17"
17+
],
18+
"cflags_cc": [
19+
"-std=c++20"
20+
],
21+
"conditions": [
22+
[ 'OS=="win"', {
23+
"msvs_settings": {
24+
"VCCLCompilerTool": {
25+
"AdditionalOptions!": [ "/std:c++17" ],
26+
"AdditionalOptions": [ "/std:c++20" ]
27+
}
28+
}
29+
}],
30+
[ 'OS=="mac"', {
31+
"cflags_cc!": [
32+
"-std=gnu++0x",
33+
"-std=gnu++11",
34+
"-std=gnu++14",
35+
"-std=gnu++17",
36+
"-std=c++11",
37+
"-std=c++14",
38+
"-std=c++17"
39+
],
40+
"cflags_cc": [
41+
"-std=c++20"
42+
],
43+
"xcode_settings": {
44+
"CLANG_CXX_LANGUAGE_STANDARD": "c++20",
45+
"CLANG_CXX_LIBRARY": "libc++",
46+
"OTHER_CPLUSPLUSFLAGS!": [
47+
"-std=gnu++0x",
48+
"-std=gnu++11",
49+
"-std=gnu++14",
50+
"-std=gnu++17",
51+
"-std=c++11",
52+
"-std=c++14",
53+
"-std=c++17"
54+
],
55+
"OTHER_CPLUSPLUSFLAGS": [
56+
"-std=c++20"
57+
]
58+
}
59+
}]
860
]
961
}
1062
]

fs-ext-prebuilt/src/package/fs-ext.js

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,124 @@
1919

2020
'use strict';
2121

22-
var binding = require('./build/Release/fs_ext.node');
22+
var path = require('path');
23+
var fs = require('fs');
24+
25+
/**
26+
* Try to load a prebuilt binary from the binaries directory.
27+
* Falls back to the locally built binary if no prebuilt is found.
28+
*/
29+
function loadBinding() {
30+
var platform = process.platform;
31+
var archName = process.arch;
32+
var nodeVersion = process.versions.node.split('.')[0] + '.0.0';
33+
34+
// Check if running in Electron
35+
var isElectron = !!(process.versions && process.versions.electron);
36+
var electronVersion = isElectron ? process.versions.electron : null;
37+
38+
// Try to find matching binaries
39+
var binariesDir = path.join(__dirname, 'binaries');
40+
var files;
41+
try {
42+
files = fs.readdirSync(binariesDir);
43+
} catch (e) {
44+
// Binaries directory doesn't exist, fall back to build
45+
return null;
46+
}
47+
48+
// Build the expected filename pattern
49+
// Format: fs-ext-{platform}-{arch}[-libc]-{runtime}-{version}.node
50+
var platformArch = platform + '-' + archName;
51+
52+
// Filter files that match our platform/arch
53+
var candidates = files.filter(function (f) {
54+
return (
55+
f.startsWith('fs-ext-') &&
56+
f.includes(platformArch) &&
57+
f.endsWith('.node')
58+
);
59+
});
60+
61+
// Try Electron first if running in Electron
62+
if (isElectron && electronVersion) {
63+
var electronBinary = candidates.find(function (f) {
64+
return f.includes('electron-' + electronVersion);
65+
});
66+
if (electronBinary) {
67+
try {
68+
return require(path.join(binariesDir, electronBinary));
69+
} catch (e) {
70+
// Failed to load, continue to Node binary
71+
}
72+
}
73+
}
74+
75+
// Try to find exact Node version match first, then fall back to major version
76+
var nodeBinary = candidates.find(function (f) {
77+
return f.includes('node-' + nodeVersion);
78+
});
79+
80+
if (!nodeBinary) {
81+
// Try to find any node binary for this platform (use highest version <= current)
82+
var nodeVersionNum = parseInt(process.versions.node.split('.')[0], 10);
83+
var nodeCandidates = candidates
84+
.filter(function (f) {
85+
return f.includes('-node-');
86+
})
87+
.map(function (f) {
88+
var match = f.match(/-node-(\d+)\./);
89+
return match
90+
? { file: f, version: parseInt(match[1], 10) }
91+
: null;
92+
})
93+
.filter(function (c) {
94+
return c && c.version <= nodeVersionNum;
95+
})
96+
.sort(function (a, b) {
97+
return b.version - a.version;
98+
});
99+
100+
if (nodeCandidates.length > 0) {
101+
nodeBinary = nodeCandidates[0].file;
102+
}
103+
}
104+
105+
if (nodeBinary) {
106+
return require(path.join(binariesDir, nodeBinary));
107+
}
108+
109+
// No matching prebuilt found
110+
return null;
111+
}
112+
113+
// Try loading prebuilt binaries, fallback to the node-gyp built binary
114+
let binding;
115+
try {
116+
binding = loadBinding();
117+
if (!binding) {
118+
// No prebuilt found, try the local build
119+
binding = require('./build/Release/fs_ext.node');
120+
}
121+
} catch (e) {
122+
// loadBinding threw an error, try local build as last resort
123+
try {
124+
binding = require('./build/Release/fs_ext.node');
125+
} catch (buildError) {
126+
throw new Error(
127+
'Failed to load fs-ext native module. ' +
128+
'No prebuilt binary found for ' +
129+
process.platform +
130+
'-' +
131+
process.arch +
132+
' (Node ' +
133+
process.version +
134+
'), and no local build available. ' +
135+
'Original error: ' +
136+
e.message
137+
);
138+
}
139+
}
23140

24141
// Used by flock
25142
function stringToFlockFlags(flag) {

fs-ext-prebuilt/src/package/package.json

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,42 @@
11
{
2-
"author": "Matt Sergeant <helpme@gmail.com> (http://baudehlo.wordpress.com/)",
3-
"name": "fs-ext",
4-
"description": "Extensions to core 'fs' module.",
2+
"name": "@wp-playground/fs-ext",
3+
"description": "Fork of fs-ext with prebuilt binaries and Windows LockFileEx support.",
54
"keywords": [
65
"fs",
76
"filesystem",
87
"flock",
9-
"seek"
8+
"seek",
9+
"lockfileex",
10+
"prebuilt"
1011
],
11-
"version": "2.1.1",
12-
"homepage": "https://github.com/baudehlo/node-fs-ext/",
12+
"version": "2.2.0",
13+
"homepage": "https://github.com/adamziel/fs-ext-prebuilt",
1314
"repository": {
1415
"type": "git",
15-
"url": "git://github.com/baudehlo/node-fs-ext.git"
16+
"url": "git://github.com/adamziel/fs-ext-prebuilt.git"
1617
},
18+
"author": "WordPress Playground team",
19+
"contributors": [
20+
"Matt Sergeant <helpme@gmail.com> (http://baudehlo.wordpress.com/)"
21+
],
1722
"main": "fs-ext.js",
1823
"engines": {
1924
"node": ">= 8.0.0"
2025
},
2126
"dependencies": {
22-
"nan": "^2.21.0",
27+
"nan": "^2.24.0",
2328
"node-abi": "^3.85.0",
29+
"node-gyp": "^11.2.0",
2430
"node-gyp-build": "^4.8.4",
2531
"prebuildify": "^6.0.1"
2632
},
27-
"licenses": [
28-
{
29-
"type": "MIT"
30-
}
31-
],
33+
"license": "MIT",
3234
"bugs": {
33-
"mail": "helpme@gmail.com",
34-
"web": "https://github.com/baudehlo/node-fs-ext/issues"
35+
"url": "https://github.com/adamziel/fs-ext-prebuilt/issues"
3536
},
3637
"scripts": {
37-
"install": "node-gyp configure build",
38+
"prebuilds": "node ./prebuildify.js",
39+
"install": "node ./install.js",
3840
"test": "node ./run_tests",
3941
"lint": "node ./node_modules/eslint/bin/eslint \"*.js\" \"tests/**/*.js\"",
4042
"cover": "NODE_ENV=cov ./node_modules/.bin/istanbul cover node ./run_tests"

fs-ext-prebuilt/src/package/run_tests.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ require('./tests/test-fs-seek');
88

99
require('./tests/test-fs-flock');
1010

11+
// Windows-specific LockFileEx/UnlockFileEx tests
12+
if (process.platform === 'win32') {
13+
require('./tests/test-fs-lockfileex');
14+
}
15+
1116
require('./tests/worker-test.js');
1217

1318
// for stress testing only

0 commit comments

Comments
 (0)