-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FileSystemAdapter for saving files to the server's file system #716
Changes from all commits
1dfc7e4
ae8fe88
5866e61
b8c08a3
13bc540
273ee52
ac42754
89ae73a
a9b2f46
8b55128
31f56ee
2f08a57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,3 +43,6 @@ lib/ | |
|
||
# Mac DS_Store files | ||
.DS_Store | ||
|
||
# Folder created by FileSystemAdapter | ||
/files | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// FileSystemAdapter | ||
// | ||
// Stores files in local file system | ||
// Requires write access to the server's file system. | ||
|
||
import { FilesAdapter } from './FilesAdapter'; | ||
import colors from 'colors'; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var pathSep = require('path').sep; | ||
|
||
export class FileSystemAdapter extends FilesAdapter { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please allow options in the constructor to provide a path by the developer |
||
|
||
constructor({filesSubDirectory = ''} = {}) { | ||
super(); | ||
|
||
this._filesDir = filesSubDirectory; | ||
this._mkdir(this._getApplicationDir()); | ||
if (!this._applicationDirExist()) { | ||
throw "Files directory doesn't exist."; | ||
} | ||
} | ||
|
||
// For a given config object, filename, and data, store a file | ||
// Returns a promise | ||
createFile(config, filename, data) { | ||
return new Promise((resolve, reject) => { | ||
let filepath = this._getLocalFilePath(filename); | ||
fs.writeFile(filepath, data, (err) => { | ||
if(err !== null) { | ||
return reject(err); | ||
} | ||
resolve(data); | ||
}); | ||
}); | ||
} | ||
|
||
deleteFile(config, filename) { | ||
return new Promise((resolve, reject) => { | ||
let filepath = this._getLocalFilePath(filename); | ||
fs.readFile( filepath , function (err, data) { | ||
if(err !== null) { | ||
return reject(err); | ||
} | ||
fs.unlink(filepath, (unlinkErr) => { | ||
if(err !== null) { | ||
return reject(unlinkErr); | ||
} | ||
resolve(data); | ||
}); | ||
}); | ||
|
||
}); | ||
} | ||
|
||
getFileData(config, filename) { | ||
return new Promise((resolve, reject) => { | ||
let filepath = this._getLocalFilePath(filename); | ||
fs.readFile( filepath , function (err, data) { | ||
if(err !== null) { | ||
return reject(err); | ||
} | ||
resolve(data); | ||
}); | ||
}); | ||
} | ||
|
||
getFileLocation(config, filename) { | ||
return (config.mount + '/' + this._getLocalFilePath(filename)); | ||
} | ||
|
||
/* | ||
Helpers | ||
--------------- */ | ||
_getApplicationDir() { | ||
if (this._filesDir) { | ||
return path.join('files', this._filesDir); | ||
} else { | ||
return 'files'; | ||
} | ||
} | ||
|
||
_applicationDirExist() { | ||
return fs.existsSync(this._getApplicationDir()); | ||
} | ||
|
||
_getLocalFilePath(filename) { | ||
let applicationDir = this._getApplicationDir(); | ||
if (!fs.existsSync(applicationDir)) { | ||
this._mkdir(applicationDir); | ||
} | ||
return path.join(applicationDir, encodeURIComponent(filename)); | ||
} | ||
|
||
_mkdir(path) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't use var path as it's defined at the top-level |
||
// snippet found on -> https://gist.github.com/danherbert-epam/3960169 | ||
var dirs = path.split(pathSep); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use const, let not vars |
||
var root = ""; | ||
|
||
while (dirs.length > 0) { | ||
var dir = dirs.shift(); | ||
if (dir === "") { // If directory starts with a /, the first path will be an empty string. | ||
root = pathSep; | ||
} | ||
if (!fs.existsSync(root + dir)) { | ||
try { | ||
fs.mkdirSync(root + dir); | ||
} | ||
catch (e) { | ||
if ( e.code == 'EACCES' ) { | ||
console.error(""); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you may wanna throw an error here as there is no fallback, and this will render the File management on the server completely unusable |
||
console.error(colors.red("ERROR: In order to use the FileSystemAdapter, write access to the server's file system is required")); | ||
console.error(""); | ||
} | ||
} | ||
} | ||
root += dir + pathSep; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use path.join |
||
} | ||
} | ||
} | ||
|
||
export default FileSystemAdapter; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add line break after that line |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,7 +40,7 @@ if (program.args.length > 0 ) { | |
jsonPath = path.resolve(jsonPath); | ||
options = require(jsonPath); | ||
console.log(`Configuation loaded from ${jsonPath}`) | ||
} | ||
} | ||
|
||
options = Object.keys(definitions).reduce(function (options, key) { | ||
if (program[key]) { | ||
|
@@ -53,7 +53,7 @@ if (!options.serverURL) { | |
options.serverURL = `http://localhost:${options.port}${options.mountPath}`; | ||
} | ||
|
||
if (!options.appId || !options.masterKey || !options.serverURL) { | ||
if (!program.appId || !program.masterKey || !program.serverURL) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please revert those changes |
||
program.outputHelp(); | ||
console.error(""); | ||
console.error(colors.red("ERROR: appId, masterKey and serverURL are required")); | ||
|
@@ -65,7 +65,7 @@ const app = express(); | |
const api = new ParseServer(options); | ||
app.use(options.mountPath, api); | ||
|
||
var server = app.listen(options.port, function() { | ||
app.listen(options.port, function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and this change too |
||
|
||
for (let key in options) { | ||
let value = options[key]; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove '/'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without '/' git ignores 'src/Adapters/Files/' folder too. I added this so git ignores only the first-level 'files' folder