much improvement to client side \n fixed wdiff output for markdown server side
This commit is contained in:
parent
4917885686
commit
ee3bd40ef7
@ -15,10 +15,21 @@ $fa-font-path: "/bower_components/font-awesome/fonts";
|
||||
padding: 0.2em 0;
|
||||
}
|
||||
|
||||
table.revisions th, table.revisions td{
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
table.revisions .state {
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
// Component styles are injected through grunt
|
||||
// injector
|
||||
@import 'account/login/login.scss';
|
||||
@import 'admin/admin.scss';
|
||||
@import 'document/document.scss';
|
||||
@import 'document/revision-new/revision-new.scss';
|
||||
@import 'wdiff/wdiff.scss';
|
||||
@import 'modal/modal.scss';
|
||||
// endinjector
|
3
client/app/document/document.scss
Normal file
3
client/app/document/document.scss
Normal file
@ -0,0 +1,3 @@
|
||||
table.revisions {
|
||||
column-gap: 2em;
|
||||
}
|
@ -2,8 +2,10 @@
|
||||
|
||||
angular.module('markdownFormatWdiffApp')
|
||||
.controller('DocumentIndexCtrl', function ($scope, $routeParams, $http, Auth, $location) {
|
||||
$scope.title = 'Documents';
|
||||
|
||||
$scope.documents = [];
|
||||
$scope.newDocumentTitle;
|
||||
$scope.newDocumentTitle = '';
|
||||
|
||||
$scope.getCurrentUser = Auth.getCurrentUser;
|
||||
$scope.isLoggedIn = Auth.isLoggedIn;
|
||||
|
@ -1,10 +1,10 @@
|
||||
nav(ng-include='"components/navbar/navbar.html"')
|
||||
|
||||
nav(ng-include='"components/elements/header.html"', onload='title = "documents"')
|
||||
nav(ng-include='"components/elements/header.html"')
|
||||
|
||||
.container
|
||||
.row(ng-show='isLoggedIn()')
|
||||
.col-lg-9.col-md-12.center-block
|
||||
.col-lg-9.col-md-12
|
||||
form.form-inline
|
||||
.form-group
|
||||
label(for='title-input')
|
||||
@ -15,17 +15,27 @@ nav(ng-include='"components/elements/header.html"', onload='title = "documents"'
|
||||
|
||||
.row
|
||||
.col-lg-6.col-md-12(ng-repeat='document in documents | orderBy:"currentRevision.created":true' )
|
||||
h4
|
||||
h1
|
||||
a(href='/{{document._id}}')
|
||||
{{document.title}}
|
||||
div
|
||||
table.revisions
|
||||
tr
|
||||
th.state State
|
||||
th.created revision
|
||||
tr(ng-repeat='revision in document.revisions | orderBy:"created":true | limitTo:5' )
|
||||
td.state {{revision.state}}
|
||||
td.created
|
||||
h4
|
||||
a(href='/{{document._id}}/revision/{{revision._id}}')
|
||||
{{revision.created}}
|
||||
//div
|
||||
p
|
||||
| State:
|
||||
{{document.currentRevision.state}}
|
||||
p
|
||||
| Updated:
|
||||
{{document.currentRevision.created}}
|
||||
pre
|
||||
//pre
|
||||
{{json(document)}}
|
||||
|
||||
|
||||
|
@ -2,8 +2,12 @@
|
||||
|
||||
angular.module('markdownFormatWdiffApp')
|
||||
.controller('DocumentRevisionNewCtrl', function ($scope, $routeParams, $http, Auth, $location) {
|
||||
$scope.title = '';
|
||||
$scope.subtitle = '';
|
||||
|
||||
$scope.revision = {};
|
||||
|
||||
$scope.stateOptions = ['first draft', 'final draft', 'first edit', 'final edit'];
|
||||
|
||||
$scope.getCurrentUser = Auth.getCurrentUser;
|
||||
$scope.isLoggedIn = Auth.isLoggedIn;
|
||||
@ -17,13 +21,16 @@ angular.module('markdownFormatWdiffApp')
|
||||
};
|
||||
|
||||
var path = '/api/documents/' + $routeParams.id;
|
||||
$http.get(path).success(function(revision) {
|
||||
$http.get(path).success(function(document) {
|
||||
$scope.document = document;
|
||||
$scope.revision = angular.copy(document.currentRevision);
|
||||
$scope.title = document.title;
|
||||
$scope.subtitle = 'new revision';
|
||||
});
|
||||
|
||||
|
||||
$scope.saveRevision = function() {
|
||||
alert(JSON.stringify($scope.revision))
|
||||
//save the revision to the document
|
||||
$http.post('/api/documents/'+$routeParams.id+'/revisions', $scope.revision)
|
||||
.success(function(newRevision) {
|
||||
|
@ -1,24 +1,30 @@
|
||||
nav(ng-include='"components/navbar/navbar.html"')
|
||||
|
||||
nav(ng-include='"components/elements/header.html"', ng-onload='title = {{revision.created}}')
|
||||
nav(ng-include='"components/elements/header.html"')
|
||||
|
||||
.container
|
||||
.row
|
||||
form.col-lg-9.col-md-12.center-block
|
||||
.col-lg-6.col-md-12
|
||||
form
|
||||
h4
|
||||
{{revision.document.title}} - {{revision.created}}
|
||||
{{document.title}} - {{revision.created}}
|
||||
.form-group
|
||||
label(for='status-input')
|
||||
| Status
|
||||
input.form-control(type='text', id='status-input', ng-model='revision.status')
|
||||
select.form-control(id='status-input', ng-model='revision.state', ng-options='stateOption as stateOption for stateOption in stateOptions')
|
||||
option(value='{{stateOption}}')
|
||||
//input.form-control(type='text', id='status-input', ng-model='revision.state')
|
||||
.form-group
|
||||
label(for='content-input')
|
||||
| Content
|
||||
textarea.form-control(id='content-input', ng-model='revision.content')
|
||||
button.btn.btn-default(ng-click='saveRevision()')
|
||||
button.btn.btn-primary(ng-click='saveRevision()')
|
||||
| Save
|
||||
|
||||
.row
|
||||
.col-lg-6.col-md-12
|
||||
div(btf-markdown='revision.content')
|
||||
|
||||
//.row
|
||||
pre.col-lg-9.col-md-12.center-block
|
||||
{{json(revision)}}
|
||||
|
||||
|
20
client/app/document/revision-new/revision-new.scss
Normal file
20
client/app/document/revision-new/revision-new.scss
Normal file
@ -0,0 +1,20 @@
|
||||
#content-input {
|
||||
resize: vertical;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: $screen-md-min) {
|
||||
#content-input {
|
||||
resize: vertical;
|
||||
min-height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $screen-lg-min) {
|
||||
#content-input {
|
||||
resize: vertical;
|
||||
min-height: 450px;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ angular.module('markdownFormatWdiffApp')
|
||||
.controller('DocumentRevisionCtrl', function ($scope, $routeParams, $http, Auth) {
|
||||
$scope.revision = {};
|
||||
|
||||
$scope.title = '';
|
||||
$scope.subtitle = '';
|
||||
|
||||
$scope.getCurrentUser = Auth.getCurrentUser;
|
||||
$scope.isLoggedIn = Auth.isLoggedIn;
|
||||
|
||||
@ -27,6 +30,8 @@ angular.module('markdownFormatWdiffApp')
|
||||
var path = '/api/documents/'+$routeParams.id+'/revisions/' + $routeParams.revisionid;
|
||||
$http.get(path).success(function(revision) {
|
||||
$scope.revision = revision;
|
||||
$scope.title = revision.document.title;
|
||||
$scope.subtitle = $scope.isCurrent() ? " (current)":(" ("+$scope.revision.created+")");
|
||||
});
|
||||
|
||||
$scope.json = function (object) { return JSON.stringify(object, null, " "); };
|
||||
|
@ -1,27 +1,22 @@
|
||||
nav(ng-include='"components/navbar/navbar.html"')
|
||||
|
||||
nav(ng-include='"components/elements/header.html"', ng-onload='title = {{revision.created}}')
|
||||
nav(ng-include='"components/elements/header.html"')
|
||||
|
||||
.container
|
||||
.row
|
||||
span(ng-show='isCurrent()')
|
||||
//span(ng-show='isCurrent()')
|
||||
| Current revision
|
||||
a.btn.btn-primary(ng-hide='isCurrent()' href='/wdiff/{{revision._id}}/{{revision.document.currentRevision}}')
|
||||
| wdiff current
|
||||
|
||||
.row
|
||||
.col-lg-6.col-md-9.center-block
|
||||
h4
|
||||
{{revision.created}}
|
||||
.col-lg-6.col-md-9
|
||||
div
|
||||
p
|
||||
| State:
|
||||
{{revision.state}}
|
||||
p
|
||||
| Updated:
|
||||
{{revision.created}}
|
||||
div(btf-markdown='revision.content')
|
||||
pre
|
||||
//pre
|
||||
{{json(revision)}}
|
||||
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
angular.module('markdownFormatWdiffApp')
|
||||
.controller('DocumentShowCtrl', function ($scope, $routeParams, $http, Auth) {
|
||||
$scope.document = {};
|
||||
$scope.title = '';
|
||||
|
||||
$scope.getCurrentUser = Auth.getCurrentUser;
|
||||
$scope.isLoggedIn = Auth.isLoggedIn;
|
||||
@ -19,6 +20,7 @@ angular.module('markdownFormatWdiffApp')
|
||||
var path = '/api/documents/' + $routeParams.id;
|
||||
$http.get(path).success(function(document) {
|
||||
$scope.document = document;
|
||||
$scope.title = document.title;
|
||||
});
|
||||
|
||||
$scope.json = function (object) { return JSON.stringify(object, null, " "); };
|
||||
|
@ -1,26 +1,28 @@
|
||||
nav(ng-include='"components/navbar/navbar.html"')
|
||||
|
||||
nav(ng-include='"components/elements/header.html"', ng-onload='title = {{document.title}}')
|
||||
nav(ng-include='"components/elements/header.html"')
|
||||
|
||||
.container
|
||||
.row(ng-show='isOwner()')
|
||||
form.col-lg-12
|
||||
.col-lg-12
|
||||
form
|
||||
a.btn.btn-primary(href='/{{document._id}}/revision/new')
|
||||
| New Revision
|
||||
|
||||
.row(ng-repeat='revision in document.revisions | orderBy:"created":true' )
|
||||
.row
|
||||
.col-lg-6.col-md-9.center-block
|
||||
|
||||
table.revisions
|
||||
tr
|
||||
th.state State
|
||||
th.created revision
|
||||
tr(ng-repeat='revision in document.revisions | orderBy:"created":true | limitTo:5' )
|
||||
td.state {{revision.state}}
|
||||
td.created
|
||||
h4
|
||||
a(href='/{{document._id}}/revision/{{revision._id}}')
|
||||
{{revision.created}}
|
||||
div
|
||||
p
|
||||
| State:
|
||||
{{revision.state}}
|
||||
p
|
||||
| Updated:
|
||||
{{revision.created}}
|
||||
pre
|
||||
//pre
|
||||
| {{json(revision)}}
|
||||
|
||||
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
angular.module('markdownFormatWdiffApp')
|
||||
.controller('DocumentWdiffCtrl', function ($scope, $routeParams, $http, Auth) {
|
||||
$scope.wdiff = "";
|
||||
$scope.wdiff = '';
|
||||
$scope.title = '';
|
||||
$scope.same = false;
|
||||
$scope.revisionA = {};
|
||||
$scope.revisionB = {};
|
||||
@ -33,6 +34,9 @@ angular.module('markdownFormatWdiffApp')
|
||||
$scope.wdiff = result.wdiff;
|
||||
$scope.revisionA = result.a;
|
||||
$scope.revisionB = result.b;
|
||||
|
||||
$scope.title = result.a.document.title;
|
||||
$scope.subtitle = "wdiff: "+result.a.created + " / " + result.b.created;
|
||||
});
|
||||
|
||||
$scope.json = function (object) { return JSON.stringify(object, null, " "); };
|
||||
|
@ -1,6 +1,6 @@
|
||||
wdiff.jadenav(ng-include='"components/navbar/navbar.html"')
|
||||
|
||||
nav(ng-include='"components/elements/header.html"', ng-onload='title = {{revision.created}}')
|
||||
nav(ng-include='"components/elements/header.html"')
|
||||
|
||||
.container
|
||||
.row
|
||||
@ -8,11 +8,8 @@ nav(ng-include='"components/elements/header.html"', ng-onload='title = {{revisio
|
||||
|
||||
.row
|
||||
.col-lg-6.col-md-9.center-block
|
||||
h4
|
||||
| wdiff {{a.created}} " -- " {{b.created}}
|
||||
div
|
||||
div(btf-markdown='wdiff')
|
||||
pre
|
||||
//pre
|
||||
{{json(result)}}
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
header#banner.hero-unit
|
||||
.container
|
||||
h1 {{title}}
|
||||
h3 {{subtitle}}
|
@ -14,6 +14,7 @@
|
||||
"express-session": "~1.0.2",
|
||||
"jade": "~1.2.0",
|
||||
"jsonwebtoken": "^0.3.0",
|
||||
"lex": "^1.7.8",
|
||||
"lodash": "~2.4.1",
|
||||
"method-override": "~1.0.0",
|
||||
"mongoose": "~3.8.8",
|
||||
|
@ -22,6 +22,7 @@ exports.index = function(req, res) {
|
||||
.find()
|
||||
.populate('owner', '_id name')
|
||||
.populate('currentRevision', '_id state created')
|
||||
.populate('revisions', '_id state created description')
|
||||
.exec(function (err, documents) {
|
||||
if(err) { return handleError(res, err); }
|
||||
return res.json(200, documents);
|
||||
@ -33,6 +34,7 @@ exports.indexForUser = function(req, res) {
|
||||
Document
|
||||
.find({owner: req.params.userid})
|
||||
.populate('owner', '_id name')
|
||||
.populate('revisions', '_id state created description')
|
||||
.populate('currentRevision', '_id state created')
|
||||
.exec(function (err, documents) {
|
||||
if(err) { return handleError(res, err); }
|
||||
@ -189,6 +191,11 @@ exports.createRevision = function(req, res) {
|
||||
//and the date
|
||||
if (req.body.created) { delete req.body.created; }
|
||||
|
||||
//and the id!
|
||||
if (req.body._id) { delete req.body._id; }
|
||||
|
||||
console.log(req.body);
|
||||
|
||||
//get the record for the parent document
|
||||
Document.findById(req.params.id).exec(function(err, document){
|
||||
if (err) { return handleError(res, err); }
|
||||
@ -198,12 +205,22 @@ exports.createRevision = function(req, res) {
|
||||
if (! mongoose.Types.ObjectId(document.owner).equals(req.user._id))
|
||||
{return res.send(401);}
|
||||
|
||||
console.log('---');
|
||||
console.log(document);
|
||||
|
||||
//set the owner and document fields for the revision
|
||||
var revision = _.merge(req.body, {owner: req.user, document: document});
|
||||
|
||||
console.log('---');
|
||||
console.log(revision);
|
||||
|
||||
//create the record
|
||||
Revision.create(revision, function (err, revision) {
|
||||
if(err) { return handleError(res, err); }
|
||||
if (!revision) {return handleError(res, "Unknown error creating revision");}
|
||||
|
||||
console.log('---');
|
||||
console.log(revision);
|
||||
|
||||
//and update the document
|
||||
document.revisions.push(revision);
|
||||
@ -219,12 +236,18 @@ exports.createRevision = function(req, res) {
|
||||
|
||||
//compares two revisions with wdiff
|
||||
exports.wdiff = function(req, res) {
|
||||
Revision.findById(req.params.revisionida).exec(function (err, revisiona) {
|
||||
Revision
|
||||
.findById(req.params.revisionida)
|
||||
.populate('document', 'title')
|
||||
.exec(function (err, revisiona) {
|
||||
if(err) { return handleError(res, err); }
|
||||
if(!revisiona) { return res.send(404); }
|
||||
|
||||
|
||||
Revision.findById(req.params.revisionidb).exec(function (err, revisionb) {
|
||||
Revision
|
||||
.findById(req.params.revisionidb)
|
||||
.populate('document', 'title')
|
||||
.exec(function (err, revisionb) {
|
||||
if(err) { return handleError(res, err); }
|
||||
if(!revisionb) { return res.send(404); }
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
var _ = require('lodash'),
|
||||
temp = require('temp'),
|
||||
fs = require('fs'),
|
||||
exec = require('child_process').exec;
|
||||
exec = require('child_process').exec,
|
||||
Lexer = require('lex');
|
||||
|
||||
// Automatically track and cleanup files at exit
|
||||
temp.track();
|
||||
@ -58,12 +59,9 @@ module.exports = function(a, b, asMarkdown, callback) {
|
||||
if (asMarkdown) {
|
||||
|
||||
//!!! this needs more sophisticated parsing
|
||||
//sub del and ins for the wdiff tags
|
||||
var markdown = stdout;
|
||||
markdown = markdown.replace(/\[-/g, '<del>');
|
||||
markdown = markdown.replace(/-\]/g, '</del>');
|
||||
markdown = markdown.replace(/{\+/g, '<ins>');
|
||||
markdown = markdown.replace(/\+}/g, '</ins>');
|
||||
|
||||
var markdown = rewriteWdiffMarkdown(stdout)
|
||||
|
||||
resData.wdiff=markdown;
|
||||
}
|
||||
|
||||
@ -74,3 +72,178 @@ module.exports = function(a, b, asMarkdown, callback) {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* Rewrites the given wdiff output to correctly render as markdown,
|
||||
assuming the source documents were also valid markdown. */
|
||||
function rewriteWdiffMarkdown(source) {
|
||||
|
||||
//initialize a stack for the lexed input
|
||||
//make it a lodash container, just for kicks
|
||||
var tokens = _([]);
|
||||
|
||||
//define tokens
|
||||
var LDEL = {type:"LDEL"}, RDEL = {type:"RDEL"}, LINS = {type:"LINS"}, RINS = {type:"RINS"};
|
||||
//var STRING = {type: "STRING", value:""};
|
||||
var RDEL_LINS = {type:"RDEL_LINS"};
|
||||
var NEWLINE = {type:"\n"};
|
||||
|
||||
var isStringToken = function (token) { return token.type == "STRING";}
|
||||
|
||||
|
||||
//create a lexer to process the wdiff string
|
||||
var lexer = new Lexer(function (char) {
|
||||
//the default rule creates a string on the stack for unmatched characters
|
||||
//and just adds characters to it as they come in
|
||||
if (tokens.size() == 0 || !isStringToken(tokens.last()))
|
||||
tokens.push({type: "STRING", value:""});
|
||||
|
||||
tokens.last().value += char;
|
||||
});
|
||||
|
||||
//rules for the newline character,
|
||||
//as well as opening and closing (left and right) delete and insert tokens
|
||||
lexer
|
||||
.addRule(/\[-/, function () {
|
||||
tokens.push(LDEL);
|
||||
})
|
||||
.addRule(/-\]/, function () {
|
||||
tokens.push(RDEL);
|
||||
})
|
||||
.addRule(/{\+/, function () {
|
||||
tokens.push(LINS);
|
||||
})
|
||||
.addRule(/\+}/, function () {
|
||||
tokens.push(RINS);
|
||||
})
|
||||
//we have a special rule for joined delete and insert tokens
|
||||
.addRule(/-\] {\+/, function() {
|
||||
tokens.push(RDEL_LINS);
|
||||
})
|
||||
.addRule(/\n/, function () {
|
||||
//tokens.push({type:"STRING", value:"\n"})
|
||||
tokens.push(NEWLINE);
|
||||
})
|
||||
;
|
||||
|
||||
|
||||
//do the lexing
|
||||
lexer.setInput(source);
|
||||
lexer.lex();
|
||||
|
||||
//# now we parse and transform the input
|
||||
|
||||
//create a stack for the transformed output
|
||||
var transform = _([]);
|
||||
|
||||
//set the state variables for the parse
|
||||
var SSTRING = "string", SINS = "ins", SDEL = "del", SDELINS = "delins";
|
||||
var state = SSTRING;
|
||||
|
||||
//this is the index of the immediately previous delete string in the transform stack
|
||||
var deleteStartIndex = -1
|
||||
|
||||
//iterate the input tokens to create the intermediate representation
|
||||
tokens.forEach(function(token) {
|
||||
//we add string tokens to the transformed stack
|
||||
if (isStringToken(token)) {
|
||||
//add the string with state information
|
||||
var item = {
|
||||
string: token.value,
|
||||
state: state
|
||||
};
|
||||
//if this is the DELINS state, we will put the string in the transformed stack in a different order
|
||||
// the INS string is spliced into place just after the first DEL string
|
||||
// the point of this is so that the preceeding markdown formatting instructions
|
||||
// on this line are applied equally to the del and ins strings
|
||||
// an extra space is inserted between DEL and INS items, for readibility
|
||||
if (state == SDELINS) {
|
||||
state = SINS;
|
||||
item.state = SINS;
|
||||
var spaceItem = {string: ' ', state: SSTRING};
|
||||
transform.splice(deleteStartIndex+1, 0, item);
|
||||
transform.splice(deleteStartIndex+1, 0, spaceItem);
|
||||
|
||||
}
|
||||
else {
|
||||
transform.push(item);
|
||||
}
|
||||
}
|
||||
//the various tokens control the transformation mode
|
||||
if (token == LDEL) {
|
||||
state = SDEL;
|
||||
deleteStartIndex = transform.size();
|
||||
}
|
||||
if (token == LINS) {
|
||||
state = SINS;
|
||||
}
|
||||
if (token == RDEL || token == RINS) {
|
||||
state = SSTRING;
|
||||
deleteStartIndex = -1;
|
||||
}
|
||||
if (token == RDEL_LINS) {
|
||||
state = SDELINS;
|
||||
}
|
||||
|
||||
if (token == NEWLINE) {
|
||||
transform.push({string: '\n', state: state});
|
||||
}
|
||||
|
||||
//ignore newlines (they get added to the output)
|
||||
});
|
||||
|
||||
|
||||
// * now emit the output string
|
||||
var output = "";
|
||||
var newline = true;
|
||||
|
||||
// prefixes are matched as follows:
|
||||
// ^ - start of line
|
||||
// ([ \t]*\>)* - blockquotes (possibly nested)
|
||||
// (
|
||||
// ([ \t]*#*) - headers
|
||||
// |([ \t]+[\*\+-]) - unordered lists
|
||||
// |([ \t]+[0-9]+\.) - numeric lists
|
||||
// )?
|
||||
// [ \t]+ - trailing whitespace
|
||||
var PREFIX = /^([ \t]*\>)*(([ \t]*#*)|([ \t]+[\*\+-])|([ \t]+[0-9]+\.))?[ \t]+/
|
||||
//var PREFIX = /^#*/
|
||||
|
||||
|
||||
transform.forEach(function(item) {
|
||||
//newlines are undecorated
|
||||
if (item.string == '\n') {
|
||||
output += '\n';
|
||||
newline = true;
|
||||
return
|
||||
}
|
||||
|
||||
var prestring = "";
|
||||
var poststring = item.string;
|
||||
|
||||
//if this is a newline, we need to peel off any markdown formatting prefixes
|
||||
//and output them outside the del/ins tags
|
||||
if (newline) {
|
||||
var match = item.string.match(PREFIX);
|
||||
if (match == null)
|
||||
prestring ="";
|
||||
else
|
||||
prestring = match[0];
|
||||
|
||||
poststring = item.string.substring(prestring.length);
|
||||
}
|
||||
|
||||
//wrap ins and del strings with tags
|
||||
if (item.state == SDEL)
|
||||
output += prestring+'<del>' + poststring + '</del>';
|
||||
else if (item.state ==SINS)
|
||||
output += prestring+'<ins>' + poststring + '</ins>';
|
||||
|
||||
//and just output other strings
|
||||
else
|
||||
output += prestring+poststring;
|
||||
|
||||
newline = false;
|
||||
});
|
||||
return output;
|
||||
|
||||
}
|
@ -8,5 +8,5 @@ module.exports = {
|
||||
uri: 'mongodb://mongodb/markdownformatwdiff-dev'
|
||||
},
|
||||
|
||||
seedDB: true
|
||||
seedDB: false
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user