memfs 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/LICENSE +201 -24
  2. package/README.md +21 -92
  3. package/lib/Dirent.d.ts +2 -1
  4. package/lib/__tests__/util.d.ts +13 -0
  5. package/lib/__tests__/util.js +29 -0
  6. package/lib/consts/AMODE.d.ts +9 -0
  7. package/lib/consts/FLAG.d.ts +22 -0
  8. package/lib/consts/FLAG.js +2 -0
  9. package/lib/fsa/types.d.ts +3 -3
  10. package/lib/fsa-to-node/FsaNodeCore.d.ts +32 -0
  11. package/lib/fsa-to-node/FsaNodeCore.js +168 -0
  12. package/lib/fsa-to-node/FsaNodeDirent.d.ts +13 -0
  13. package/lib/fsa-to-node/FsaNodeDirent.js +31 -0
  14. package/lib/fsa-to-node/FsaNodeFs.d.ts +171 -0
  15. package/lib/fsa-to-node/FsaNodeFs.js +842 -0
  16. package/lib/fsa-to-node/FsaNodeFsOpenFile.d.ts +24 -0
  17. package/lib/fsa-to-node/FsaNodeFsOpenFile.js +46 -0
  18. package/lib/fsa-to-node/FsaNodeReadStream.d.ts +24 -0
  19. package/lib/fsa-to-node/FsaNodeReadStream.js +100 -0
  20. package/lib/fsa-to-node/FsaNodeStats.d.ts +30 -0
  21. package/lib/fsa-to-node/FsaNodeStats.js +52 -0
  22. package/lib/fsa-to-node/FsaNodeWriteStream.d.ts +48 -0
  23. package/lib/fsa-to-node/FsaNodeWriteStream.js +162 -0
  24. package/lib/fsa-to-node/__tests__/FsaNodeFs.test.d.ts +1 -0
  25. package/lib/fsa-to-node/__tests__/FsaNodeFs.test.js +873 -0
  26. package/lib/fsa-to-node/__tests__/util.test.d.ts +1 -0
  27. package/lib/fsa-to-node/__tests__/util.test.js +28 -0
  28. package/lib/fsa-to-node/constants.d.ts +3 -0
  29. package/lib/fsa-to-node/constants.js +2 -0
  30. package/lib/fsa-to-node/index.d.ts +2 -0
  31. package/lib/fsa-to-node/index.js +7 -0
  32. package/lib/fsa-to-node/json.d.ts +4 -0
  33. package/lib/fsa-to-node/json.js +7 -0
  34. package/lib/fsa-to-node/types.d.ts +37 -0
  35. package/lib/fsa-to-node/types.js +2 -0
  36. package/lib/fsa-to-node/util.d.ts +4 -0
  37. package/lib/fsa-to-node/util.js +40 -0
  38. package/lib/fsa-to-node/worker/FsaNodeSyncAdapterWorker.d.ts +10 -0
  39. package/lib/fsa-to-node/worker/FsaNodeSyncAdapterWorker.js +72 -0
  40. package/lib/fsa-to-node/worker/FsaNodeSyncWorker.d.ts +20 -0
  41. package/lib/fsa-to-node/worker/FsaNodeSyncWorker.js +190 -0
  42. package/lib/fsa-to-node/worker/SyncMessenger.d.ts +24 -0
  43. package/lib/fsa-to-node/worker/SyncMessenger.js +80 -0
  44. package/lib/fsa-to-node/worker/constants.d.ts +8 -0
  45. package/lib/fsa-to-node/worker/constants.js +2 -0
  46. package/lib/fsa-to-node/worker/types.d.ts +17 -0
  47. package/lib/fsa-to-node/worker/types.js +2 -0
  48. package/lib/index.d.ts +5 -4
  49. package/lib/index.js +1 -1
  50. package/lib/node/constants.d.ts +41 -0
  51. package/lib/node/constants.js +56 -0
  52. package/lib/node/options.d.ts +23 -0
  53. package/lib/node/options.js +94 -0
  54. package/lib/node/promises.d.ts +1 -1
  55. package/lib/node/promises.js +1 -3
  56. package/lib/node/types/FsCommonObjects.d.ts +17 -0
  57. package/lib/node/types/FsCommonObjects.js +2 -0
  58. package/lib/node/types/{sync.d.ts → FsSynchronousApi.d.ts} +36 -37
  59. package/lib/node/types/FsSynchronousApi.js +2 -0
  60. package/lib/node/types/callback.d.ts +57 -58
  61. package/lib/node/types/index.d.ts +1 -1
  62. package/lib/node/types/misc.d.ts +6 -8
  63. package/lib/node/types/options.d.ts +20 -6
  64. package/lib/node/types/promises.d.ts +2 -2
  65. package/lib/node/util.d.ts +19 -0
  66. package/lib/node/util.js +265 -1
  67. package/lib/node-to-fsa/NodeFileSystemDirectoryHandle.d.ts +71 -0
  68. package/lib/node-to-fsa/NodeFileSystemDirectoryHandle.js +264 -0
  69. package/lib/node-to-fsa/NodeFileSystemFileHandle.d.ts +28 -0
  70. package/lib/node-to-fsa/NodeFileSystemFileHandle.js +73 -0
  71. package/lib/node-to-fsa/NodeFileSystemHandle.d.ts +33 -0
  72. package/lib/node-to-fsa/NodeFileSystemHandle.js +53 -0
  73. package/lib/node-to-fsa/NodeFileSystemSyncAccessHandle.d.ts +42 -0
  74. package/lib/node-to-fsa/NodeFileSystemSyncAccessHandle.js +116 -0
  75. package/lib/node-to-fsa/NodeFileSystemWritableFileStream.d.ts +54 -0
  76. package/lib/node-to-fsa/NodeFileSystemWritableFileStream.js +195 -0
  77. package/lib/node-to-fsa/NodePermissionStatus.d.ts +8 -0
  78. package/lib/node-to-fsa/NodePermissionStatus.js +13 -0
  79. package/lib/node-to-fsa/__tests__/NodeFileSystemDirectoryHandle.test.d.ts +1 -0
  80. package/lib/node-to-fsa/__tests__/NodeFileSystemDirectoryHandle.test.js +627 -0
  81. package/lib/node-to-fsa/__tests__/NodeFileSystemFileHandle.test.d.ts +1 -0
  82. package/lib/node-to-fsa/__tests__/NodeFileSystemFileHandle.test.js +191 -0
  83. package/lib/node-to-fsa/__tests__/NodeFileSystemHandle.test.d.ts +1 -0
  84. package/lib/node-to-fsa/__tests__/NodeFileSystemHandle.test.js +49 -0
  85. package/lib/node-to-fsa/__tests__/NodeFileSystemSyncAccessHandle.test.d.ts +1 -0
  86. package/lib/node-to-fsa/__tests__/NodeFileSystemSyncAccessHandle.test.js +183 -0
  87. package/lib/node-to-fsa/__tests__/NodeFileSystemWritableFileStream.test.d.ts +1 -0
  88. package/lib/node-to-fsa/__tests__/NodeFileSystemWritableFileStream.test.js +106 -0
  89. package/lib/node-to-fsa/__tests__/scenarios.test.d.ts +1 -0
  90. package/lib/node-to-fsa/__tests__/scenarios.test.js +46 -0
  91. package/lib/node-to-fsa/__tests__/util.test.d.ts +1 -0
  92. package/lib/node-to-fsa/__tests__/util.test.js +25 -0
  93. package/lib/node-to-fsa/index.d.ts +7 -0
  94. package/lib/node-to-fsa/index.js +26 -0
  95. package/lib/node-to-fsa/types.d.ts +12 -0
  96. package/lib/node-to-fsa/types.js +2 -0
  97. package/lib/node-to-fsa/util.d.ts +11 -0
  98. package/lib/node-to-fsa/util.js +33 -0
  99. package/lib/node.d.ts +1 -1
  100. package/lib/volume.d.ts +45 -126
  101. package/lib/volume.js +204 -562
  102. package/lib/webfs/index.d.ts +1 -0
  103. package/lib/webfs/index.js +22 -0
  104. package/package.json +28 -5
  105. /package/lib/{node/types/sync.js → consts/AMODE.js} +0 -0
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const __1 = require("../..");
13
+ const NodeFileSystemDirectoryHandle_1 = require("../NodeFileSystemDirectoryHandle");
14
+ const util_1 = require("../../__tests__/util");
15
+ const setup = (json = {}) => {
16
+ const fs = (0, __1.memfs)(json, '/');
17
+ const dir = new NodeFileSystemDirectoryHandle_1.NodeFileSystemDirectoryHandle(fs, '/', { mode: 'readwrite' });
18
+ return { dir, fs };
19
+ };
20
+ (0, util_1.onlyOnNode20)('NodeFileSystemFileHandle', () => {
21
+ describe('.getFile()', () => {
22
+ test('can read file contents', () => __awaiter(void 0, void 0, void 0, function* () {
23
+ const { dir, fs } = setup({
24
+ 'file.txt': 'Hello, world!',
25
+ });
26
+ const entry = yield dir.getFileHandle('file.txt');
27
+ const file = yield entry.getFile();
28
+ const contents = yield file.text();
29
+ expect(entry.name).toBe('file.txt');
30
+ expect(file).toBeInstanceOf(File);
31
+ expect(file.name).toBe('file.txt');
32
+ expect(file.lastModified).toBe(fs.statSync('/file.txt').mtime.getTime());
33
+ expect(contents).toBe('Hello, world!');
34
+ }));
35
+ });
36
+ describe('.createWritable()', () => {
37
+ test('throws if not in "readwrite" mode', () => __awaiter(void 0, void 0, void 0, function* () {
38
+ const fs = (0, __1.memfs)({ 'file.txt': 'abc' }, '/');
39
+ const dir = new NodeFileSystemDirectoryHandle_1.NodeFileSystemDirectoryHandle(fs, '/', { mode: 'read' });
40
+ const entry = yield dir.getFileHandle('file.txt');
41
+ try {
42
+ yield entry.createWritable();
43
+ throw new Error('Not this error');
44
+ }
45
+ catch (error) {
46
+ expect(error).toBeInstanceOf(DOMException);
47
+ expect(error.name).toBe('NotAllowedError');
48
+ expect(error.message).toBe('The request is not allowed by the user agent or the platform in the current context.');
49
+ }
50
+ }));
51
+ describe('.truncate()', () => {
52
+ test('can truncate file', () => __awaiter(void 0, void 0, void 0, function* () {
53
+ const { dir, fs } = setup({
54
+ 'file.txt': '012345',
55
+ });
56
+ const entry = yield dir.getFileHandle('file.txt');
57
+ const writable = yield entry.createWritable({ keepExistingData: true });
58
+ yield writable.truncate(3);
59
+ yield writable.close();
60
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('012');
61
+ }));
62
+ test('can truncate file - 2', () => __awaiter(void 0, void 0, void 0, function* () {
63
+ const { dir, fs } = setup({
64
+ 'file.txt': '012345',
65
+ });
66
+ const entry = yield dir.getFileHandle('file.txt');
67
+ const writable = yield entry.createWritable({ keepExistingData: true });
68
+ yield writable.write({ type: 'truncate', size: 3 });
69
+ yield writable.close();
70
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('012');
71
+ }));
72
+ test('can truncate up', () => __awaiter(void 0, void 0, void 0, function* () {
73
+ const { dir, fs } = setup({
74
+ 'file.txt': '012345',
75
+ });
76
+ const entry = yield dir.getFileHandle('file.txt');
77
+ const writable = yield entry.createWritable({ keepExistingData: true });
78
+ yield writable.write({ type: 'truncate', size: 10 });
79
+ yield writable.close();
80
+ expect(fs.readFileSync('/file.txt').length).toBe(10);
81
+ expect(fs.readFileSync('/file.txt')[8]).toBe(0);
82
+ }));
83
+ test('on up truncation bytes are nulled', () => __awaiter(void 0, void 0, void 0, function* () {
84
+ const { dir, fs } = setup({
85
+ 'file.txt': '012345',
86
+ });
87
+ const entry = yield dir.getFileHandle('file.txt');
88
+ const writable = yield entry.createWritable({ keepExistingData: true });
89
+ yield writable.write({ type: 'truncate', size: 10 });
90
+ yield writable.close();
91
+ expect(fs.readFileSync('/file.txt')[8]).toBe(0);
92
+ }));
93
+ });
94
+ describe('.write(chunk)', () => {
95
+ test('overwrites the file when write is being executed', () => __awaiter(void 0, void 0, void 0, function* () {
96
+ const { dir, fs } = setup({
97
+ 'file.txt': 'Hello, world!',
98
+ });
99
+ const entry = yield dir.getFileHandle('file.txt');
100
+ const writable = yield entry.createWritable();
101
+ yield writable.write('...');
102
+ yield writable.close();
103
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('...');
104
+ }));
105
+ test('writes at file start', () => __awaiter(void 0, void 0, void 0, function* () {
106
+ const { dir, fs } = setup({
107
+ 'file.txt': '...',
108
+ });
109
+ const entry = yield dir.getFileHandle('file.txt');
110
+ const writable = yield entry.createWritable({ keepExistingData: true });
111
+ yield writable.write('1');
112
+ yield writable.close();
113
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('1..');
114
+ }));
115
+ test('can seek and then write', () => __awaiter(void 0, void 0, void 0, function* () {
116
+ const { dir, fs } = setup({
117
+ 'file.txt': '...',
118
+ });
119
+ const entry = yield dir.getFileHandle('file.txt');
120
+ const writable = yield entry.createWritable({ keepExistingData: true });
121
+ writable.seek(1);
122
+ yield writable.write('1');
123
+ yield writable.write('2');
124
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('...');
125
+ yield writable.close();
126
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('.12');
127
+ }));
128
+ test('does not commit changes before .close() is called', () => __awaiter(void 0, void 0, void 0, function* () {
129
+ const { dir, fs } = setup({
130
+ 'file.txt': '...',
131
+ });
132
+ const entry = yield dir.getFileHandle('file.txt');
133
+ const writable = yield entry.createWritable();
134
+ yield writable.write('1');
135
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('...');
136
+ yield writable.close();
137
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('1');
138
+ }));
139
+ test('does not commit changes if .abort() is called and removes the swap file', () => __awaiter(void 0, void 0, void 0, function* () {
140
+ const { dir, fs } = setup({
141
+ 'file.txt': '...',
142
+ });
143
+ const entry = yield dir.getFileHandle('file.txt');
144
+ const writable = yield entry.createWritable();
145
+ yield writable.write('1');
146
+ expect(fs.__vol.toJSON()).toStrictEqual({
147
+ '/file.txt': '...',
148
+ '/file.txt.crswap': '1',
149
+ });
150
+ yield writable.abort();
151
+ expect(fs.__vol.toJSON()).toStrictEqual({
152
+ '/file.txt': '...',
153
+ });
154
+ }));
155
+ });
156
+ describe('.write(options)', () => {
157
+ test('can write at offset, when providing position in write call', () => __awaiter(void 0, void 0, void 0, function* () {
158
+ const { dir, fs } = setup({
159
+ 'file.txt': '...',
160
+ });
161
+ const entry = yield dir.getFileHandle('file.txt');
162
+ const writable = yield entry.createWritable({ keepExistingData: true });
163
+ yield writable.write({ type: 'write', position: 1, data: '1' });
164
+ yield writable.close();
165
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('.1.');
166
+ }));
167
+ test('can seek and then write', () => __awaiter(void 0, void 0, void 0, function* () {
168
+ const { dir, fs } = setup({
169
+ 'file.txt': '...',
170
+ });
171
+ const entry = yield dir.getFileHandle('file.txt');
172
+ const writable = yield entry.createWritable({ keepExistingData: true });
173
+ yield writable.write({ type: 'seek', position: 1 });
174
+ yield writable.write({ type: 'write', data: Buffer.from('1') });
175
+ yield writable.close();
176
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('.1.');
177
+ }));
178
+ test('can seek and then write', () => __awaiter(void 0, void 0, void 0, function* () {
179
+ const { dir, fs } = setup({
180
+ 'file.txt': '...',
181
+ });
182
+ const entry = yield dir.getFileHandle('file.txt');
183
+ const writable = yield entry.createWritable({ keepExistingData: true });
184
+ yield writable.write({ type: 'seek', position: 1 });
185
+ yield writable.write({ type: 'write', data: Buffer.from('1') });
186
+ yield writable.close();
187
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('.1.');
188
+ }));
189
+ });
190
+ });
191
+ });
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const __1 = require("../..");
13
+ const NodeFileSystemDirectoryHandle_1 = require("../NodeFileSystemDirectoryHandle");
14
+ const util_1 = require("../../__tests__/util");
15
+ const setup = (json = {}) => {
16
+ const fs = (0, __1.memfs)(json, '/');
17
+ const dir = new NodeFileSystemDirectoryHandle_1.NodeFileSystemDirectoryHandle(fs, '/', { mode: 'readwrite' });
18
+ return { dir, fs };
19
+ };
20
+ (0, util_1.onlyOnNode20)('NodeFileSystemHandle', () => {
21
+ test('can instantiate', () => {
22
+ const { dir } = setup();
23
+ expect(dir).toBeInstanceOf(NodeFileSystemDirectoryHandle_1.NodeFileSystemDirectoryHandle);
24
+ });
25
+ describe('.isSameEntry()', () => {
26
+ test('returns true for the same root entry', () => __awaiter(void 0, void 0, void 0, function* () {
27
+ const { dir } = setup();
28
+ expect(dir.isSameEntry(dir)).toBe(true);
29
+ }));
30
+ test('returns true for two different instances of the same entry', () => __awaiter(void 0, void 0, void 0, function* () {
31
+ const { dir } = setup({
32
+ subdir: null,
33
+ });
34
+ const subdir = yield dir.getDirectoryHandle('subdir');
35
+ expect(subdir.isSameEntry(subdir)).toBe(true);
36
+ expect(dir.isSameEntry(dir)).toBe(true);
37
+ expect(dir.isSameEntry(subdir)).toBe(false);
38
+ expect(subdir.isSameEntry(dir)).toBe(false);
39
+ }));
40
+ test('returns false when comparing file with a directory', () => __awaiter(void 0, void 0, void 0, function* () {
41
+ const { dir } = setup({
42
+ file: 'lala',
43
+ });
44
+ const file = yield dir.getFileHandle('file');
45
+ expect(file.isSameEntry(dir)).toBe(false);
46
+ expect(dir.isSameEntry(file)).toBe(false);
47
+ }));
48
+ });
49
+ });
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const __1 = require("../..");
13
+ const NodeFileSystemDirectoryHandle_1 = require("../NodeFileSystemDirectoryHandle");
14
+ const NodeFileSystemSyncAccessHandle_1 = require("../NodeFileSystemSyncAccessHandle");
15
+ const util_1 = require("../../__tests__/util");
16
+ const setup = (json = {}) => {
17
+ const fs = (0, __1.memfs)(json, '/');
18
+ const dir = new NodeFileSystemDirectoryHandle_1.NodeFileSystemDirectoryHandle(fs, '/', { syncHandleAllowed: true, mode: 'readwrite' });
19
+ return { dir, fs };
20
+ };
21
+ (0, util_1.onlyOnNode20)('NodeFileSystemSyncAccessHandle', () => {
22
+ describe('.close()', () => {
23
+ test('can close the file', () => __awaiter(void 0, void 0, void 0, function* () {
24
+ const { dir } = setup({
25
+ 'file.txt': 'Hello, world!',
26
+ });
27
+ const entry = yield dir.getFileHandle('file.txt');
28
+ const sync = yield entry.createSyncAccessHandle();
29
+ expect(sync).toBeInstanceOf(NodeFileSystemSyncAccessHandle_1.NodeFileSystemSyncAccessHandle);
30
+ yield sync.close();
31
+ // ...
32
+ }));
33
+ });
34
+ describe('.flush()', () => {
35
+ test('can flush', () => __awaiter(void 0, void 0, void 0, function* () {
36
+ const { dir } = setup({
37
+ 'file.txt': 'Hello, world!',
38
+ });
39
+ const entry = yield dir.getFileHandle('file.txt');
40
+ const sync = yield entry.createSyncAccessHandle();
41
+ yield sync.flush();
42
+ }));
43
+ });
44
+ describe('.getSize()', () => {
45
+ test('can get file size', () => __awaiter(void 0, void 0, void 0, function* () {
46
+ const { dir } = setup({
47
+ 'file.txt': 'Hello, world!',
48
+ });
49
+ const entry = yield dir.getFileHandle('file.txt');
50
+ const sync = yield entry.createSyncAccessHandle();
51
+ const size = yield sync.getSize();
52
+ expect(size).toBe(13);
53
+ }));
54
+ });
55
+ describe('.getSize()', () => {
56
+ test('can get file size', () => __awaiter(void 0, void 0, void 0, function* () {
57
+ const { dir } = setup({
58
+ 'file.txt': 'Hello, world!',
59
+ });
60
+ const entry = yield dir.getFileHandle('file.txt');
61
+ const sync = yield entry.createSyncAccessHandle();
62
+ const size = yield sync.getSize();
63
+ expect(size).toBe(13);
64
+ }));
65
+ });
66
+ describe('.read()', () => {
67
+ test('can read from beginning', () => __awaiter(void 0, void 0, void 0, function* () {
68
+ const { dir } = setup({
69
+ 'file.txt': '0123456789',
70
+ });
71
+ const entry = yield dir.getFileHandle('file.txt');
72
+ const sync = yield entry.createSyncAccessHandle();
73
+ const buf = new Uint8Array(5);
74
+ const size = yield sync.read(buf);
75
+ expect(size).toBe(5);
76
+ expect(Buffer.from(buf).toString()).toBe('01234');
77
+ }));
78
+ test('can read at offset', () => __awaiter(void 0, void 0, void 0, function* () {
79
+ const { dir } = setup({
80
+ 'file.txt': '0123456789',
81
+ });
82
+ const entry = yield dir.getFileHandle('file.txt');
83
+ const sync = yield entry.createSyncAccessHandle();
84
+ const buf = new Uint8Array(3);
85
+ const size = yield sync.read(buf, { at: 3 });
86
+ expect(size).toBe(3);
87
+ expect(Buffer.from(buf).toString()).toBe('345');
88
+ }));
89
+ test('can read into buffer larger than file', () => __awaiter(void 0, void 0, void 0, function* () {
90
+ const { dir } = setup({
91
+ 'file.txt': '0123456789',
92
+ });
93
+ const entry = yield dir.getFileHandle('file.txt');
94
+ const sync = yield entry.createSyncAccessHandle();
95
+ const buf = new Uint8Array(25);
96
+ const size = yield sync.read(buf);
97
+ expect(size).toBe(10);
98
+ expect(Buffer.from(buf).slice(0, 10).toString()).toBe('0123456789');
99
+ }));
100
+ test('throws "InvalidStateError" DOMException if handle is closed', () => __awaiter(void 0, void 0, void 0, function* () {
101
+ const { dir } = setup({
102
+ 'file.txt': '0123456789',
103
+ });
104
+ const entry = yield dir.getFileHandle('file.txt');
105
+ const sync = yield entry.createSyncAccessHandle();
106
+ yield sync.close();
107
+ const buf = new Uint8Array(25);
108
+ try {
109
+ const size = yield sync.read(buf);
110
+ throw new Error('No error was thrown');
111
+ }
112
+ catch (error) {
113
+ expect(error).toBeInstanceOf(DOMException);
114
+ expect(error.name).toBe('InvalidStateError');
115
+ }
116
+ }));
117
+ });
118
+ describe('.truncate()', () => {
119
+ test('can read from beginning', () => __awaiter(void 0, void 0, void 0, function* () {
120
+ const { dir } = setup({
121
+ 'file.txt': '0123456789',
122
+ });
123
+ const entry = yield dir.getFileHandle('file.txt');
124
+ const sync = yield entry.createSyncAccessHandle();
125
+ const res = yield sync.truncate(5);
126
+ expect(res).toBe(undefined);
127
+ }));
128
+ });
129
+ describe('.write()', () => {
130
+ test('can write to the file', () => __awaiter(void 0, void 0, void 0, function* () {
131
+ const { dir, fs } = setup({
132
+ 'file.txt': '0123456789',
133
+ });
134
+ const entry = yield dir.getFileHandle('file.txt');
135
+ const sync = yield entry.createSyncAccessHandle();
136
+ const res = yield sync.write(Buffer.from('Hello'));
137
+ expect(res).toBe(5);
138
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('Hello56789');
139
+ }));
140
+ test('can write at an offset', () => __awaiter(void 0, void 0, void 0, function* () {
141
+ const { dir, fs } = setup({
142
+ 'file.txt': '0123456789',
143
+ });
144
+ const entry = yield dir.getFileHandle('file.txt');
145
+ const sync = yield entry.createSyncAccessHandle();
146
+ const res = yield sync.write(Buffer.from('Hello'), { at: 7 });
147
+ expect(res).toBe(5);
148
+ expect(fs.readFileSync('/file.txt', 'utf8')).toBe('0123456Hello');
149
+ }));
150
+ test('throws "InvalidStateError" DOMException if file descriptor is already closed', () => __awaiter(void 0, void 0, void 0, function* () {
151
+ const { dir, fs } = setup({
152
+ 'file.txt': '0123456789',
153
+ });
154
+ const entry = yield dir.getFileHandle('file.txt');
155
+ const sync = yield entry.createSyncAccessHandle();
156
+ yield sync.write(Buffer.from('a'));
157
+ yield sync.close();
158
+ try {
159
+ yield sync.write(Buffer.from('b'));
160
+ throw new Error('No error was thrown');
161
+ }
162
+ catch (error) {
163
+ expect(error).toBeInstanceOf(DOMException);
164
+ expect(error.name).toBe('InvalidStateError');
165
+ }
166
+ }));
167
+ // TODO: Need to find out what is the correct behavior here.
168
+ xtest('writing at offset past file size', () => __awaiter(void 0, void 0, void 0, function* () {
169
+ const { dir, fs } = setup({
170
+ 'file.txt': '0123456789',
171
+ });
172
+ const entry = yield dir.getFileHandle('file.txt');
173
+ const sync = yield entry.createSyncAccessHandle();
174
+ try {
175
+ yield sync.write(Buffer.from('a'), { at: 100 });
176
+ // ?
177
+ }
178
+ catch (error) {
179
+ // ?
180
+ }
181
+ }));
182
+ });
183
+ });
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const __1 = require("../..");
13
+ const FileHandle_1 = require("../../node/FileHandle");
14
+ const NodeFileSystemWritableFileStream_1 = require("../NodeFileSystemWritableFileStream");
15
+ describe('createSwapFile()', () => {
16
+ test('can create a swap file', () => __awaiter(void 0, void 0, void 0, function* () {
17
+ const fs = (0, __1.memfs)({
18
+ '/file.txt': 'Hello, world!',
19
+ }, '/');
20
+ const [handle, path] = yield (0, NodeFileSystemWritableFileStream_1.createSwapFile)(fs, '/file.txt', false);
21
+ expect(handle).toBeInstanceOf(FileHandle_1.FileHandle);
22
+ expect(path).toBe('/file.txt.crswap');
23
+ expect(fs.__vol.toJSON()).toStrictEqual({
24
+ '/file.txt': 'Hello, world!',
25
+ '/file.txt.crswap': '',
26
+ });
27
+ }));
28
+ test('can create a swap file at subfolder', () => __awaiter(void 0, void 0, void 0, function* () {
29
+ const fs = (0, __1.memfs)({
30
+ '/foo/file.txt': 'Hello, world!',
31
+ }, '/');
32
+ const [handle, path] = yield (0, NodeFileSystemWritableFileStream_1.createSwapFile)(fs, '/foo/file.txt', false);
33
+ expect(handle).toBeInstanceOf(FileHandle_1.FileHandle);
34
+ expect(path).toBe('/foo/file.txt.crswap');
35
+ expect(fs.__vol.toJSON()).toStrictEqual({
36
+ '/foo/file.txt': 'Hello, world!',
37
+ '/foo/file.txt.crswap': '',
38
+ });
39
+ }));
40
+ test('can create a swap file when the default swap file name is in use', () => __awaiter(void 0, void 0, void 0, function* () {
41
+ const fs = (0, __1.memfs)({
42
+ '/foo/file.txt': 'Hello, world!',
43
+ '/foo/file.txt.crswap': 'lala',
44
+ }, '/');
45
+ const [handle, path] = yield (0, NodeFileSystemWritableFileStream_1.createSwapFile)(fs, '/foo/file.txt', false);
46
+ expect(handle).toBeInstanceOf(FileHandle_1.FileHandle);
47
+ expect(path).toBe('/foo/file.txt.1.crswap');
48
+ expect(fs.__vol.toJSON()).toStrictEqual({
49
+ '/foo/file.txt': 'Hello, world!',
50
+ '/foo/file.txt.crswap': 'lala',
51
+ '/foo/file.txt.1.crswap': '',
52
+ });
53
+ }));
54
+ test('can create a swap file when the first two names are already taken', () => __awaiter(void 0, void 0, void 0, function* () {
55
+ const fs = (0, __1.memfs)({
56
+ '/foo/file.txt': 'Hello, world!',
57
+ '/foo/file.txt.crswap': 'lala',
58
+ '/foo/file.txt.1.crswap': 'blah',
59
+ }, '/');
60
+ const [handle, path] = yield (0, NodeFileSystemWritableFileStream_1.createSwapFile)(fs, '/foo/file.txt', false);
61
+ expect(handle).toBeInstanceOf(FileHandle_1.FileHandle);
62
+ expect(path).toBe('/foo/file.txt.2.crswap');
63
+ expect(fs.__vol.toJSON()).toStrictEqual({
64
+ '/foo/file.txt': 'Hello, world!',
65
+ '/foo/file.txt.crswap': 'lala',
66
+ '/foo/file.txt.1.crswap': 'blah',
67
+ '/foo/file.txt.2.crswap': '',
68
+ });
69
+ }));
70
+ test('can create a swap file when the first three names are already taken', () => __awaiter(void 0, void 0, void 0, function* () {
71
+ const fs = (0, __1.memfs)({
72
+ '/foo/file.txt': 'Hello, world!',
73
+ '/foo/file.txt.crswap': 'lala',
74
+ '/foo/file.txt.1.crswap': 'blah',
75
+ '/foo/file.txt.2.crswap': 'brawo',
76
+ }, '/');
77
+ const [handle, path] = yield (0, NodeFileSystemWritableFileStream_1.createSwapFile)(fs, '/foo/file.txt', false);
78
+ expect(handle).toBeInstanceOf(FileHandle_1.FileHandle);
79
+ expect(path).toBe('/foo/file.txt.3.crswap');
80
+ expect(fs.__vol.toJSON()).toStrictEqual({
81
+ '/foo/file.txt': 'Hello, world!',
82
+ '/foo/file.txt.crswap': 'lala',
83
+ '/foo/file.txt.1.crswap': 'blah',
84
+ '/foo/file.txt.2.crswap': 'brawo',
85
+ '/foo/file.txt.3.crswap': '',
86
+ });
87
+ }));
88
+ test('can copy existing data into the swap file', () => __awaiter(void 0, void 0, void 0, function* () {
89
+ const fs = (0, __1.memfs)({
90
+ '/foo/file.txt': 'Hello, world!',
91
+ '/foo/file.txt.crswap': 'lala',
92
+ '/foo/file.txt.1.crswap': 'blah',
93
+ '/foo/file.txt.2.crswap': 'brawo',
94
+ }, '/');
95
+ const [handle, path] = yield (0, NodeFileSystemWritableFileStream_1.createSwapFile)(fs, '/foo/file.txt', true);
96
+ expect(handle).toBeInstanceOf(FileHandle_1.FileHandle);
97
+ expect(path).toBe('/foo/file.txt.3.crswap');
98
+ expect(fs.__vol.toJSON()).toStrictEqual({
99
+ '/foo/file.txt': 'Hello, world!',
100
+ '/foo/file.txt.crswap': 'lala',
101
+ '/foo/file.txt.1.crswap': 'blah',
102
+ '/foo/file.txt.2.crswap': 'brawo',
103
+ '/foo/file.txt.3.crswap': 'Hello, world!',
104
+ });
105
+ }));
106
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const __1 = require("..");
13
+ const __2 = require("../..");
14
+ const util_1 = require("../../__tests__/util");
15
+ (0, util_1.onlyOnNode20)('scenarios', () => {
16
+ test('can init FSA from an arbitrary FS folder and execute operations', () => __awaiter(void 0, void 0, void 0, function* () {
17
+ const fs = (0, __2.memfs)({
18
+ '/tmp': null,
19
+ '/etc': null,
20
+ '/bin': null,
21
+ '/Users/kasper/Documents/shopping-list.txt': 'Milk, Eggs, Bread',
22
+ });
23
+ const dir = (0, __1.nodeToFsa)(fs, '/Users/kasper/Documents', { mode: 'readwrite' });
24
+ const shoppingListFile = yield dir.getFileHandle('shopping-list.txt');
25
+ const shoppingList = yield shoppingListFile.getFile();
26
+ expect(yield shoppingList.text()).toBe('Milk, Eggs, Bread');
27
+ const backupsDir = yield dir.getDirectoryHandle('backups', { create: true });
28
+ const backupFile = yield backupsDir.getFileHandle('shopping-list.txt', { create: true });
29
+ const writable = yield backupFile.createWritable();
30
+ yield writable.write(yield shoppingList.arrayBuffer());
31
+ yield writable.close();
32
+ const logsFileHandle = yield dir.getFileHandle('logs.csv', { create: true });
33
+ const logsWritable = yield logsFileHandle.createWritable();
34
+ yield logsWritable.write('timestamp,level,message\n');
35
+ yield logsWritable.write({ type: 'write', data: '2021-01-01T00:00:00Z,INFO,Hello World\n' });
36
+ yield logsWritable.close();
37
+ expect(fs.__vol.toJSON()).toStrictEqual({
38
+ '/tmp': null,
39
+ '/etc': null,
40
+ '/bin': null,
41
+ '/Users/kasper/Documents/shopping-list.txt': 'Milk, Eggs, Bread',
42
+ '/Users/kasper/Documents/backups/shopping-list.txt': 'Milk, Eggs, Bread',
43
+ '/Users/kasper/Documents/logs.csv': 'timestamp,level,message\n2021-01-01T00:00:00Z,INFO,Hello World\n',
44
+ });
45
+ }));
46
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const util_1 = require("../util");
4
+ describe('basename()', () => {
5
+ test('handles empty string', () => {
6
+ expect((0, util_1.basename)('', '/')).toBe('');
7
+ });
8
+ test('return the same string if there is no nesting', () => {
9
+ expect((0, util_1.basename)('scary.exe', '/')).toBe('scary.exe');
10
+ });
11
+ test('returns last step in path', () => {
12
+ expect((0, util_1.basename)('/gg/wp/hf/gl.txt', '/')).toBe('gl.txt');
13
+ expect((0, util_1.basename)('gg/wp/hf/gl.txt', '/')).toBe('gl.txt');
14
+ expect((0, util_1.basename)('/wp/hf/gl.txt', '/')).toBe('gl.txt');
15
+ expect((0, util_1.basename)('wp/hf/gl.txt', '/')).toBe('gl.txt');
16
+ expect((0, util_1.basename)('/hf/gl.txt', '/')).toBe('gl.txt');
17
+ expect((0, util_1.basename)('hf/gl.txt', '/')).toBe('gl.txt');
18
+ expect((0, util_1.basename)('/gl.txt', '/')).toBe('gl.txt');
19
+ expect((0, util_1.basename)('gl.txt', '/')).toBe('gl.txt');
20
+ });
21
+ test('handles double slashes', () => {
22
+ expect((0, util_1.basename)('/gg/wp/hf//gl.txt', '/')).toBe('gl.txt');
23
+ expect((0, util_1.basename)('//gl.txt', '/')).toBe('gl.txt');
24
+ });
25
+ });
@@ -0,0 +1,7 @@
1
+ import { NodeFileSystemDirectoryHandle } from './NodeFileSystemDirectoryHandle';
2
+ import { NodeFsaContext, NodeFsaFs } from './types';
3
+ export * from './types';
4
+ export * from './NodeFileSystemHandle';
5
+ export * from './NodeFileSystemDirectoryHandle';
6
+ export * from './NodeFileSystemFileHandle';
7
+ export declare const nodeToFsa: (fs: NodeFsaFs, dirPath: string, ctx?: Partial<NodeFsaContext>) => NodeFileSystemDirectoryHandle;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.nodeToFsa = void 0;
18
+ const NodeFileSystemDirectoryHandle_1 = require("./NodeFileSystemDirectoryHandle");
19
+ __exportStar(require("./types"), exports);
20
+ __exportStar(require("./NodeFileSystemHandle"), exports);
21
+ __exportStar(require("./NodeFileSystemDirectoryHandle"), exports);
22
+ __exportStar(require("./NodeFileSystemFileHandle"), exports);
23
+ const nodeToFsa = (fs, dirPath, ctx) => {
24
+ return new NodeFileSystemDirectoryHandle_1.NodeFileSystemDirectoryHandle(fs, dirPath, ctx);
25
+ };
26
+ exports.nodeToFsa = nodeToFsa;