diff --git a/app/index.js b/app/index.js index 4ae1ad871..99f1e3995 100644 --- a/app/index.js +++ b/app/index.js @@ -316,6 +316,7 @@ var AngularFullstackGenerator = yeoman.generators.Base.extend({ saveSettings: function() { if(this.skipConfig) return; + this.config.set('endpointDirectory', 'server/api/'); this.config.set('insertRoutes', true); this.config.set('registerRoutesFile', 'server/routes.js'); this.config.set('routesNeedle', '// Insert routes below'); @@ -399,11 +400,19 @@ var AngularFullstackGenerator = yeoman.generators.Base.extend({ }, generateEndpoint: function() { - var name = this.name = this.cameledName = 'thing'; - this.classedName = name.charAt(0).toUpperCase() + name.slice(1); - this.route = '/api/' + name + 's'; - this.sourceRoot(path.join(__dirname, '..', 'endpoint', 'templates')); - genUtils.processDirectory(this, '.', 'server/api/' + name); + var models; + if (this.filters.mongooseModels) { + models = 'mongoose'; + } else if (this.filters.sequelizeModels) { + models = 'sequelize'; + } + this.composeWith('angular-fullstack:endpoint', { + options: { + route: '/api/things', + models: models + }, + args: ['thing'] + }); } }, diff --git a/app/templates/_package.json b/app/templates/_package.json index c9b1533be..f72c18ca5 100644 --- a/app/templates/_package.json +++ b/app/templates/_package.json @@ -19,7 +19,7 @@ "mongoose": "~4.0.3", "mongoose-bird": "~0.0.1", "connect-mongo": "^0.8.1",<% } %><% if (filters.sequelize) { %> - "sequelize": "^2.0.0-rc2", + "sequelize": "^3.5.1", "sqlite3": "~3.0.2",<% } %><% if (filters.auth) { %> "jsonwebtoken": "^5.0.0", "express-jwt": "^3.0.0", diff --git a/app/templates/server/sqldb(sequelize)/index.js b/app/templates/server/sqldb(sequelize)/index.js index 231db9823..2500a2213 100644 --- a/app/templates/server/sqldb(sequelize)/index.js +++ b/app/templates/server/sqldb(sequelize)/index.js @@ -13,23 +13,8 @@ var db = { Sequelize: Sequelize, sequelize: new Sequelize(config.sequelize.uri, config.sequelize.options) }; -<% if (filters.sequelizeModels) { %> -db.Thing = db.sequelize.import(path.join( - config.root, - 'server', - 'api', - 'thing', - 'thing.model' -)); -<% if (filters.auth) { %> -db.User = db.sequelize.import(path.join( - config.root, - 'server', - 'api', - 'user', - 'user.model' -)); -<% } %><% } %> -// Insert models below + +// Insert models below<% if (filters.sequelizeModels && filters.auth) { %> +db.User = db.sequelize.import('../api/user/user.model');<% } %> module.exports = db; diff --git a/endpoint/index.js b/endpoint/index.js index 22e8e8950..cbb8d5aeb 100644 --- a/endpoint/index.js +++ b/endpoint/index.js @@ -7,12 +7,59 @@ var ScriptBase = require('../script-base.js'); var Generator = module.exports = function Generator() { ScriptBase.apply(this, arguments); + + this.option('route', { + desc: 'URL for the endpoint', + type: String + }); + + this.option('models', { + desc: 'Specify which model(s) to use', + type: String + }); + + this.option('endpointDirectory', { + desc: 'Parent directory for enpoints', + type: String + }); }; util.inherits(Generator, ScriptBase); Generator.prototype.prompting = function askFor() { var done = this.async(); + var promptCb = function (props) { + if(props.route.charAt(0) !== '/') { + props.route = '/' + props.route; + } + + this.route = props.route; + + if (props.models) { + delete this.filters.mongoose; + delete this.filters.mongooseModels; + delete this.filters.sequelize; + delete this.filters.sequelizeModels; + + this.filters[props.models] = true; + this.filters[props.models + 'Models'] = true; + } + done(); + }.bind(this); + + if (this.options.route) { + if (this.filters.mongoose && this.filters.sequelize) { + if (this.options.models) { + return promptCb(this.options); + } + } else { + if (this.filters.mongooseModels) { this.options.models = 'mongoose'; } + else if (this.filters.sequelizeModels) { this.options.models = 'sequelize'; } + else { delete this.options.models; } + return promptCb(this.options); + } + } + var name = this.name; var base = this.config.get('routesBase') || '/api/'; @@ -46,73 +93,58 @@ Generator.prototype.prompting = function askFor() { } ]; - this.prompt(prompts, function (props) { - if(props.route.charAt(0) !== '/') { - props.route = '/' + props.route; - } - - this.route = props.route; - - if (props.models) { - delete this.filters.mongoose; - delete this.filters.mongooseModels; - delete this.filters.sequelize; - delete this.filters.sequelizeModels; + this.prompt(prompts, promptCb); +}; - this.filters[props.models] = true; - this.filters[props.models + 'Models'] = true; - } - done(); - }.bind(this)); +Generator.prototype.configuring = function config() { + this.routeDest = path.join(this.options.endpointDirectory || + this.config.get('endpointDirectory') || 'server/api/', this.name); }; Generator.prototype.writing = function createFiles() { - var dest = this.config.get('endpointDirectory') || 'server/api/' + this.name; this.sourceRoot(path.join(__dirname, './templates')); - ngUtil.processDirectory(this, '.', dest); + ngUtil.processDirectory(this, '.', this.routeDest); }; Generator.prototype.end = function registerEndpoint() { if(this.config.get('insertRoutes')) { + var routesFile = this.config.get('registerRoutesFile'); + var reqPath = this.relativeRequire(this.routeDest, routesFile); var routeConfig = { - file: this.config.get('registerRoutesFile'), + file: routesFile, needle: this.config.get('routesNeedle'), splicable: [ - "app.use(\'" + this.route +"\', require(\'./api/" + this.name + "\'));" + "app.use(\'" + this.route +"\', require(\'" + reqPath + "\'));" ] }; ngUtil.rewriteFile(routeConfig); } - if (this.filters.socketio) { - if(this.config.get('insertSockets')) { - var socketConfig = { - file: this.config.get('registerSocketsFile'), - needle: this.config.get('socketsNeedle'), - splicable: [ - "require(\'../api/" + this.name + '/' + this.name + ".socket\').register(socket);" - ] - }; - ngUtil.rewriteFile(socketConfig); - } + if (this.filters.socketio && this.config.get('insertSockets')) { + var socketsFile = this.config.get('registerSocketsFile'); + var reqPath = this.relativeRequire(this.routeDest + '/' + this.basename + + '.socket', socketsFile); + var socketConfig = { + file: socketsFile, + needle: this.config.get('socketsNeedle'), + splicable: [ + "require(\'" + reqPath + "\').register(socket);" + ] + }; + ngUtil.rewriteFile(socketConfig); } - if (this.filters.sequelize) { - if (this.config.get('insertModels')) { - var modelConfig = { - file: this.config.get('registerModelsFile'), - needle: this.config.get('modelsNeedle'), - splicable: [ - "db." + this.classedName + " = db.sequelize.import(path.join(\n" + - " config.root,\n" + - " 'server',\n" + - " 'api',\n" + - " '" + this.name + "',\n" + - " '" + this.name + ".model'\n" + - "));" - ] - }; - ngUtil.rewriteFile(modelConfig); - } + if (this.filters.sequelize && this.config.get('insertModels')) { + var modelsFile = this.config.get('registerModelsFile'); + var reqPath = this.relativeRequire(this.routeDest + '/' + this.basename + + '.model', modelsFile); + var modelConfig = { + file: modelsFile, + needle: this.config.get('modelsNeedle'), + splicable: [ + "db." + this.classedName + " = db.sequelize.import(\'" + reqPath +"\');" + ] + }; + ngUtil.rewriteFile(modelConfig); } }; diff --git a/endpoint/templates/name.controller.js b/endpoint/templates/basename.controller.js similarity index 89% rename from endpoint/templates/name.controller.js rename to endpoint/templates/basename.controller.js index abcc5f34b..cd151b13a 100644 --- a/endpoint/templates/name.controller.js +++ b/endpoint/templates/basename.controller.js @@ -10,8 +10,8 @@ 'use strict';<% if (filters.models) { %> var _ = require('lodash');<% if (filters.mongooseModels) { %> -var <%= classedName %> = require('./<%= name %>.model');<% } if (filters.sequelizeModels) { %> -var sqldb = require('../../sqldb'); +var <%= classedName %> = require('./<%= basename %>.model');<% } if (filters.sequelizeModels) { %> +var sqldb = require('<%= relativeRequire(config.get('registerModelsFile')) %>'); var <%= classedName %> = sqldb.<%= classedName %>;<% } %> function handleError(res, statusCode) { @@ -64,7 +64,7 @@ function removeEntity(res) { }; }<% } %> -// Gets a list of <%= name %>s +// Gets a list of <%= classedName %>s exports.index = function(req, res) {<% if (!filters.models) { %> res.json([]);<% } else { %> <% if (filters.mongooseModels) { %><%= classedName %>.findAsync()<% } @@ -73,7 +73,7 @@ exports.index = function(req, res) {<% if (!filters.models) { %> .catch(handleError(res));<% } %> };<% if (filters.models) { %> -// Gets a single <%= name %> from the DB +// Gets a single <%= classedName %> from the DB exports.show = function(req, res) { <% if (filters.mongooseModels) { %><%= classedName %>.findByIdAsync(req.params.id)<% } if (filters.sequelizeModels) { %><%= classedName %>.find({ @@ -86,7 +86,7 @@ exports.show = function(req, res) { .catch(handleError(res)); }; -// Creates a new <%= name %> in the DB +// Creates a new <%= classedName %> in the DB exports.create = function(req, res) { <% if (filters.mongooseModels) { %><%= classedName %>.createAsync(req.body)<% } if (filters.sequelizeModels) { %><%= classedName %>.create(req.body)<% } %> @@ -94,7 +94,7 @@ exports.create = function(req, res) { .catch(handleError(res)); }; -// Updates an existing <%= name %> in the DB +// Updates an existing <%= classedName %> in the DB exports.update = function(req, res) { if (req.body._id) { delete req.body._id; @@ -111,7 +111,7 @@ exports.update = function(req, res) { .catch(handleError(res)); }; -// Deletes a <%= name %> from the DB +// Deletes a <%= classedName %> from the DB exports.destroy = function(req, res) { <% if (filters.mongooseModels) { %><%= classedName %>.findByIdAsync(req.params.id)<% } if (filters.sequelizeModels) { %><%= classedName %>.find({ diff --git a/endpoint/templates/name.events(models).js b/endpoint/templates/basename.events(models).js similarity index 84% rename from endpoint/templates/name.events(models).js rename to endpoint/templates/basename.events(models).js index 8bda5cf9a..f39b5b0be 100644 --- a/endpoint/templates/name.events(models).js +++ b/endpoint/templates/basename.events(models).js @@ -5,8 +5,8 @@ 'use strict'; var EventEmitter = require('events').EventEmitter;<% if (filters.mongooseModels) { %> -var <%= classedName %> = require('./<%= name %>.model');<% } if (filters.sequelizeModels) { %> -var <%= classedName %> = require('../../sqldb').<%= classedName %>;<% } %> +var <%= classedName %> = require('./<%= basename %>.model');<% } if (filters.sequelizeModels) { %> +var <%= classedName %> = require('<%= relativeRequire(config.get('registerModelsFile')) %>').<%= classedName %>;<% } %> var <%= classedName %>Events = new EventEmitter(); // Set max event listeners (0 == unlimited) diff --git a/endpoint/templates/name.integration.js b/endpoint/templates/basename.integration.js similarity index 84% rename from endpoint/templates/name.integration.js rename to endpoint/templates/basename.integration.js index 160cdedfa..bcd3fd407 100644 --- a/endpoint/templates/name.integration.js +++ b/endpoint/templates/basename.integration.js @@ -1,6 +1,6 @@ 'use strict'; -var app = require('../../app'); +var app = require('<%= relativeRequire('server/app') %>'); var request = require('supertest');<% if(filters.models) { %> var new<%= classedName %>;<% } %> @@ -36,7 +36,7 @@ describe('<%= classedName %> API:', function() { .post('<%= route %>') .send({ name: 'New <%= classedName %>', - info: 'This is the brand new <%= name %>!!!' + info: 'This is the brand new <%= cameledName %>!!!' }) .expect(201) .expect('Content-Type', /json/) @@ -49,9 +49,9 @@ describe('<%= classedName %> API:', function() { }); }); - it('should respond with the newly created <%= name %>', function() { + it('should respond with the newly created <%= cameledName %>', function() { new<%= classedName %>.name.should.equal('New <%= classedName %>'); - new<%= classedName %>.info.should.equal('This is the brand new <%= name %>!!!'); + new<%= classedName %>.info.should.equal('This is the brand new <%= cameledName %>!!!'); }); }); @@ -77,9 +77,9 @@ describe('<%= classedName %> API:', function() { <%= cameledName %> = {}; }); - it('should respond with the requested <%= name %>', function() { + it('should respond with the requested <%= cameledName %>', function() { <%= cameledName %>.name.should.equal('New <%= classedName %>'); - <%= cameledName %>.info.should.equal('This is the brand new <%= name %>!!!'); + <%= cameledName %>.info.should.equal('This is the brand new <%= cameledName %>!!!'); }); }); @@ -92,7 +92,7 @@ describe('<%= classedName %> API:', function() { .put('<%= route %>/' + new<%= classedName %>._id) .send({ name: 'Updated <%= classedName %>', - info: 'This is the updated <%= name %>!!!' + info: 'This is the updated <%= cameledName %>!!!' }) .expect(200) .expect('Content-Type', /json/) @@ -109,9 +109,9 @@ describe('<%= classedName %> API:', function() { updated<%= classedName %> = {}; }); - it('should respond with the updated <%= name %>', function() { + it('should respond with the updated <%= cameledName %>', function() { updated<%= classedName %>.name.should.equal('Updated <%= classedName %>'); - updated<%= classedName %>.info.should.equal('This is the updated <%= name %>!!!'); + updated<%= classedName %>.info.should.equal('This is the updated <%= cameledName %>!!!'); }); }); @@ -130,7 +130,7 @@ describe('<%= classedName %> API:', function() { }); }); - it('should respond with 404 when <%= name %> does not exist', function(done) { + it('should respond with 404 when <%= cameledName %> does not exist', function(done) { request(app) .delete('<%= route %>/' + new<%= classedName %>._id) .expect(404) diff --git a/endpoint/templates/name.model(mongooseModels).js b/endpoint/templates/basename.model(mongooseModels).js similarity index 100% rename from endpoint/templates/name.model(mongooseModels).js rename to endpoint/templates/basename.model(mongooseModels).js diff --git a/endpoint/templates/name.model(sequelizeModels).js b/endpoint/templates/basename.model(sequelizeModels).js similarity index 100% rename from endpoint/templates/name.model(sequelizeModels).js rename to endpoint/templates/basename.model(sequelizeModels).js diff --git a/endpoint/templates/name.socket(socketio).js b/endpoint/templates/basename.socket(socketio).js similarity index 82% rename from endpoint/templates/name.socket(socketio).js rename to endpoint/templates/basename.socket(socketio).js index 24d744d13..037f6113a 100644 --- a/endpoint/templates/name.socket(socketio).js +++ b/endpoint/templates/basename.socket(socketio).js @@ -4,7 +4,7 @@ 'use strict'; -var <%= classedName %>Events = require('./<%= name %>.events'); +var <%= classedName %>Events = require('./<%= basename %>.events'); // Model events to emit var events = ['save', 'remove']; @@ -13,7 +13,7 @@ exports.register = function(socket) { // Bind model events to socket events for (var i = 0, eventsLength = events.length; i < eventsLength; i++) { var event = events[i]; - var listener = createListener('<%= name %>:' + event, socket); + var listener = createListener('<%= cameledName %>:' + event, socket); <%= classedName %>Events.on(event, listener); socket.on('disconnect', removeListener(event, listener)); diff --git a/endpoint/templates/index.js b/endpoint/templates/index.js index 60198d142..26dc430dd 100644 --- a/endpoint/templates/index.js +++ b/endpoint/templates/index.js @@ -1,7 +1,7 @@ 'use strict'; var express = require('express'); -var controller = require('./<%= name %>.controller'); +var controller = require('./<%= basename %>.controller'); var router = express.Router(); diff --git a/endpoint/templates/index.spec.js b/endpoint/templates/index.spec.js index 291a04662..4bd178948 100644 --- a/endpoint/templates/index.spec.js +++ b/endpoint/templates/index.spec.js @@ -3,11 +3,11 @@ var proxyquire = require('proxyquire').noPreserveCache(); var <%= cameledName %>CtrlStub = { - index: '<%= name %>Ctrl.index'<% if(filters.models) { %>, - show: '<%= name %>Ctrl.show', - create: '<%= name %>Ctrl.create', - update: '<%= name %>Ctrl.update', - destroy: '<%= name %>Ctrl.destroy'<% } %> + index: '<%= cameledName %>Ctrl.index'<% if(filters.models) { %>, + show: '<%= cameledName %>Ctrl.show', + create: '<%= cameledName %>Ctrl.create', + update: '<%= cameledName %>Ctrl.update', + destroy: '<%= cameledName %>Ctrl.destroy'<% } %> }; var routerStub = { @@ -25,7 +25,7 @@ var <%= cameledName %>Index = proxyquire('./index.js', { return routerStub; } }, - './<%= name %>.controller': <%= cameledName %>CtrlStub + './<%= basename %>.controller': <%= cameledName %>CtrlStub }); describe('<%= classedName %> API Router:', function() { @@ -36,9 +36,9 @@ describe('<%= classedName %> API Router:', function() { describe('GET <%= route %>', function() { - it('should route to <%= name %>.controller.index', function() { + it('should route to <%= cameledName %>.controller.index', function() { routerStub.get - .withArgs('/', '<%= name %>Ctrl.index') + .withArgs('/', '<%= cameledName %>Ctrl.index') .should.have.been.calledOnce; }); @@ -46,9 +46,9 @@ describe('<%= classedName %> API Router:', function() { describe('GET <%= route %>/:id', function() { - it('should route to <%= name %>.controller.show', function() { + it('should route to <%= cameledName %>.controller.show', function() { routerStub.get - .withArgs('/:id', '<%= name %>Ctrl.show') + .withArgs('/:id', '<%= cameledName %>Ctrl.show') .should.have.been.calledOnce; }); @@ -56,9 +56,9 @@ describe('<%= classedName %> API Router:', function() { describe('POST <%= route %>', function() { - it('should route to <%= name %>.controller.create', function() { + it('should route to <%= cameledName %>.controller.create', function() { routerStub.post - .withArgs('/', '<%= name %>Ctrl.create') + .withArgs('/', '<%= cameledName %>Ctrl.create') .should.have.been.calledOnce; }); @@ -66,9 +66,9 @@ describe('<%= classedName %> API Router:', function() { describe('PUT <%= route %>/:id', function() { - it('should route to <%= name %>.controller.update', function() { + it('should route to <%= cameledName %>.controller.update', function() { routerStub.put - .withArgs('/:id', '<%= name %>Ctrl.update') + .withArgs('/:id', '<%= cameledName %>Ctrl.update') .should.have.been.calledOnce; }); @@ -76,9 +76,9 @@ describe('<%= classedName %> API Router:', function() { describe('PATCH <%= route %>/:id', function() { - it('should route to <%= name %>.controller.update', function() { + it('should route to <%= cameledName %>.controller.update', function() { routerStub.patch - .withArgs('/:id', '<%= name %>Ctrl.update') + .withArgs('/:id', '<%= cameledName %>Ctrl.update') .should.have.been.calledOnce; }); @@ -86,9 +86,9 @@ describe('<%= classedName %> API Router:', function() { describe('DELETE <%= route %>/:id', function() { - it('should route to <%= name %>.controller.destroy', function() { + it('should route to <%= cameledName %>.controller.destroy', function() { routerStub.delete - .withArgs('/:id', '<%= name %>Ctrl.destroy') + .withArgs('/:id', '<%= cameledName %>Ctrl.destroy') .should.have.been.calledOnce; }); diff --git a/script-base.js b/script-base.js index 5d6c7dd2e..d88cd988c 100644 --- a/script-base.js +++ b/script-base.js @@ -15,8 +15,13 @@ var Generator = module.exports = function Generator() { this.appname = this._.slugify(this._.humanize(this.appname)); this.scriptAppName = this._.camelize(this.appname) + angularUtils.appName(this); - this.cameledName = this._.camelize(this.name); - this.classedName = this._.classify(this.name); + var name = this.name.replace(/\//g, '-'); + + this.cameledName = this._.camelize(name); + this.classedName = this._.classify(name); + + this.basename = path.basename(this.name); + this.dirname = (this.name.indexOf('/') >= 0) ? path.dirname(this.name) : this.name; // dynamic assertion statement this.does = this.is = function(foo) { @@ -27,6 +32,12 @@ var Generator = module.exports = function Generator() { } }.bind(this); + // dynamic relative require path + this.relativeRequire = function(to, fr) { + fr = fr || this.filePath; + return angularUtils.relativeRequire(this, to, fr); + }.bind(this); + this.filters = this.config.get('filters'); this.sourceRoot(path.join(__dirname, '/templates')); }; diff --git a/test/test-file-creation.js b/test/test-file-creation.js index ce8635c0b..fb0fb2b91 100644 --- a/test/test-file-creation.js +++ b/test/test-file-creation.js @@ -314,6 +314,7 @@ describe('angular-fullstack generator', function () { this.timeout(10000); var deps = [ '../../app', + '../../endpoint', [ helpers.createDummyGenerator(), 'ng-component:app' @@ -416,11 +417,35 @@ describe('angular-fullstack generator', function () { runTest('grunt test:server', this, done, 'Foo'); }); + it('should pass lint with generated path name endpoint', function(done) { + runTest('grunt jshint', this, done, 'foo/bar'); + }); + + it('should run server tests successfully with generated path name endpoint', function(done) { + runTest('grunt test:server', this, done, 'foo/bar'); + }); + + it('should generate expected files with path name endpoint', function(done) { + runTest('(exit 0)', this, function() { + helpers.assertFile([ + 'server/api/foo/bar/index.js', + 'server/api/foo/bar/index.spec.js', + 'server/api/foo/bar/bar.controller.js', + 'server/api/foo/bar/bar.events.js', + 'server/api/foo/bar/bar.integration.js', + 'server/api/foo/bar/bar.model.js', + 'server/api/foo/bar/bar.socket.js' + ]); + done(); + }, 'foo/bar'); + }); + it('should use existing config if available', function(done) { this.timeout(60000); fs.copySync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json'); var gen = helpers.createGenerator('angular-fullstack:app', [ '../../app', + '../../endpoint', [ helpers.createDummyGenerator(), 'ng-component:app' @@ -445,6 +470,7 @@ describe('angular-fullstack generator', function () { fs.copySync(__dirname + '/fixtures/.yo-rc.json', __dirname + '/temp/.yo-rc.json'); var gen = helpers.createGenerator('angular-fullstack:app', [ '../../app', + '../../endpoint', [ helpers.createDummyGenerator(), 'ng-component:app' diff --git a/util.js b/util.js index 4bf2170c4..6657cfc9f 100644 --- a/util.js +++ b/util.js @@ -6,7 +6,8 @@ module.exports = { rewrite: rewrite, rewriteFile: rewriteFile, appName: appName, - processDirectory: processDirectory + processDirectory: processDirectory, + relativeRequire: relativeRequire }; function rewriteFile (args) { @@ -74,6 +75,23 @@ function appName (self) { return suffix ? self._.classify(suffix) : ''; } +function destinationPath (self, filepath) { + filepath = path.normalize(filepath); + if (!path.isAbsolute(filepath)) { + filepath = path.join(self.destinationRoot(), filepath); + } + + return filepath; +} + +function relativeRequire (self, to, fr) { + fr = destinationPath(self, fr); + to = destinationPath(self, to); + return path.relative(path.dirname(fr), to) + .replace(/^(?!\.\.)(.*)/, './$1') + .replace(/[\/\\]index\.js$/, ''); +} + function filterFile (template) { // Find matches for parans var filterMatches = template.match(/\(([^)]+)\)/g); @@ -109,6 +127,9 @@ function processDirectory (self, source, destination) { files.forEach(function(f) { var filteredFile = filterFile(f); + if(self.basename) { + filteredFile.name = filteredFile.name.replace('basename', self.basename); + } if(self.name) { filteredFile.name = filteredFile.name.replace('name', self.name); } @@ -133,7 +154,9 @@ function processDirectory (self, source, destination) { if(copy) { self.copy(src, dest); } else { + self.filePath = dest; self.template(src, dest); + delete self.filePath; } } });