@spinajs/fs 2.0.180 → 2.0.181

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 (73) hide show
  1. package/lib/cjs/cli/rm.d.ts +11 -11
  2. package/lib/cjs/cli/rm.js +28 -28
  3. package/lib/cjs/cli/rm.js.map +1 -1
  4. package/lib/cjs/cli/stat.d.ts +10 -10
  5. package/lib/cjs/cli/stat.js +26 -26
  6. package/lib/cjs/cli/stat.js.map +1 -1
  7. package/lib/cjs/config/fs.d.ts +33 -16
  8. package/lib/cjs/config/fs.d.ts.map +1 -1
  9. package/lib/cjs/config/fs.js +50 -36
  10. package/lib/cjs/config/fs.js.map +1 -1
  11. package/lib/cjs/decorators.d.ts +7 -7
  12. package/lib/cjs/decorators.js +23 -23
  13. package/lib/cjs/file-hasher.d.ts +12 -8
  14. package/lib/cjs/file-hasher.d.ts.map +1 -1
  15. package/lib/cjs/file-hasher.js +51 -42
  16. package/lib/cjs/file-hasher.js.map +1 -1
  17. package/lib/cjs/file-info.d.ts +10 -10
  18. package/lib/cjs/file-info.js +124 -124
  19. package/lib/cjs/file-info.js.map +1 -1
  20. package/lib/cjs/index.d.ts +10 -10
  21. package/lib/cjs/index.d.ts.map +1 -1
  22. package/lib/cjs/index.js +72 -71
  23. package/lib/cjs/index.js.map +1 -1
  24. package/lib/cjs/interfaces.d.ts +180 -157
  25. package/lib/cjs/interfaces.d.ts.map +1 -1
  26. package/lib/cjs/interfaces.js +44 -33
  27. package/lib/cjs/interfaces.js.map +1 -1
  28. package/lib/cjs/local-provider.d.ts +96 -100
  29. package/lib/cjs/local-provider.d.ts.map +1 -1
  30. package/lib/cjs/local-provider.js +321 -278
  31. package/lib/cjs/local-provider.js.map +1 -1
  32. package/lib/cjs/local-temp-provider.d.ts +18 -18
  33. package/lib/cjs/local-temp-provider.d.ts.map +1 -1
  34. package/lib/cjs/local-temp-provider.js +59 -54
  35. package/lib/cjs/local-temp-provider.js.map +1 -1
  36. package/lib/mjs/cli/rm.d.ts +11 -11
  37. package/lib/mjs/cli/rm.js +25 -25
  38. package/lib/mjs/cli/rm.js.map +1 -1
  39. package/lib/mjs/cli/stat.d.ts +10 -10
  40. package/lib/mjs/cli/stat.js +23 -23
  41. package/lib/mjs/cli/stat.js.map +1 -1
  42. package/lib/mjs/config/fs.d.ts +33 -16
  43. package/lib/mjs/config/fs.d.ts.map +1 -1
  44. package/lib/mjs/config/fs.js +48 -34
  45. package/lib/mjs/config/fs.js.map +1 -1
  46. package/lib/mjs/decorators.d.ts +7 -7
  47. package/lib/mjs/decorators.js +19 -19
  48. package/lib/mjs/file-hasher.d.ts +12 -8
  49. package/lib/mjs/file-hasher.d.ts.map +1 -1
  50. package/lib/mjs/file-hasher.js +45 -36
  51. package/lib/mjs/file-hasher.js.map +1 -1
  52. package/lib/mjs/file-info.d.ts +10 -10
  53. package/lib/mjs/file-info.js +121 -121
  54. package/lib/mjs/file-info.js.map +1 -1
  55. package/lib/mjs/index.d.ts +10 -10
  56. package/lib/mjs/index.d.ts.map +1 -1
  57. package/lib/mjs/index.js +55 -54
  58. package/lib/mjs/index.js.map +1 -1
  59. package/lib/mjs/interfaces.d.ts +180 -157
  60. package/lib/mjs/interfaces.d.ts.map +1 -1
  61. package/lib/mjs/interfaces.js +38 -27
  62. package/lib/mjs/interfaces.js.map +1 -1
  63. package/lib/mjs/local-provider.d.ts +96 -100
  64. package/lib/mjs/local-provider.d.ts.map +1 -1
  65. package/lib/mjs/local-provider.js +315 -272
  66. package/lib/mjs/local-provider.js.map +1 -1
  67. package/lib/mjs/local-temp-provider.d.ts +18 -18
  68. package/lib/mjs/local-temp-provider.d.ts.map +1 -1
  69. package/lib/mjs/local-temp-provider.js +56 -51
  70. package/lib/mjs/local-temp-provider.js.map +1 -1
  71. package/lib/tsconfig.cjs.tsbuildinfo +1 -1
  72. package/lib/tsconfig.mjs.tsbuildinfo +1 -1
  73. package/package.json +6 -2
@@ -1 +1 @@
1
- {"version":3,"file":"local-provider.d.ts","sourceRoot":"","sources":["../../src/local-provider.ts"],"names":[],"mappings":";;AAEA,OAAO,EAQL,UAAU,EACX,MAAM,IAAI,CAAC;AAIZ,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,GAAG,EAAU,MAAM,qBAAqB,CAAC;AAIlD;;;;;;;;GAQG;AACH,qBAEa,QAAQ,CAAC,CAAC,SAAS,eAAe,CAAE,SAAQ,EAAE;IAYtC,OAAO,EAAE,CAAC;IAV7B,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;IAEtB;;;OAGG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;gBAEkB,OAAO,EAAE,CAAC;IAIhB,OAAO;IAepB;;;;;;OAMG;IACU,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASvC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAStD;;OAEG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc;IAYlD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc;IAIzD;;OAEG;IACU,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,cAAc;IAKnE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3F,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU,EAAE,QAAQ,CAAC,EAAE,cAAc;IAQjG;;;OAGG;IACU,MAAM,CAAC,IAAI,EAAE,MAAM;IASnB,SAAS,CAAC,IAAI,EAAE,MAAM;IAInC;;;;OAIG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAI5C;;OAEG;IACU,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAgBlD;;OAEG;IACU,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAIpD;;;;;OAKG;IACU,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO;IASpD;;;;;OAKG;IACU,EAAE,CAAC,IAAI,EAAE,MAAM;IAI5B;;;;;OAKG;IACU,KAAK,CAAC,IAAI,EAAE,MAAM;IAI/B;;OAEG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAaxC,OAAO,IAAI,MAAM;IAIxB;;;;OAIG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM;IAIjB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAapC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAqC5D,WAAW,CAAC,IAAI,EAAE,MAAM;CAOhC"}
1
+ {"version":3,"file":"local-provider.d.ts","sourceRoot":"","sources":["../../src/local-provider.ts"],"names":[],"mappings":";;;AAEA,OAAO,EAAsF,UAAU,EAAE,MAAM,IAAI,CAAC;AAIpH,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,GAAG,EAAU,MAAM,qBAAqB,CAAC;AAMlD;;;;;;;;GAQG;AACH,qBAEa,QAAQ,CAAC,CAAC,SAAS,eAAe,CAAE,SAAQ,EAAE;IAYtC,OAAO,EAAE,CAAC;IAV7B,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;IAEtB;;;OAGG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;gBAEkB,OAAO,EAAE,CAAC;IAIhB,OAAO;IAgBpB;;;;;;OAMG;IACU,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASvC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAStD;;OAEG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc;IAYlD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc;IAIzD;;OAEG;IACU,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,cAAc;IAgBnE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3F,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,cAAc;IAYxG;;;OAGG;IACU,MAAM,CAAC,IAAI,EAAE,MAAM;IASnB,SAAS,CAAC,IAAI,EAAE,MAAM;IAInC;;;;OAIG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE;IAkBxD;;OAEG;IACU,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE;IAY9D;;OAEG;IACU,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAIpD;;;;;;OAMG;IACU,EAAE,CAAC,IAAI,EAAE,MAAM;IAI5B;;;;;OAKG;IACU,KAAK,CAAC,IAAI,EAAE,MAAM;IAI/B;;OAEG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAaxC,OAAO,IAAI,MAAM;IAIxB;;;;OAIG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM;IAIjB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE;IAgBjD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASrC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAgErF,WAAW,CAAC,IAAI,EAAE,MAAM;CAIhC"}
@@ -1,273 +1,316 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- /* eslint-disable security/detect-non-literal-fs-filename */
11
- import { IOFail } from '@spinajs/exceptions';
12
- import { constants, copyFileSync, createReadStream, createWriteStream, existsSync, readFile, readFileSync, } from 'fs';
13
- import { unlink, rm, stat, readdir, rename, mkdir, copyFile, access, open, appendFile } from 'node:fs/promises';
14
- import { DateTime } from 'luxon';
15
- import { DI, Injectable, PerInstanceCheck } from '@spinajs/di';
16
- import { fs } from './interfaces.js';
17
- import { basename, join } from 'path';
18
- import { Log, Logger } from '@spinajs/log-common';
19
- import archiver from 'archiver';
20
- import unzipper from 'unzipper';
21
- /**
22
- * Abstract layer for file operations.
23
- * Basic implementation is just wrapper for native node fs functions
24
- *
25
- * It allows to wrap other libs eg. aws s3, ftp
26
- * and inject it into code without changing logic that use them.
27
- *
28
- * TODO: map errors to some kind of common errors shared with other implementations
29
- */
30
- let fsNative = class fsNative extends fs {
31
- /**
32
- * Name of provider. We can have multiple providers of the same type but with different options.
33
- * Also used in InjectService decorator for mapping
34
- */
35
- get Name() {
36
- return this.Options.name;
37
- }
38
- constructor(Options) {
39
- super();
40
- this.Options = Options;
41
- }
42
- async resolve() {
43
- // yup, exceptions as conditional execution path is bad :)
44
- try {
45
- await access(this.Options.basePath, constants.F_OK);
46
- }
47
- catch {
48
- this.Logger.warn(`Base path ${this.Options.basePath} for file provider ${this.Options.name} not exists, trying to create base folder`);
49
- await mkdir(this.Options.basePath, { recursive: true });
50
- this.Logger.success(`Base path ${this.Options.basePath} created`);
51
- }
52
- }
53
- /**
54
- *
55
- * Tries to download file to local filesystem, then returns local filesystem path.
56
- * Native implementation simply returns local path and does nothing.
57
- *
58
- * @param path - file to download
59
- */
60
- async download(path) {
61
- const p = this.resolvePath(path);
62
- const exists = await this.exists(path);
63
- if (!exists) {
64
- throw new IOFail(`file ${p} does not exists`);
65
- }
66
- return p;
67
- }
68
- async upload(srcPath, destPath) {
69
- if (!existsSync(srcPath)) {
70
- throw new IOFail(`file ${srcPath} does not exists`);
71
- }
72
- const dPath = this.resolvePath(destPath ?? basename(srcPath));
73
- copyFileSync(srcPath, dPath);
74
- }
75
- /**
76
- * read all content of file
77
- */
78
- async read(path, encoding) {
79
- return new Promise((resolve, reject) => {
80
- readFile(this.resolvePath(path), { encoding: encoding ?? 'binary' }, (err, data) => {
81
- if (err) {
82
- reject(err);
83
- }
84
- else {
85
- resolve(data);
86
- }
87
- });
88
- });
89
- }
90
- readStream(path, encoding) {
91
- return Promise.resolve(createReadStream(this.resolvePath(path), { encoding: encoding ?? 'binary' }));
92
- }
93
- /**
94
- * Write to file string or buffer
95
- */
96
- async write(path, data, encoding) {
97
- const fDesc = await open(this.resolvePath(path), 'w');
98
- return await fDesc.writeFile(data, { encoding });
99
- }
100
- async append(path, data, encoding) {
101
- await appendFile(path, data, encoding);
102
- }
103
- writeStream(path, rStream, encoding) {
104
- return Promise.resolve(createWriteStream(this.resolvePath(path), {
105
- encoding: (typeof rStream === 'string' ? rStream : encoding) ?? 'binary',
106
- }));
107
- }
108
- /**
109
- * Checks if file existst
110
- * @param path - path to check
111
- */
112
- async exists(path) {
113
- try {
114
- await access(this.resolvePath(path), constants.F_OK);
115
- return true;
116
- }
117
- catch {
118
- return false;
119
- }
120
- }
121
- async dirExists(path) {
122
- return this.exists(this.resolvePath(path));
123
- }
124
- /**
125
- * Copy file to another location
126
- * @param path - src path
127
- * @param dest - dest path
128
- */
129
- async copy(path, dest) {
130
- await copyFile(this.resolvePath(path), this.resolvePath(dest));
131
- }
132
- /**
133
- * Copy file to another location and deletes src file
134
- */
135
- async move(oldPath, newPath) {
136
- const oPath = this.resolvePath(oldPath);
137
- const nPath = this.resolvePath(newPath);
138
- try {
139
- await rename(oPath, nPath);
140
- }
141
- catch (err) {
142
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
143
- if (err.code === 'EXDEV') {
144
- await copyFile(oPath, nPath);
145
- await unlink(oPath);
146
- }
147
- else {
148
- throw err;
149
- }
150
- }
151
- }
152
- /**
153
- * Change name of a file
154
- */
155
- async rename(oldPath, newPath) {
156
- await rename(this.resolvePath(oldPath), this.resolvePath(newPath));
157
- }
158
- /**
159
- * Deletes file permanently
160
- *
161
- * @param path - path to file that will be deleted
162
- * @param onlyTemp - remote filesystems need to download file before, if so, calling unlink with this flag removes only local temp file after we finished processing
163
- */
164
- async unlink(path, onlyTemp) {
165
- // local fs returns only local path to file, we dont want to delete it
166
- if (onlyTemp) {
167
- return;
168
- }
169
- await unlink(this.resolvePath(path));
170
- }
171
- /**
172
- *
173
- * Deletes dir recursively & all contents inside
174
- *
175
- * @param path - dir to remove
176
- */
177
- async rm(path) {
178
- await rm(this.resolvePath(path), { recursive: true, force: true, maxRetries: 3, retryDelay: 1000 });
179
- }
180
- /**
181
- *
182
- * Creates directory, recursively
183
- *
184
- * @param path - directory to create
185
- */
186
- async mkdir(path) {
187
- await mkdir(this.resolvePath(path), { recursive: true });
188
- }
189
- /**
190
- * Returns file statistics, not all fields may be accesible
191
- */
192
- async stat(path) {
193
- const result = await stat(this.resolvePath(path));
194
- return {
195
- IsDirectory: result.isDirectory(),
196
- IsFile: result.isFile(),
197
- CreationTime: DateTime.fromJSDate(result.ctime),
198
- ModifiedTime: DateTime.fromJSDate(result.mtime),
199
- AccessTime: DateTime.fromJSDate(result.atime),
200
- Size: result.size,
201
- };
202
- }
203
- tmppath() {
204
- return join(this.Options.basePath, super.tmpname());
205
- }
206
- /**
207
- * List content of directory
208
- *
209
- * @param path - path to directory
210
- */
211
- async list(path) {
212
- return await readdir(this.resolvePath(path));
213
- }
214
- async unzip(path, destPath) {
215
- return new Promise((resolve, reject) => {
216
- createReadStream(this.resolvePath(path)).pipe(unzipper
217
- .Extract({
218
- path: this.resolvePath(destPath),
219
- })
220
- .on('close', resolve)
221
- .on('error', reject));
222
- });
223
- }
224
- async zip(path, zName) {
225
- const fs = await DI.resolve('__file_provider__', ['fs-temp']);
226
- const outFile = fs.resolvePath(fs.tmpname() + '.zip');
227
- const output = createWriteStream(outFile);
228
- const pStat = await this.stat(path);
229
- const fPath = this.resolvePath(path);
230
- const archive = archiver('zip', {
231
- zlib: { level: 9 }, // Sets the compression level.
232
- });
233
- // pipe archive data to the file
234
- archive.pipe(output);
235
- if (pStat.IsDirectory) {
236
- archive.directory(fPath, false);
237
- }
238
- else {
239
- archive.file(fPath, { name: zName ?? basename(fPath) });
240
- }
241
- await archive.finalize();
242
- return {
243
- asFilePath: () => {
244
- return outFile;
245
- },
246
- asStream: (encoding) => {
247
- return createReadStream(outFile, {
248
- encoding: encoding ?? 'binary',
249
- });
250
- },
251
- asBase64: () => {
252
- return readFileSync(outFile, { encoding: 'base64' });
253
- },
254
- };
255
- }
256
- resolvePath(path) {
257
- if (path.startsWith(this.Options.basePath)) {
258
- return path;
259
- }
260
- return join(this.Options.basePath, path);
261
- }
262
- };
263
- __decorate([
264
- Logger('fs'),
265
- __metadata("design:type", Log)
266
- ], fsNative.prototype, "Logger", void 0);
267
- fsNative = __decorate([
268
- Injectable('fs'),
269
- PerInstanceCheck(),
270
- __metadata("design:paramtypes", [Object])
271
- ], fsNative);
272
- export { fsNative };
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ /* eslint-disable security/detect-non-literal-fs-filename */
11
+ import { IOFail } from '@spinajs/exceptions';
12
+ import { constants, createReadStream, createWriteStream, existsSync, readFile, readFileSync, ReadStream } from 'fs';
13
+ import { rm, stat, readdir, rename, mkdir, access, open, appendFile } from 'node:fs/promises';
14
+ import { DateTime } from 'luxon';
15
+ import { DI, Injectable, PerInstanceCheck } from '@spinajs/di';
16
+ import { fs } from './interfaces.js';
17
+ import { basename, join } from 'path';
18
+ import { Log, Logger } from '@spinajs/log-common';
19
+ import archiver from 'archiver';
20
+ import unzipper from 'unzipper';
21
+ import { cp } from 'fs/promises';
22
+ import { toArray } from '@spinajs/util';
23
+ /**
24
+ * Abstract layer for file operations.
25
+ * Basic implementation is just wrapper for native node fs functions
26
+ *
27
+ * It allows to wrap other libs eg. aws s3, ftp
28
+ * and inject it into code without changing logic that use them.
29
+ *
30
+ * TODO: map errors to some kind of common errors shared with other implementations
31
+ */
32
+ let fsNative = class fsNative extends fs {
33
+ /**
34
+ * Name of provider. We can have multiple providers of the same type but with different options.
35
+ * Also used in InjectService decorator for mapping
36
+ */
37
+ get Name() {
38
+ return this.Options.name;
39
+ }
40
+ constructor(Options) {
41
+ super();
42
+ this.Options = Options;
43
+ }
44
+ async resolve() {
45
+ if (!this.Options.basePath) {
46
+ throw new IOFail(`Base path for file provider ${this.Options.name} not set`);
47
+ }
48
+ if ((await this.exists(this.Options.basePath)) === false) {
49
+ this.Logger.warn(`Base path ${this.Options.basePath} for file provider ${this.Options.name} not exists, trying to create base folder`);
50
+ await mkdir(this.Options.basePath, { recursive: true });
51
+ this.Logger.success(`Base path ${this.Options.basePath} created`);
52
+ }
53
+ }
54
+ /**
55
+ *
56
+ * Tries to download file to local filesystem, then returns local filesystem path.
57
+ * Native implementation simply returns local path and does nothing.
58
+ *
59
+ * @param path - file to download
60
+ */
61
+ async download(path) {
62
+ const p = this.resolvePath(path);
63
+ const exists = await this.exists(path);
64
+ if (!exists) {
65
+ throw new IOFail(`file ${p} does not exists`);
66
+ }
67
+ return p;
68
+ }
69
+ async upload(srcPath, destPath) {
70
+ if (!existsSync(srcPath)) {
71
+ throw new IOFail(`file ${srcPath} does not exists`);
72
+ }
73
+ const dPath = this.resolvePath(destPath ?? basename(srcPath));
74
+ await cp(srcPath, dPath, { force: true, recursive: true });
75
+ }
76
+ /**
77
+ * read all content of file
78
+ */
79
+ async read(path, encoding) {
80
+ return new Promise((resolve, reject) => {
81
+ readFile(this.resolvePath(path), { encoding: encoding ?? 'binary' }, (err, data) => {
82
+ if (err) {
83
+ reject(err);
84
+ }
85
+ else {
86
+ resolve(data);
87
+ }
88
+ });
89
+ });
90
+ }
91
+ readStream(path, encoding) {
92
+ return Promise.resolve(createReadStream(this.resolvePath(path), { encoding: encoding ?? 'binary' }));
93
+ }
94
+ /**
95
+ * Write to file string or buffer
96
+ */
97
+ async write(path, data, encoding) {
98
+ let fHandle = null;
99
+ try {
100
+ fHandle = await open(this.resolvePath(path), 'w');
101
+ await fHandle.writeFile(data, { encoding });
102
+ }
103
+ catch (err) {
104
+ throw new IOFail(`Cannot write to file ${path}`, err);
105
+ }
106
+ finally {
107
+ if (fHandle) {
108
+ await fHandle.sync();
109
+ await fHandle.close();
110
+ }
111
+ }
112
+ }
113
+ async append(path, data, encoding) {
114
+ await appendFile(path, data, encoding);
115
+ }
116
+ writeStream(path, rStream, encoding) {
117
+ const stream = createWriteStream(this.resolvePath(path), {
118
+ encoding: (typeof rStream === 'string' ? rStream : encoding) ?? 'binary',
119
+ });
120
+ if (rStream instanceof ReadStream) {
121
+ rStream.pipe(stream);
122
+ }
123
+ return Promise.resolve(stream);
124
+ }
125
+ /**
126
+ * Checks if file existst
127
+ * @param path - path to check
128
+ */
129
+ async exists(path) {
130
+ try {
131
+ await access(this.resolvePath(path), constants.F_OK);
132
+ return true;
133
+ }
134
+ catch {
135
+ return false;
136
+ }
137
+ }
138
+ async dirExists(path) {
139
+ return this.exists(this.resolvePath(path));
140
+ }
141
+ /**
142
+ * Copy file or dir to another location
143
+ * @param path - src path
144
+ * @param dest - dest path
145
+ */
146
+ async copy(path, dest, dstFs) {
147
+ const sPath = this.resolvePath(path);
148
+ const exists = await this.exists(path);
149
+ if (!exists) {
150
+ throw new IOFail(`File ${path} not exists`);
151
+ }
152
+ if (dstFs) {
153
+ await dstFs.upload(sPath, dest);
154
+ }
155
+ else {
156
+ const dPath = this.resolvePath(dest);
157
+ await cp(sPath, dPath, {
158
+ recursive: true,
159
+ force: true,
160
+ });
161
+ }
162
+ }
163
+ /**
164
+ * Copy file to another location and deletes src file
165
+ */
166
+ async move(oldPath, newPath, dstFs) {
167
+ const oPath = this.resolvePath(oldPath);
168
+ if (dstFs) {
169
+ await dstFs.upload(oPath, newPath);
170
+ await this.rm(oldPath);
171
+ }
172
+ else {
173
+ const nPath = this.resolvePath(newPath);
174
+ await rename(oPath, nPath);
175
+ }
176
+ }
177
+ /**
178
+ * Change name of a file
179
+ */
180
+ async rename(oldPath, newPath) {
181
+ await rename(this.resolvePath(oldPath), this.resolvePath(newPath));
182
+ }
183
+ /**
184
+ *
185
+ * Deletes file OR
186
+ * Deletes dir recursively & all contents inside
187
+ *
188
+ * @param path - dir to remove
189
+ */
190
+ async rm(path) {
191
+ await rm(this.resolvePath(path), { recursive: true, force: true, maxRetries: 3, retryDelay: 1000 });
192
+ }
193
+ /**
194
+ *
195
+ * Creates directory, recursively
196
+ *
197
+ * @param path - directory to create
198
+ */
199
+ async mkdir(path) {
200
+ await mkdir(this.resolvePath(path), { recursive: true });
201
+ }
202
+ /**
203
+ * Returns file statistics, not all fields may be accesible
204
+ */
205
+ async stat(path) {
206
+ const result = await stat(this.resolvePath(path));
207
+ return {
208
+ IsDirectory: result.isDirectory(),
209
+ IsFile: result.isFile(),
210
+ CreationTime: DateTime.fromJSDate(result.ctime),
211
+ ModifiedTime: DateTime.fromJSDate(result.mtime),
212
+ AccessTime: DateTime.fromJSDate(result.atime),
213
+ Size: result.size,
214
+ };
215
+ }
216
+ tmppath() {
217
+ return join(this.Options.basePath, super.tmpname());
218
+ }
219
+ /**
220
+ * List content of directory
221
+ *
222
+ * @param path - path to directory
223
+ */
224
+ async list(path) {
225
+ return await readdir(this.resolvePath(path));
226
+ }
227
+ async unzip(path, destPath, dstFs) {
228
+ const dFs = dstFs ?? this;
229
+ const dst = dFs.resolvePath(destPath ?? dFs.tmpname());
230
+ return new Promise((resolve, reject) => {
231
+ createReadStream(this.resolvePath(path)).pipe(unzipper
232
+ .Extract({
233
+ path: dst,
234
+ })
235
+ .on('close', resolve)
236
+ .on('error', reject));
237
+ });
238
+ }
239
+ async isDir(path) {
240
+ try {
241
+ const pStat = await this.stat(path);
242
+ return pStat.IsDirectory;
243
+ }
244
+ catch {
245
+ return false;
246
+ }
247
+ }
248
+ async zip(path, dstFs, dstFile) {
249
+ const paths = toArray(path);
250
+ const fs = dstFs ?? (await DI.resolve('__file_provider__', ['fs-temp']));
251
+ const outFile = dstFile ?? `${fs.tmpname()}.zip`;
252
+ const wStream = await fs.writeStream(outFile);
253
+ const archive = archiver('zip');
254
+ // pipe archive data to the file
255
+ archive.pipe(wStream);
256
+ for (const p of paths.map((p) => this.resolvePath(p))) {
257
+ if (await this.isDir(p)) {
258
+ archive.directory(p, false);
259
+ continue;
260
+ }
261
+ archive.file(p, { name: basename(p) });
262
+ }
263
+ return new Promise((resolve, reject) => {
264
+ archive.on('warning', (err) => {
265
+ if (err.code === 'ENOENT') {
266
+ this.Logger.error(err, `File not found ( archiving file ), reason: ${err.message})`);
267
+ return;
268
+ }
269
+ reject(new IOFail('Archiving error', err));
270
+ });
271
+ archive.on('error', (err) => {
272
+ reject(new IOFail('Archiving error', err));
273
+ });
274
+ archive.on('entry', (entry) => {
275
+ this.Logger.trace(`Archiving file ${entry.name}, size: ${entry.stats?.size} into ${outFile}, fs: ${fs.Name}`);
276
+ });
277
+ wStream.on('close', () => {
278
+ const result = {
279
+ fs,
280
+ asFilePath: () => {
281
+ return outFile;
282
+ },
283
+ asStream: (encoding) => {
284
+ return createReadStream(outFile, {
285
+ encoding: encoding ?? 'binary',
286
+ });
287
+ },
288
+ asBase64: () => {
289
+ return readFileSync(outFile, { encoding: 'base64' });
290
+ },
291
+ unlink: async () => {
292
+ return await fs.rm(outFile);
293
+ },
294
+ };
295
+ resolve(result);
296
+ });
297
+ archive.finalize();
298
+ });
299
+ }
300
+ resolvePath(path) {
301
+ if (!this.Options.basePath || path.startsWith(this.Options.basePath))
302
+ return path;
303
+ return join(this.Options.basePath, path);
304
+ }
305
+ };
306
+ __decorate([
307
+ Logger('fs'),
308
+ __metadata("design:type", Log)
309
+ ], fsNative.prototype, "Logger", void 0);
310
+ fsNative = __decorate([
311
+ Injectable('fs'),
312
+ PerInstanceCheck(),
313
+ __metadata("design:paramtypes", [Object])
314
+ ], fsNative);
315
+ export { fsNative };
273
316
  //# sourceMappingURL=local-provider.js.map