Compare commits

...

102 Commits

Author SHA1 Message Date
dependabot[bot] 4f4015a4f7 chore(deps-dev): bump karma from 6.3.8 to 6.3.14
Bumps [karma](https://github.com/karma-runner/karma) from 6.3.8 to 6.3.14.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma/compare/v6.3.8...v6.3.14)

---
updated-dependencies:
- dependency-name: karma
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-11 11:38:38 -05:00
dependabot[bot] b73ce7bd2e chore(deps): bump log4js from 6.3.0 to 6.4.0
Bumps [log4js](https://github.com/log4js-node/log4js-node) from 6.3.0 to 6.4.0.
- [Release notes](https://github.com/log4js-node/log4js-node/releases)
- [Changelog](https://github.com/log4js-node/log4js-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/log4js-node/log4js-node/compare/v6.3.0...v6.4.0)

---
updated-dependencies:
- dependency-name: log4js
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-21 15:51:57 -05:00
David Humphrey 3279c2d65a Release 1.4.1 2021-11-15 18:13:39 -05:00
Ben Heidemann e135305f25
Fix Issue 790 and 791 (#795)
* fix: distribute shims and webpack folders to NPM

* docs: update README.md
2021-11-15 18:09:46 -05:00
David Humphrey 0b26979839 Release 1.4.0 2021-11-15 11:12:05 -05:00
Ben Heidemann 7efc4cdc1d
Fix Issue #790 (#793)
* fix: make wepback plugin available from filer/webpack

* deprecate accessing FilerWebpackPlugin through index.js

* docs: update documentation to reflect changes to FilerWebpackPlugin

* docs: fix typo
2021-11-15 11:05:39 -05:00
David Humphrey 4112d072b5 Release 1.3.1 2021-11-13 08:53:11 -05:00
David Humphrey ee26394ead Update dev deps 2021-11-13 08:48:53 -05:00
David Humphrey 9f8804f716 Update actions/setup-node to 2.4.1, fix matrix syntax 2021-10-19 16:58:00 -04:00
David Humphrey 621b6567e0 Update node matrix to 14, 16 2021-10-19 16:49:44 -04:00
David Humphrey 4acd064a2b Release 1.3.0 2021-10-19 16:44:10 -04:00
David Humphrey b283023286 Update deps 2021-10-19 16:40:38 -04:00
Arun Bose 24697a3ed9 fix: rename across directories working 2021-10-19 16:16:31 -04:00
dependabot[bot] 5f872f0f24 chore(deps): bump trim-newlines from 3.0.0 to 3.0.1
Bumps [trim-newlines](https://github.com/sindresorhus/trim-newlines) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/sindresorhus/trim-newlines/releases)
- [Commits](https://github.com/sindresorhus/trim-newlines/commits)

---
updated-dependencies:
- dependency-name: trim-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-08 11:10:49 -04:00
bcheidemann 77abca991a docs: format fs.readdir documentation section 2021-06-05 13:45:41 -04:00
bcheidemann 49ace4b2fb docs: add documentation for the options in fs.readdir 2021-06-05 13:45:41 -04:00
bcheidemann d055d8042e test: update tests for issue #775 2021-06-05 13:45:41 -04:00
bcheidemann 576831370f fix: handle withFileTypes options in readdir 2021-06-05 13:45:41 -04:00
bcheidemann 594ab2621f fix: mkdir accepts encoding options 2021-06-05 13:45:41 -04:00
Ben Heidemann 75a2cc86cf test: skip this until we have a fix 2021-06-05 13:45:41 -04:00
Ben Heidemann a4b3726520 test(#775): add regression test for issue #775 2021-06-05 13:45:41 -04:00
Ben Heidemann 21e7a4750a test: skip test for issue #776 until fix is finished 2021-05-26 09:55:26 -04:00
Ben Heidemann aa2df3a17c test(#776): add regression test for issue #776 2021-05-26 09:55:26 -04:00
Ben Heidemann bd15462f6e test: skip test for issue #776 until fix is finished 2021-05-26 09:55:26 -04:00
Ben Heidemann 78ae19fbad test(#776): add regression test for issue #776 2021-05-26 09:55:26 -04:00
Ben Heidemann b3caddcfec refactor: make fs shim a commonjs module to match node.js fs module 2021-05-26 09:54:38 -04:00
Ben Heidemann 11e05e131b fix: make fs proxy return undefined for keys which do not exist on the file system instance 2021-05-26 09:54:38 -04:00
Ben Heidemann fb100b165a refactor: use Object.assign instead of Object.create for cloning nodePath
because Object.keys omits many of the methods on the filerPath module when using Object.create
2021-05-26 09:54:38 -04:00
Ben Heidemann e94543471b test: rename webpack plugin test 2021-05-26 09:54:38 -04:00
Ben Heidemann 20d4d5e720 chore: remove path dependency 2021-05-26 09:54:38 -04:00
Ben Heidemann 0295d19a7f refactor: rename plugin.js to index.js 2021-05-26 09:54:38 -04:00
Ben Heidemann 365a7d23a3 test: remove describe.only 2021-05-26 09:54:38 -04:00
Ben Heidemann ea5e48b48b style: fix linting issues 2021-05-26 09:54:38 -04:00
Ben Heidemann e82374ae2b test: add spec for webpack plugin 2021-05-26 09:54:38 -04:00
Ben Heidemann 5bd05287d4 test: add mock function create helper to utils 2021-05-26 09:54:38 -04:00
Ben Heidemann 1c34abf009 style: add missing indents in switch 2021-05-26 09:54:38 -04:00
Ben Heidemann 8b4b0a6140 fix: when cwd is root and the <rootDir> tag is replaced, the resulting path should not begin with // 2021-05-26 09:54:38 -04:00
Ben Heidemann e489409b9c test: remove buffer shim spec test 2021-05-26 09:54:38 -04:00
Ben Heidemann 0db08e31bb docs: remove buffer shim docs and replace with info on why it's not provided 2021-05-26 09:54:38 -04:00
Ben Heidemann 1f02edf5b3 refactor: remove buffer shim option from filer webpack plugin 2021-05-26 09:54:38 -04:00
Ben Heidemann 708c84fc63 refactor: remove buffer shim 2021-05-26 09:54:38 -04:00
Ben Heidemann 4e45701b51 test: update path shim test to not use broken import 2021-05-26 09:54:38 -04:00
Ben Heidemann fe9ed6a648 fix: fix shim path export 2021-05-26 09:54:38 -04:00
Ben Heidemann 81ab65b95c docs: update and replace README.md section on using regular node.js imports 2021-05-26 09:54:38 -04:00
Ben Heidemann 582352f754 refactor: add missing import for path in processors 2021-05-26 09:54:38 -04:00
Ben Heidemann 3b9fafc53e style: fix linting issues in webpack plugin 2021-05-26 09:54:38 -04:00
Ben Heidemann bfb50bf608 docs: fix typo in README.md 2021-05-26 09:54:38 -04:00
Ben Heidemann ce56539190 docs: fix typo in webpack plugin docs 2021-05-26 09:54:38 -04:00
Ben Heidemann 0f812fc6a0 refactor: remove typo in webpack plugin 2021-05-26 09:54:38 -04:00
Ben Heidemann 767c83706b docs: add missing filer import in webpack.config.js code snippet 2021-05-26 09:54:38 -04:00
Ben Heidemann 6a20ac2c3f docs: replace alias documentation with docs for FilerWebpackPlugin 2021-05-26 09:54:38 -04:00
Ben Heidemann 2bcf7e560b refactor: export filer webpack plugin in index.js 2021-05-26 09:54:38 -04:00
Ben Heidemann d040763a73 feat: add filer webpack plugin 2021-05-26 09:54:38 -04:00
Ben Heidemann fd90f32d4c chore: add path and schema-utils as dependancies 2021-05-26 09:54:38 -04:00
dependabot[bot] e18104a60d chore(deps): bump browserslist from 4.11.1 to 4.16.6
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.11.1 to 4.16.6.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.11.1...4.16.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-26 09:46:18 -04:00
Ben Heidemann 7bd6e5f4e1 fix: handle case data = 0 in writeFile 2021-04-18 11:44:39 -04:00
Ben Heidemann 90db749ee5 fix: handle case data = 0 in writeFile 2021-04-18 11:44:39 -04:00
Ben Heidemann f9c5473c49 test: add missing space in issue 773 regression test 2021-04-18 11:44:39 -04:00
Ben Heidemann f5ad682fd7 fix: allow encodings other that utf8 when using writeFile 2021-04-18 11:44:39 -04:00
Ben Heidemann 7b1c3e85ce fix(#773): use utf8 encoding when reading file when encoding not specified by options 2021-04-18 11:44:39 -04:00
Ben Heidemann 51afeeaf54 test: simplify regression test for issue773 2021-04-18 11:44:39 -04:00
Ben Heidemann cef6adfc37 style: fix linting issues and invoke done with error if error is captured 2021-04-18 11:44:39 -04:00
Ben Heidemann 6590cb79bd test: add regression test for issue 773 2021-04-18 11:44:39 -04:00
Ben Heidemann 3e88aeca92
Fix issue #766: Remove describe.only from shim tests (#767)
* test: replace describe.only in shim tests with describes so all tests run

* test: move require chai to top of file for consistency with other tests

* chore: npm install

* test: replace describe.only in shim tests with describes so all tests run

* test: move require chai to top of file for consistency with other tests

* chore: npm install

* Revert "chore: npm install"

This reverts commit cddeef421b.

* Revert "test: move require chai to top of file for consistency with other tests"

This reverts commit 40df7912fb.
2021-03-21 13:57:34 -04:00
Ben Heidemann f8c9732be9 docs: correct error in buffer shim documentation 2021-03-20 11:54:36 -04:00
David Humphrey 200171d2a5 Use node-version vs. node_version 2021-03-20 11:48:00 -04:00
David Humphrey 095f78498f Change node version definition in node-js-ci 2021-03-20 11:39:37 -04:00
David Humphrey 5cf2495079 Update node-js-ci workflow to fix broken npm installs 2021-03-20 11:32:38 -04:00
David Humphrey aacc8061cf
Merge pull request #762 from medayo/resolvePackageJSONConflicts
Using filer with webpack
2021-03-07 10:53:40 -05:00
Ben Heidemann c378288819
Merge branch 'master' into resolvePackageJSONConflicts 2021-03-07 15:36:28 +00:00
Ben Heidemann d1054753a6
Merge pull request #3 from medayo/fixTypo
docs: fix buffer import example in README.md
2021-03-07 15:26:31 +00:00
bcheidemann 887ed9318a docs: fix buffer import example in README.md 2021-03-07 15:25:52 +00:00
Ben Heidemann ce076729f6
Merge pull request #2 from medayo/shimTests
Shim tests and buffer shim/docs
2021-03-07 15:23:45 +00:00
bcheidemann a2151cab25 test: add spec for path shim 2021-03-07 15:21:39 +00:00
bcheidemann 3a8a59d362 test: add spec for buffer shim 2021-03-07 15:21:28 +00:00
bcheidemann 15be384940 test: run tests for path and buffer 2021-03-07 15:21:11 +00:00
bcheidemann 6027376efa refactor: use correct import for Buffer in buffer shim 2021-03-07 15:20:58 +00:00
bcheidemann 8b57d299f4 test: add test for fs shim 2021-03-07 15:05:18 +00:00
bcheidemann d6b29226aa refactor: return result of fn when wrapping in utils.shimIndexDB 2021-03-07 15:02:29 +00:00
bcheidemann da65e06e3c test: run fs shim spec test 2021-03-07 15:01:51 +00:00
bcheidemann aa152955b5 refactor: use correct path import in shim 2021-03-07 15:01:05 +00:00
bcheidemann d264113e0d docs: add documentation for use of buffer shim to README.md 2021-03-07 14:58:35 +00:00
bcheidemann ce809c4ac9 feat: add buffer shim 2021-03-07 14:58:09 +00:00
dependabot[bot] 3061328459 Bump ini from 1.3.5 to 1.3.8
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-24 15:24:13 -05:00
David Humphrey c0a41d67ff Add .gitattributes and define eol style as lf 2021-02-24 12:35:38 -05:00
David Humphrey 4941d10e13 Remove 16.x from GitHub Actions node build matrix 2021-02-24 12:07:57 -05:00
David Humphrey 07a00a3f77 Update deps, add GitHub Actions CI 2021-02-24 12:04:39 -05:00
bcheidemann 0f5fe64ae8 chore: npm install regenerator-runtime 2021-02-21 10:25:43 +00:00
bcheidemann 7ec1fed51f chore: use regenerator runtime in tests for async/await 2021-02-21 10:21:03 +00:00
bcheidemann a2f7ee044b chore: show console logs when running tests 2021-02-21 10:18:57 +00:00
bcheidemann 7415e45867 docs: fix typo in README.md
replace 'alternative file sytem' with 'alternative file system provider'
2021-02-21 00:24:19 +00:00
bcheidemann 986ad37597 refactor: get reference to error in catch block
fixes red squigle for unexpected {
2021-02-21 00:21:20 +00:00
bcheidemann 9c669564b2 refactor: change fsprovider to fsProvider 2021-02-21 00:19:17 +00:00
bcheidemann 9d03788c1c docs: add own name to authors file 2021-02-20 04:14:24 +00:00
Ben Heidemann a60d2b4cfc
Merge pull request #1 from medayo/feat/shims
Feat/shims
2021-02-20 04:09:06 +00:00
bcheidemann 417a4e97dd docs: 2021-02-20 04:04:37 +00:00
bcheidemann 4d4b6bf3f3 docs: add recommendation to use fsprovider alias in README.md 2021-02-20 03:54:01 +00:00
bcheidemann f12f01dca0 feat: add path shim 2021-02-20 03:38:52 +00:00
bcheidemann 128e10dc13 docs: add webpack section to README.md 2021-02-20 03:36:34 +00:00
bcheidemann ceed84f377 feat: add shim for fs 2021-02-20 02:43:21 +00:00
bcheidemann 2a581726c6 feat: add shims for file system providers 2021-02-20 02:38:43 +00:00
David Humphrey 75f2a70c7b Fix tag and release naming for release-it update 2020-04-13 13:03:11 -04:00
36 changed files with 16881 additions and 5937 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

27
.github/workflows/node-js-ci.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: node-js-ci
on:
pull_request:
branches:
- master
push:
branches:
- master
jobs:
build:
runs-on: ${{matrix.os}}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: ['14', '16']
name: Node ${{ matrix.node }} on ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Test
uses: actions/setup-node@v2.4.1
with:
node-version: ${{ matrix.node }}
- run: npm install
- run: npm test

1
.gitignore vendored
View File

@ -2,6 +2,7 @@ node_modules
.env
*~
.vscode
.idea
# Parcel build dirs
.cache

View File

@ -5,14 +5,13 @@
},
"git": {
"pushRepo": "git@github.com:filerjs/filer.git",
"tagName": "v%s"
"tagName": "v${version}"
},
"npm": {
"publish": true
},
"github": {
"pushRepo": "git@github.com:filerjs/filer.git",
"release": true,
"releaseName": "Filer.js %s Released"
"release": true
}
}

View File

@ -5,4 +5,5 @@ Barry Tulchinsky <barry.tulchinsky@gmail.com> (@btulchinsky)
Kieran Sedgwick <kieran.sedgwick@gmail.com> (@sedge)
Yoav Gurevich <ygurevich@ymail.com>
Gideon Thomas <r.gideonthomas@gmail.com>
Abdirahman Guled <aguled2@myseneca.ca>
Abdirahman Guled <aguled2@myseneca.ca>
Ben Heidemann <ben@heidemann.co.uk>

View File

@ -54,6 +54,78 @@ requirejs(['filer'], function(Filer) {...}
var Filer = window.Filer;
```
### Webpack Plugin
Filer can be used as a drop-in replacement for the node.js [fs](http://nodejs.org/api/fs.html) and
[path](http://nodejs.org/api/path.html) modules. For convenience, filer provides a webpack plugin which
will shim the desired node.js functionality. This plugin can be used by inserting the following into
your webpack config:
```javascript
// webpack.config.js
var { FilerWebpackPlugin } = require('filer/webpack');
module.exports = {
plugins: [
new FilerWebpackPlugin(),
],
}
```
---
**NOTE**
Previously it was recommended to access the `FilerWebpackPlugin` class by importing the main filer module. This was depracated due [this issue](https://github.com/filerjs/filer/issues/790). For anyone using ***filer version 1.4.0 or earlier***, please import the plugin class like this:
```javascript
var FilerWebpackPlugin = require('filer/src/webpack-plugin');
```
---
You can then import the node.js [fs](http://nodejs.org/api/fs.html) and [path](http://nodejs.org/api/path.html)
modules as normal and `FilerWebpackPlugin` will ensure that webpack will resolve references to these modules to
the appropriate filer shims. You will then be able to use these modules as normal (with the exception of the
synchronous fs methods e.g. `mkdirSync()`).
```javascript
import fs from 'fs';
import path from 'path';
```
The filer webpack plugin will, by default, shim the [fs](http://nodejs.org/api/fs.html) and
[path](http://nodejs.org/api/path.html) modules. However, it's behaviour can be customised by passing an
options object.
```javascript
// webpack.config.js
module.exports = {
plugins: [
new FilerWebpackPlugin({
// Options
}),
],
}
```
The following options can be passed to the filer webpack plugin:
| Option | Type | Optional | Default | Description |
|---------------|---------|----------|--------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| filerDir | string | yes | '\<rootDir\>/node_modules/filer' | The directory in which filer is installed. |
| shimsDir | string | yes | '\<rootDir\>/node_modules/filer/shims' | The directory in which the shims are installed. |
| fsProviderDir | string | yes | '\<rootDir\>/node_modules/filer/shims/providers' | The directory in which the shims are located. This option is required when using a custom provider. |
| shimFs | boolean | yes | true | Should the fs module be shimmed. |
| shimPath | boolean | yes | true | Should the path module be shimmed. |
| fsProvider | string | yes | 'default' | The file system provider to use. Should be one of 'default', 'indexeddb', 'memory', 'custom'. The 'default' option is equivalent to 'indexeddb'. |
NOTE: '\<rootDir\>' will be resolved to the current working directory.
Though filer also exposes the Buffer object, it is left up to the user to shim this as appropriate. This is because filer offers
no custom implementation. Currently, filer uses the [node-libs-browser](https://github.com/webpack/node-libs-browser) Buffer implementation
internally, though any faithful implementation of the [node.js Buffer object](http://nodejs.org/api/buffer.html) should play nicely
with filer.
### Getting Started
Filer is as close to the node.js [fs module](http://nodejs.org/api/fs.html) as possible,
@ -788,7 +860,7 @@ fs.mkdtemp("/myDir/tmp", function (error, path) {
});
```
#### fs.readdir(path, callback)<a name="readdir"></a>
#### fs.readdir(path, [options], callback)<a name="readdir"></a>
Reads the contents of a directory. Asynchronous [readdir(3)](http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir.html).
Callback gets `(error, files)`, where `files` is an array containing the names of each directory entry (i.e., file, directory, link) in the directory, excluding `.` and `..`.
@ -809,6 +881,12 @@ fs.readdir('/docs', function(err, files) {
});
```
Optionally accepts an options parameter, which can be either an encoding (e.g. "utf8") or an object with optional properties `encoding` and `withFileTypes`.
The `encoding` property is a `string` which will determine the character encoding to use for the names of each directory entry. The `withFileTypes` property is a `boolean` which defaults to `false`. If `true`, this method will return an array of [fs.Dirent](https://nodejs.org/api/fs.html#fs_class_fs_dirent) objects.
The `name` property on the [fs.Dirent](https://nodejs.org/api/fs.html#fs_class_fs_dirent) objects will be encoded using the specified character encoding.
#### fs.close(fd, callback)<a name="close"></a>
Closes a file descriptor. Asynchronous [close(2)](http://pubs.opengroup.org/onlinepubs/009695399/functions/close.html).

10820
dist/filer.js vendored

File diff suppressed because it is too large Load Diff

2
dist/filer.js.map vendored

File diff suppressed because one or more lines are too long

188
dist/filer.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,10 +2,14 @@ module.exports = function(config) {
config.set({
singleRun: true,
basePath: '',
files: ['tests/dist/index.js'],
files: [
'node_modules/regenerator-runtime/runtime.js',
'tests/dist/index.js'
],
frameworks: ['mocha', 'chai'],
reporters: ['mocha', 'summary'],
client: {
captureConsole: true,
mocha: {
ui: 'bdd',
timeout: 5000,

10460
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@
"indexeddb",
"idb"
],
"version": "1.2.0",
"version": "1.4.1",
"author": "Alan K <ack@modeswitch.org> (http://blog.modeswitch.org)",
"homepage": "http://filerjs.github.io/filer",
"bugs": "https://github.com/filerjs/filer/issues",
@ -45,37 +45,41 @@
"url": "https://github.com/filerjs/filer.git"
},
"dependencies": {
"es6-promisify": "^6.1.0",
"minimatch": "^3.0.4"
"es6-promisify": "^7.0.0",
"minimatch": "^3.0.4",
"schema-utils": "^3.1.1"
},
"devDependencies": {
"chai": "^4.2.0",
"chai-datetime": "^1.5.0",
"eslint": "^6.8.0",
"fake-indexeddb": "^3.0.0",
"karma": "^5.0.1",
"regenerator-runtime": "^0.13.9",
"chai": "^4.3.4",
"chai-datetime": "^1.8.0",
"eslint": "^7.32.0",
"fake-indexeddb": "^3.1.7",
"karma": "^6.3.8",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.0",
"karma-firefox-launcher": "^1.3.0",
"karma-mocha": "^1.3.0",
"karma-firefox-launcher": "^2.1.2",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-summary-reporter": "^1.7.2",
"meow": "^6.1.0",
"mocha": "^7.1.1",
"nyc": "^15.0.1",
"parcel-bundler": "^1.12.4",
"pretty-bytes": "^5.3.0",
"release-it": "^13.5.2",
"karma-summary-reporter": "^3.0.0",
"meow": "^10.0.1",
"mocha": "^9.1.3",
"nyc": "^15.1.0",
"parcel-bundler": "^1.12.5",
"pretty-bytes": "^5.6.0",
"release-it": "^14.11.6",
"run.env": "^1.1.0",
"unused-filename": "^2.1.0",
"walk": "^2.3.14"
"unused-filename": "^3.0.1",
"walk": "^2.3.15"
},
"main": "./src/index.js",
"browser": "./dist/filer.min.js",
"files": [
"src",
"lib",
"dist"
"dist",
"shims",
"webpack"
],
"nyc": {
"exclude": [

65
shims/fs.js Normal file
View File

@ -0,0 +1,65 @@
const { FileSystem } = require('../src/index');
let Provider;
try {
Provider = require('fsProvider');
}
catch (err) {
Provider = require('./providers/default');
}
const provider = new Provider();
let onFsReady;
let onFsError;
let fsReady = new Promise((resolve, reject) => {
onFsReady = resolve;
onFsError = reject;
});
var fsInstance = new FileSystem({ provider }, (err) => {
if (err) {
onFsError(err);
} else {
onFsReady(true);
}
});
function proxyHasProp(target, prop) {
return prop in target;
}
const fsPromises = new Proxy(fsInstance.promises, {
get(target, prop) {
if (!proxyHasProp(target, prop)) {
return;
}
return async (...args) => {
await fsReady;
return await target[prop](...args);
};
},
});
const fs = new Proxy(fsInstance, {
get(target, prop) {
if (!proxyHasProp(target, prop)) {
return;
}
if (prop === 'promises') {
return fsPromises;
}
return (...args) => {
(async () => {
await fsReady;
target[prop](...args);
})();
};
},
});
module.exports = fs;

3
shims/path.js Normal file
View File

@ -0,0 +1,3 @@
const { path } = require('../src/index');
module.exports = path;

View File

@ -0,0 +1,2 @@
const { Default } = require('../../src/providers/index');
module.exports = Default;

View File

@ -0,0 +1,2 @@
const IndexedDB = require('../../src/providers/indexeddb');
module.exports = IndexedDB;

View File

@ -0,0 +1,2 @@
const Memory = require('../../src/providers/memory');
module.exports = Memory;

12
src/dirent.js Normal file
View File

@ -0,0 +1,12 @@
'use strict';
const Stats = require('./stats.js');
function Dirent(path, fileNode, devName) {
this.constructor = Dirent;
Stats.call(this, path, fileNode, devName);
}
Dirent.prototype = Stats.prototype;
module.exports = Dirent;

View File

@ -4,6 +4,7 @@ var dirname = Path.dirname;
var basename = Path.basename;
var isAbsolutePath = Path.isAbsolute;
var shared = require('../shared.js');
var async = require('../../lib/async.js');
var Constants = require('../constants.js');
var NODE_TYPE_FILE = Constants.NODE_TYPE_FILE;
@ -35,6 +36,7 @@ var openFiles = require('../open-files.js');
var OpenFileDescription = require('../open-file-description.js');
var SuperNode = require('../super-node.js');
var Node = require('../node.js');
var Dirent = require('../dirent.js');
var Stats = require('../stats.js');
/**
@ -478,7 +480,7 @@ function access_file(context, path, mode, callback) {
}
// In any other case, the file isn't accessible
callback(new Errors.EACCES('permission denied',path)) ;
callback(new Errors.EACCES('permission denied',path)) ;
});
}
@ -1077,7 +1079,7 @@ function unlink_node(context, path, callback) {
context.putObject(fileNode.id, fileNode, function(error) {
if(error) {
callback(error);
} else {
} else {
update_node_times(context, path, fileNode, { ctime: Date.now() }, update_directory_data);
}
});
@ -1120,26 +1122,72 @@ function unlink_node(context, path, callback) {
find_node(context, parentPath, read_directory_data);
}
function read_directory(context, path, callback) {
function read_directory(context, path, options, callback) {
path = normalize(path);
if (typeof options === 'function') {
callback = options;
options = {};
}
options = validate_directory_options(options);
var directoryNode;
var directoryData;
function handle_directory_data(error, result) {
if(error) {
if (error) {
callback(error);
} else {
directoryData = result;
var files = Object.keys(directoryData);
callback(null, files);
if (options.encoding) {
var fileBuffers = files.map(function (file) {
return Buffer.from(file);
});
if (options.encoding === 'buffer') {
files = fileBuffers;
}
else {
files = fileBuffers.map(function (fileBuffer) {
return fileBuffer.toString(options.encoding);
});
}
}
if (options.withFileTypes) {
var dirEnts = [];
// eslint-disable-next-line no-inner-declarations
function to_dir_entry(file, callback) {
const filename = Buffer.from(file, options.encoding).toString();
const filepath = Path.join(path, filename);
get_dir_entry(context, filepath, function(error, dirEnt) {
if (error) {
callback(error);
}
dirEnt.name = file;
dirEnts.push(dirEnt);
callback();
});
}
async.eachSeries(files, to_dir_entry, function (error) {
callback(error, dirEnts);
});
}
else {
callback(null, files);
}
}
}
function read_directory_data(error, result) {
if(error) {
if (error) {
callback(error);
} else if(result.type !== NODE_TYPE_DIRECTORY) {
} else if (result.type !== NODE_TYPE_DIRECTORY) {
callback(new Errors.ENOTDIR(null, path));
} else {
directoryNode = result;
@ -1150,6 +1198,30 @@ function read_directory(context, path, callback) {
find_node(context, path, read_directory_data);
}
function get_dir_entry(context, path, callback) {
function check_result(error, result) {
if(error) {
callback(error);
} else {
var stats = new Dirent(path, result, context.name);
callback(null, stats);
}
}
lstat_file(context, path, check_result);
}
function validate_directory_options(options, enc) {
if (!options) {
options = { encoding: enc };
} else if (typeof options === 'function') {
options = { encoding: enc };
} else if (typeof options === 'string') {
options = { encoding: options };
}
return options;
}
function make_symbolic_link(context, srcpath, dstpath, callback) {
dstpath = normalize(dstpath);
var name = basename(dstpath);
@ -1203,12 +1275,12 @@ function make_symbolic_link(context, srcpath, dstpath, callback) {
// but store both versions, since we'll use the relative one in readlink().
if(!isAbsolutePath(srcpath)) {
fileNode.symlink_relpath = srcpath;
srcpath = Path.resolve(parentPath, srcpath);
srcpath = Path.resolve(parentPath, srcpath);
}
fileNode.size = srcpath.length;
fileNode.data = srcpath;
context.putObject(fileNode.id, fileNode, update_directory_data);
});
}
@ -1686,7 +1758,7 @@ function mkdir(context, path, mode, callback) {
mode = validateAndMaskMode(mode, FULL_READ_WRITE_EXEC_PERMISSIONS, callback);
if(!mode) return;
}
make_directory(context, path, callback);
}
@ -1704,14 +1776,14 @@ function mkdtemp(context, prefix, options, callback) {
callback = arguments[arguments.length - 1];
if(!prefix) {
return callback(new Error('filename prefix is required'));
}
}
let random = shared.randomChars(6);
var path = prefix + '-' + random;
var path = prefix + '-' + random;
make_directory(context, path, function(error) {
callback(error, path);
});
});
}
function rmdir(context, path, callback) {
@ -1869,12 +1941,17 @@ function writeFile(context, path, data, options, callback) {
return callback(new Errors.EINVAL('flags is not valid', path));
}
data = data || '';
if(typeof data === 'number') {
data = '' + data;
}
if(typeof data === 'string' && options.encoding === 'utf8') {
data = Buffer.from(data);
if(!Buffer.isBuffer(data)) {
if(typeof data === 'number') {
data = '' + data;
}
data = data || '';
if(typeof data !== 'string') {
data = Buffer.from(data.toString());
}
else {
data = Buffer.from(data || '', options.encoding || 'utf8');
}
}
open_file(context, path, flags, function(err, fileNode) {
@ -2158,8 +2235,8 @@ function lseek(context, fd, offset, whence, callback) {
}
}
function readdir(context, path, callback) {
read_directory(context, path, callback);
function readdir(context, path, options, callback) {
read_directory(context, path, options, callback);
}
function toUnixTimestamp(time) {
@ -2249,7 +2326,7 @@ function rename(context, oldpath, newpath, callback) {
newpath = normalize(newpath);
var oldParentPath = Path.dirname(oldpath);
var newParentPath = Path.dirname(oldpath);
var newParentPath = Path.dirname(newpath);
var oldName = Path.basename(oldpath);
var newName = Path.basename(newpath);
var oldParentDirectory, oldParentData;

View File

@ -8,7 +8,17 @@ module.exports = Filer = {
Path: require('./path.js'),
path: require('./path.js'),
Errors: require('./errors.js'),
Shell: require('./shell/shell.js')
Shell: require('./shell/shell.js'),
/**
* @deprecated Importing filer from your webpack config is not recommended.
*
* The filer `FilerWebpackPlugin` class is exposed directly.
*
* ```
* const { FilerWebpackPlugin } = require('filer/webpack');
* ```
*/
FilerWebpackPlugin: require('./webpack-plugin'),
};
// Add a getter for the `fs` instance, which returns

View File

@ -10,7 +10,7 @@ process.cwd = () => '/';
* a few things we need for the browser environment.
*/
const nodePath = require('path');
const filerPath = Object.create(nodePath);
const filerPath = Object.assign({}, nodePath);
/**
* Patch path.basename() to return / vs. ''

View File

@ -0,0 +1,81 @@
var path = require('path');
var utils = require('./utils');
const PLUGIN_NAME = 'filer-webpack-plugin';
const OPTIONS_SCHEMA = require('./schema');
const OPTIONS_PROCESSORS = require('./processors');
module.exports = class FilerWebpackPlugin {
constructor(options = {}) {
utils.validateOptions(options, OPTIONS_SCHEMA);
this.options = utils.processOptions(options, OPTIONS_PROCESSORS);
}
apply(compiler) {
compiler.hooks.normalModuleFactory.tap(
PLUGIN_NAME,
(factory) => {
factory.hooks.resolve.tap(
PLUGIN_NAME,
(resolveData) => {
// Resolve fsProvider if required
if (
resolveData.request === 'fsProvider'
&& resolveData.context === this.options.shimsDir
) {
return this.resolveFsProvider(resolveData);
}
// Ignore filer files (these should resolve modules normally)
if (resolveData.context.startsWith(this.options.filerDir)) return;
// Apply fs, path and buffer shims if required
switch (resolveData.request) {
case 'fs':
if (!this.options.shimFs) return;
return this.applyFsShim(resolveData);
case 'path':
if (!this.options.shimPath) return;
return this.applyPathShim(resolveData);
default:
return;
}
}
);
},
);
}
resolveFsProvider(resolveData) {
switch (this.options.fsProvider) {
case 'default':
resolveData.request = path.join(this.options.fsProviderDir, 'default.js');
break;
case 'indexeddb':
resolveData.request = path.join(this.options.fsProviderDir, 'indexeddb.js');
break;
case 'memory':
resolveData.request = path.join(this.options.fsProviderDir, 'memory.js');
break;
case 'custom':
resolveData.request = path.join(this.options.fsProviderDir, 'custom.js');
break;
default:
throw new Error([
'Invalid option for fsProvider.',
'fsProvider must be one of \'default\', \'indexeddb\', \'memory\' or \'custom\'.',
'If using a custom fsProvider, you must also provide the fsProviderDir option.'
].join(' '));
}
}
applyFsShim(resolveData) {
resolveData.request = path.join(this.options.shimsDir, 'fs.js');
}
applyPathShim(resolveData) {
resolveData.request = path.join(this.options.shimsDir, 'path.js');
}
};

View File

@ -0,0 +1,34 @@
var path = require('path');
const ROOT_DIR_TAG = '<rootDir>';
const CWD = process.cwd();
module.exports = {
filerDir: {
process: function(value) {
if (!value) {
return path.join(CWD, 'node_modules', 'filer');
}
return path.resolve(value.replace(ROOT_DIR_TAG, CWD));
},
},
shimsDir: {
process: function(value) {
if (!value) {
return path.join(CWD, 'node_modules', 'filer', 'shims');
}
return path.resolve(value.replace(ROOT_DIR_TAG, CWD));
}
},
fsProviderDir: {
process: function(value) {
if (!value) {
return path.join(CWD, 'node_modules', 'filer', 'shims', 'providers');
}
return path.resolve(value.replace(ROOT_DIR_TAG, CWD));
},
},
shimFs: { default: true },
shimPath: { default: true},
fsProvider: { default: 'default'},
};

View File

@ -0,0 +1,23 @@
module.exports = {
type: 'object',
properties: {
filerDir: {
type: 'string',
},
shimsDir: {
type: 'string',
},
shimFs: {
type: 'boolean',
},
shimPath: {
type: 'boolean',
},
fsProvider: {
type: 'string',
},
fsProviderDir: {
type: 'string',
},
}
};

View File

@ -0,0 +1,26 @@
var { validate } = require('schema-utils');
function validateOptions(options, schema) {
validate(schema, options);
}
function processOptions(options, processors) {
const processedOptions = {};
for (const [property, processor] of Object.entries(processors)) {
processedOptions[property] = options[property];
if (processedOptions[property] === undefined) {
processedOptions[property] = processor.default;
}
if (processor.process) {
processedOptions[property] = processor.process(processedOptions[property]);
}
}
return processedOptions;
}
module.exports = {
validateOptions,
processOptions,
};

12
tests/bugs/issue773.js Normal file
View File

@ -0,0 +1,12 @@
'use strict';
const util = require('../lib/test-utils.js');
describe('unexpected failures when calling fs functions (e.g. writeFile) with empty options object, issue 773', function() {
beforeEach(util.setup);
afterEach(util.cleanup);
it('should call fs.writeFile with an empty options object', function(done) {
const fs = util.fs();
fs.writeFile('/a', 'trololol', {}, done);
});
});

115
tests/bugs/issue775.js Normal file
View File

@ -0,0 +1,115 @@
'use strict';
var util = require('../lib/test-utils.js');
var expect = require('chai').expect;
describe('fs.readdir fails when passing options, issue775', function () {
beforeEach(util.setup);
afterEach(util.cleanup);
function setup(fs, dir, cb) {
fs.mkdir(dir, undefined, (err) => {
if (err) {
cb(err);
}
else {
fs.writeFile(dir + '/file', '', (err) => {
if (err) {
cb(err);
}
else {
fs.mkdir(dir + '/folder', (err) => {
if (err) {
cb(err);
}
else {
fs.symlink(dir + '/file', dir + '/symlink', (err) => {
if (err) {
cb(err);
}
else {
cb();
}
});
}
});
}
});
}
});
}
it('should create a directory, add a file, folder and symbolic link then call fs.readdir with buffer encoding', function (done) {
var fs = util.fs();
setup(fs, '/test_dir', (err) => {
if (err) {
done(err);
}
fs.readdir('/test_dir', 'buffer', (err, data) => {
if (err) {
done(err);
}
else {
expect(data).to.have.length(3);
expect(data[0].toString()).to.equal('file');
expect(data[1].toString()).to.equal('folder');
expect(data[2].toString()).to.equal('symlink');
done();
}
});
});
});
it('should create a directory, add a file, folder and symbolic link then call fs.readdir with withFileTypes and encoding options', function (done) {
var fs = util.fs();
setup(fs, '/test_dir', (err) => {
if (err) {
done(err);
}
fs.readdir('/test_dir', { encoding: 'base64', withFileTypes: true }, (err, data) => {
if (err) {
done(err);
}
else {
expect(data).to.have.length(3);
expect(Buffer.from(data[0].name, 'base64').toString()).to.equal('file');
expect(Buffer.from(data[1].name, 'base64').toString()).to.equal('folder');
expect(Buffer.from(data[2].name, 'base64').toString()).to.equal('symlink');
expect(data[0].isFile()).to.be.true;
expect(data[1].isDirectory()).to.be.true;
expect(data[2].isSymbolicLink()).to.be.true;
done();
}
});
});
});
it('should create a directory then call fs.readdir without options', function (done) {
var fs = util.fs();
setup(fs, '/test_dir', (err) => {
if (err) {
done(err);
}
else {
fs.readdir('/test_dir', (err, data) => {
if (err) {
done(err);
}
else {
expect(data).to.have.length(3);
expect(data[0]).to.equal('file');
expect(data[1]).to.equal('folder');
expect(data[2]).to.equal('symlink');
done();
}
});
}
});
});
});

12
tests/bugs/issue776.js Normal file
View File

@ -0,0 +1,12 @@
'use strict';
const util = require('../lib/test-utils.js');
describe('fs.mkdir does not recursively create parent directories when called with { recursive: true }, issue776', function() {
beforeEach(util.setup);
afterEach(util.cleanup);
it.skip('should not throw when calling fs.mkdir with recursive flag set', function(done) {
const fs = util.fs();
fs.mkdir('/test_dir/a/b', { recursive: true }, done);
});
});

View File

@ -3,6 +3,13 @@
* get them running by default.
*/
// Shims
require('./spec/shims/fs.spec');
require('./spec/shims/path.spec');
// Webpack Plugin
require('./spec/webpack-plugin/webpack-plugin.spec');
// Filer
require('./spec/filer.spec');
require('./spec/filer.buffer.spec.js');
@ -84,6 +91,9 @@ require('./bugs/issue267.js');
require('./bugs/issue270.js');
require('./bugs/rename-dir-trailing-slash.js');
require('./bugs/issue357.js');
require('./bugs/issue773.js');
require('./bugs/issue775.js');
require('./bugs/issue776.js');
// Sample code from README
require('./spec/readme.example.spec');

View File

@ -52,11 +52,13 @@ function shimIndexedDB(fn) {
global.indexedDB = require('fake-indexeddb');
}
fn();
var result = fn();
if(addShim) {
delete global.indexedDB;
}
return result;
}
function setup(callback) {
@ -157,6 +159,24 @@ const parseBJSON = json =>
value
);
function createMockFn(implementation = undefined) {
const calls = [];
const mockFn = function(...args) {
calls.push({
args,
});
if (typeof implementation === 'function') {
return implementation(...args);
}
};
Object.defineProperty(mockFn, 'calls', {
get() {
return calls;
}
});
return mockFn;
}
module.exports = {
uniqueName: uniqueName,
setup: setup,
@ -170,5 +190,6 @@ module.exports = {
cleanup: cleanup,
typedArrayEqual: typedArrayEqual,
parseBJSON,
shimIndexedDB
shimIndexedDB,
createMockFn
};

View File

@ -20,7 +20,7 @@ describe('fs.rename', function() {
if(error) throw error;
fs.rename('/myfile', '/myfile', function(error) {
expect(error).not.to.exist;
expect(error).not.to.exist;
done();
});
});
@ -108,6 +108,35 @@ describe('fs.rename', function() {
});
});
it('should rename an existing directory into another sub directory', () => {
var fsPromises = util.fs().promises;
return fsPromises.mkdir('/mydir')
.then(() => fsPromises.mkdir('/mydir/subdir'))
.then(() => fsPromises.mkdir('/anotherdir'))
.then(() => fsPromises.rename('/mydir', '/anotherdir/originaldir'))
.then(() => { fsPromises.stat('/mydir')
.catch((error) => {
expect(error).to.exist;
expect(error.code).to.equal('ENOENT');
});
})
.then(() => { fsPromises.stat('/anotherdir/mydir')
.catch((error) => {
expect(error).to.exist;
expect(error.code).to.equal('ENOENT');
});
})
.then(() => { fsPromises.stat('/anotherdir/originaldir/subdir')
.then(result => {
expect(result.nlinks).to.equal(1);
});
})
.catch((error) => {
if (error) throw error;
});
});
it('should rename an existing directory if the new path points to an existing directory', function(done) {
var fs = util.fs();

View File

@ -0,0 +1,44 @@
'use strict';
const expect = require('chai').expect;
const utils = require('../../lib/test-utils');
const fs = utils.shimIndexedDB(() => require('../../../shims/fs'));
describe('fs shim', () => {
it('should be defined', () => {
expect(fs).to.not.be.undefined;
});
it('should be an object', () => {
expect(typeof fs).to.equal('object');
});
it('should return a function when accessing fs.writeFile', () => {
expect(typeof fs.writeFile).to.equal('function');
});
it('should call callback when calling fs.writeFile', (done) => {
fs.writeFile('/test.txt', 'test', function(err) {
if(err) throw err;
done();
});
});
it('should return an object when accessing fs.promises', () => {
expect(typeof fs.promises).to.equal('object');
});
it('should return a function when accessing fs.promises.writeFile', () => {
expect(typeof fs.promises.writeFile).to.equal('function');
});
it('should return a promise which resolves when calling fs.promises.writeFile', (done) => {
const writeFilePromise = fs.promises.writeFile('/test2.txt', '');
expect(writeFilePromise instanceof Promise).to.equal(true);
writeFilePromise.then(() => {
done();
}).catch((err) => {
done(err);
});
});
});

View File

@ -0,0 +1,14 @@
'use strict';
const expect = require('chai').expect;
const path = require('../../../shims/path');
const pathActual = require('../../../src/index').path;
describe('path shim', () => {
it('should be defined', () => {
expect(path).to.not.be.undefined;
});
it('should be re-exposing path', () => {
expect(path).to.equal(pathActual);
});
});

View File

@ -0,0 +1,528 @@
'use strict';
const expect = require('chai').expect;
const utils = require('../../lib/test-utils');
const FilerWebpackPlugin = require('../../../src/webpack-plugin');
function createNMFResolveCompilerObject(resolveData) {
const normalModuleFactory_resolve_tap = utils.createMockFn(function (name, callback) {
callback(resolveData);
});
const normalModuleFactory = {
hooks: {
resolve: {
tap: normalModuleFactory_resolve_tap
}
}
};
const normalModuleFactory_tap = utils.createMockFn(function (name, callback) {
callback(normalModuleFactory);
});
const compiler = {
hooks: {
normalModuleFactory: {
tap: normalModuleFactory_tap,
}
}
};
return {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
};
}
describe('path shim', () => {
it('should instantiate the plugin with valid options', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'custom',
};
// Act
const plugin = new FilerWebpackPlugin(options);
// Assert
expect(plugin.options).to.not.be.undefined;
expect(plugin.options.filerDir).to.equal(options.filerDir);
expect(plugin.options.shimsDir).to.equal(options.shimsDir);
expect(plugin.options.fsProviderDir).to.equal(options.fsProviderDir);
expect(plugin.options.shimFs).to.equal(options.shimFs);
expect(plugin.options.shimPath).to.equal(options.shimPath);
expect(plugin.options.fsProvider).to.equal(options.fsProvider);
});
it('should instantiate the plugin with default options', () => {
// Act
const plugin = new FilerWebpackPlugin();
// Assert
expect(plugin.options).to.not.be.undefined;
expect(plugin.options.filerDir).to.equal('/node_modules/filer');
expect(plugin.options.shimsDir).to.equal('/node_modules/filer/shims');
expect(plugin.options.fsProviderDir).to.equal('/node_modules/filer/shims/providers');
expect(plugin.options.shimFs).to.equal(true);
expect(plugin.options.shimPath).to.equal(true);
expect(plugin.options.fsProvider).to.equal('default');
});
it('should throw if provided invalid options', () => {
// Arrange
const options = {
filerDir: 123,
shimsDir: 456,
fsProviderDir: 789,
shimFs: 'false',
shimPath: 'false',
fsProvider: false,
};
// Act // Assert
expect(() => {
new FilerWebpackPlugin(options);
}).to.throw();
});
it('should instantiate the plugin with options and the <rootDir> tag should be replaced', () => {
// Arrange
const options = {
filerDir: '<rootDir>/filer',
shimsDir: '<rootDir>/shims',
fsProviderDir: '<rootDir>/fsProvider',
};
// Act
const plugin = new FilerWebpackPlugin(options);
// Assert
expect(plugin.options).to.not.be.undefined;
expect(plugin.options.filerDir).to.equal(options.filerDir.replace('<rootDir>', ''));
expect(plugin.options.shimsDir).to.equal(options.shimsDir.replace('<rootDir>', ''));
expect(plugin.options.fsProviderDir).to.equal(options.fsProviderDir.replace('<rootDir>', ''));
});
describe('should instantiate the plugin with valid options and invoke the apply method', () => {
it('should ignore an unrelated module', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'custom',
};
const resolveData = {
request: 'aModuleWeDontCareAbout',
context: '/some/random/directory',
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(resolveData.request);
});
it('should resolve fsProvider to <fsProviderDir>/default.js when fsProvider options is default', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'default',
};
const resolveData = {
request: 'fsProvider',
context: options.shimsDir,
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(`${options.fsProviderDir}/default.js`);
});
it('should resolve fsProvider to <fsProviderDir>/indexeddb.js when fsProvider options is indexeddb', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'indexeddb',
};
const resolveData = {
request: 'fsProvider',
context: options.shimsDir,
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(`${options.fsProviderDir}/indexeddb.js`);
});
it('should resolve fsProvider to <fsProviderDir>/memory.js when fsProvider options is memory', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'memory',
};
const resolveData = {
request: 'fsProvider',
context: options.shimsDir,
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(`${options.fsProviderDir}/memory.js`);
});
it('should resolve fsProvider to <fsProviderDir>/custom.js when fsProvider options is custom', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'custom',
};
const resolveData = {
request: 'fsProvider',
context: options.shimsDir,
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(`${options.fsProviderDir}/custom.js`);
});
it('should throw an error when an invalid options is provided for fsProvider', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'invalid_fs_provider_option',
};
const resolveData = {
request: 'fsProvider',
context: options.shimsDir,
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
// Act // Assert
expect(() => {
plugin.apply(compiler);
}).to.throw();
});
it('should ignore a request for fs when the context is in the filer directory', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'custom',
};
const resolveData = {
request: 'fs',
context: options.filerDir + '/src',
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(resolveData.request);
});
it('should resolve a request for fs to the fs shim when the context is not in the filer directory', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: true,
shimPath: true,
fsProvider: 'custom',
};
const resolveData = {
request: 'fs',
context: '/some/random/directory',
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(`${options.shimsDir}/fs.js`);
});
it('should not resolve a request for fs to the fs shim when the context is not in the filer directory but shimFs is false', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'custom',
};
const resolveData = {
request: 'fs',
context: '/some/random/directory',
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(resolveData.request);
});
it('should resolve a request for path to the path shim when the context is not in the filer directory', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: true,
shimPath: true,
fsProvider: 'custom',
};
const resolveData = {
request: 'path',
context: '/some/random/directory',
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(`${options.shimsDir}/path.js`);
});
it('should not resolve a request for path to the path shim when the context is not in the filer directory but shimPath is false', () => {
// Arrange
const options = {
filerDir: '/filer',
shimsDir: '/shims',
fsProviderDir: '/fsProvider',
shimFs: false,
shimPath: false,
fsProvider: 'custom',
};
const resolveData = {
request: 'path',
context: '/some/random/directory',
};
const resolveDataIn = Object.create(resolveData);
// Mocks
const {
compiler,
normalModuleFactory_tap,
normalModuleFactory_resolve_tap,
} = createNMFResolveCompilerObject(resolveDataIn);
// Act
const plugin = new FilerWebpackPlugin(options);
plugin.apply(compiler);
// Assert
expect(normalModuleFactory_tap.calls).to.have.length(1);
expect(normalModuleFactory_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(normalModuleFactory_resolve_tap.calls).to.have.length(1);
expect(normalModuleFactory_resolve_tap.calls[0].args[0]).to.equal('filer-webpack-plugin');
expect(resolveDataIn.request).to.equal(resolveData.request);
});
});
});

3
webpack/index.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
FilerWebpackPlugin: require('../src/webpack-plugin'),
};