1 | const concatStream = require('concat-stream')
|
2 | const Readable = require('stream').Readable
|
3 | const path = require("path");
|
4 | const fs = require("fs-extra");
|
5 |
|
6 | class SolidFileStorage {
|
7 | constructor() {
|
8 | this.prefix = "file"
|
9 | this.name = "solid-rest-file-storage-1.0.0"
|
10 | }
|
11 |
|
12 | _makeStream(text){
|
13 | if (typeof text === 'object' && typeof text.stream === 'function') {
|
14 | return text.stream()
|
15 | }
|
16 | let s = new Readable
|
17 | s.push(text)
|
18 | s.push(null)
|
19 | return s;
|
20 | }
|
21 | async text (stream) {
|
22 | return new Promise((resolve, reject) => {
|
23 | stream = stream || ""
|
24 | if(typeof stream === "string") return resolve(stream);
|
25 | stream.pipe(concatStream({
|
26 | encoding: 'string'
|
27 | }, resolve())).catch(e=>{console.log(e); reject()})
|
28 | stream.on('error', reject())
|
29 | })
|
30 | }
|
31 | async json (stream) {
|
32 | return text(stream).then(text => JSON.parse(text))
|
33 | }
|
34 |
|
35 | async getObjectType(fn,options){
|
36 | let stat;
|
37 | try { stat = fs.lstatSync(fn); }
|
38 | catch(err){ }
|
39 | let type = ( stat && stat.isDirectory()) ? "Container" : "Resource";
|
40 | if(!stat && fn.endsWith('/')) type = "Container"
|
41 | return Promise.resolve( [type,stat] )
|
42 | }
|
43 |
|
44 | async getResource(pathname,options,objectType){
|
45 | const bodyData = fs.createReadStream(pathname)
|
46 | return [
|
47 | 200,
|
48 | bodyData
|
49 | ]
|
50 | }
|
51 |
|
52 | async putResource(pathname,options){
|
53 | return new Promise((resolve) => {
|
54 | options.body = this._makeStream( options.body );
|
55 | options.body.pipe(fs.createWriteStream(pathname)).on('finish',()=>{
|
56 | resolve( [201] )
|
57 | }).on('error', (err) => {
|
58 | if(options.method==="PUT" && options.objectType==="Container")
|
59 | resolve( [405] )
|
60 | resolve( [500] )
|
61 | })
|
62 | })
|
63 | }
|
64 | async deleteResource(fn){
|
65 | return new Promise(function(resolve) {
|
66 | fs.unlink( fn, function(err) {
|
67 | if(err) resolve( [409] );
|
68 | else resolve( [200] );
|
69 | });
|
70 | });
|
71 | }
|
72 | deleteContainer(fn){
|
73 | return new Promise(function(resolve) {
|
74 | fs.rmdir( fn, function(err) {
|
75 | if(err) {
|
76 | resolve( [409] );
|
77 | } else {
|
78 | resolve( [200] );
|
79 | }
|
80 | });
|
81 | });
|
82 | }
|
83 | postContainer(fn,options){
|
84 | fn = fn.replace(/\/$/,'');
|
85 | return new Promise(function(resolve) {
|
86 | if(fs.existsSync(fn)){
|
87 | return resolve( [201] )
|
88 | }
|
89 | fs.mkdirp( fn, {}, (err) => {
|
90 | if(err) {
|
91 | return resolve( [500] )
|
92 | }
|
93 | else {
|
94 | return resolve( [201] )
|
95 | }
|
96 | });
|
97 | });
|
98 | }
|
99 | async makeContainers(pathname,options){
|
100 | let filename = path.basename(pathname);
|
101 | let reg = new RegExp(filename+"\$")
|
102 | let foldername = pathname.replace(reg,'');
|
103 | let [t,exists] = await this.getObjectType(foldername);
|
104 | if(exists) return Promise.resolve([200])
|
105 | foldername = foldername.replace(/\/$/,'');
|
106 | await fs.mkdirpSync( foldername, {}, (err) => {
|
107 | if(err) return Promise.resolve( 500 )
|
108 | else return Promise.resolve( 201 )
|
109 | })
|
110 | return Promise.resolve([200])
|
111 | }
|
112 | async getContainer(pathname,options) {
|
113 | return fs.readdirSync(pathname)
|
114 | }
|
115 |
|
116 | }
|
117 | module.exports = SolidFileStorage
|
118 |
|