Add DateString type
New type that preserves string input as a string, but ensures that the string is a valid Date. Additionally, provides a .toDate function to provide the Date object representation of the string.
This commit is contained in:
parent
97f243f347
commit
5e80837424
|
@ -0,0 +1,99 @@
|
||||||
|
// Copyright IBM Corp. 2013,2016. All Rights Reserved.
|
||||||
|
// Node module: loopback-datasource-juggler
|
||||||
|
// This file is licensed under the MIT License.
|
||||||
|
// License text available at https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var inspect = require('util').inspect;
|
||||||
|
|
||||||
|
module.exports = DateString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A String whose value is a valid representation of a Date.
|
||||||
|
* Use this type if you need to preserve the format of the value and still
|
||||||
|
* check if it's valid.
|
||||||
|
* Example:
|
||||||
|
* ```js
|
||||||
|
* var loopback = require('loopback');
|
||||||
|
* var dt = new loopback.DateString('2001-01-01');
|
||||||
|
*
|
||||||
|
* dt.toString();
|
||||||
|
* // '2001-01-01'
|
||||||
|
* dt._date.toISOString();
|
||||||
|
* // '2001-01-01T00:00:00.000Z'
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* You can use this definition on your models as well:
|
||||||
|
* ```json
|
||||||
|
* {
|
||||||
|
* "name": "Person",
|
||||||
|
* "base": "PersistedModel",
|
||||||
|
* "properties": {
|
||||||
|
* "name": {
|
||||||
|
* "type": "string"
|
||||||
|
* },
|
||||||
|
* "dob": {
|
||||||
|
* "type": "DateString",
|
||||||
|
* "required": true
|
||||||
|
* },
|
||||||
|
* },
|
||||||
|
* "validations": [],
|
||||||
|
* "relations": {},
|
||||||
|
* "acls": [],
|
||||||
|
* "methods": {}
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* @class DateString
|
||||||
|
* @param {String} value
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function DateString(value) {
|
||||||
|
if (!(this instanceof DateString)) {
|
||||||
|
return new DateString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof(value) !== 'string') {
|
||||||
|
throw new Error('Input must be a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'when', {
|
||||||
|
get: () => { return this._when; },
|
||||||
|
set: (val) => {
|
||||||
|
var d = new Date(val);
|
||||||
|
if (isNaN(d.getTime())) {
|
||||||
|
throw new Error('Invalid date');
|
||||||
|
} else {
|
||||||
|
this._when = val;
|
||||||
|
this._date = d;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.when = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of DateString in its original form.
|
||||||
|
* @returns {String} The Date as a String.
|
||||||
|
*/
|
||||||
|
DateString.prototype.toString = function() {
|
||||||
|
return this.when;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the JSON representation of the DateString object.
|
||||||
|
* @returns {String} A JSON string.
|
||||||
|
*/
|
||||||
|
DateString.prototype.toJSON = function() {
|
||||||
|
return JSON.stringify({
|
||||||
|
when: this.when,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
DateString.prototype.inspect = function(depth, options) {
|
||||||
|
return 'DateString ' + inspect({
|
||||||
|
when: this.when,
|
||||||
|
_date: this._date,
|
||||||
|
});
|
||||||
|
};
|
|
@ -40,6 +40,7 @@ Types.Any.prototype.toObject = Types.Any.prototype.toJSON = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = function(modelTypes) {
|
module.exports = function(modelTypes) {
|
||||||
|
var DateString = require('./date-string');
|
||||||
var GeoPoint = require('./geo').GeoPoint;
|
var GeoPoint = require('./geo').GeoPoint;
|
||||||
|
|
||||||
for (var t in Types) {
|
for (var t in Types) {
|
||||||
|
@ -63,6 +64,7 @@ module.exports = function(modelTypes) {
|
||||||
modelTypes.registerType(Number);
|
modelTypes.registerType(Number);
|
||||||
modelTypes.registerType(Boolean);
|
modelTypes.registerType(Boolean);
|
||||||
modelTypes.registerType(Date);
|
modelTypes.registerType(Date);
|
||||||
|
modelTypes.registerType(DateString);
|
||||||
modelTypes.registerType(Buffer, ['Binary']);
|
modelTypes.registerType(Buffer, ['Binary']);
|
||||||
modelTypes.registerType(Array);
|
modelTypes.registerType(Array);
|
||||||
modelTypes.registerType(GeoPoint);
|
modelTypes.registerType(GeoPoint);
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
|
||||||
|
// Node module: loopback-datasource-juggler
|
||||||
|
// This file is licensed under the MIT License.
|
||||||
|
// License text available at https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
/* global describe,it */
|
||||||
|
/* jshint expr:true */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('should');
|
||||||
|
|
||||||
|
var DateString = require('../lib/date-string');
|
||||||
|
var fmt = require('util').format;
|
||||||
|
var inspect = require('util').inspect;
|
||||||
|
var os = require('os');
|
||||||
|
|
||||||
|
describe('DateString', function() {
|
||||||
|
describe('constructor', function() {
|
||||||
|
it('should support a valid date string', function() {
|
||||||
|
var theDate = '2015-01-01';
|
||||||
|
var date = new DateString(theDate);
|
||||||
|
date.should.not.eql(null);
|
||||||
|
date.when.should.eql(theDate);
|
||||||
|
date.toString().should.eql(theDate);
|
||||||
|
});
|
||||||
|
|
||||||
|
testValidInput('should allow date with time', '2015-01-01 02:00:00');
|
||||||
|
testValidInput('should allow full UTC datetime', '2015-06-30T20:00:00.000Z');
|
||||||
|
testValidInput('should allow date with UTC offset', '2015-01-01 20:00:00 GMT-5');
|
||||||
|
|
||||||
|
testInvalidInput('should throw on non-date string', 'notadate', 'Invalid date');
|
||||||
|
testInvalidInput('should throw on incorrect date-like value',
|
||||||
|
'2015-01-01 25:00:00', 'Invalid date');
|
||||||
|
testInvalidInput('should throw on non-string input', 20150101,
|
||||||
|
'Input must be a string');
|
||||||
|
testInvalidInput('should throw on null input', null, 'Input must be a string');
|
||||||
|
|
||||||
|
it('should update internal date on set', function() {
|
||||||
|
var date = new DateString('2015-01-01');
|
||||||
|
date.when = '2016-01-01';
|
||||||
|
date.when.should.eql('2016-01-01');
|
||||||
|
var d = new Date('2016-01-01');
|
||||||
|
// The internal date representation should also be updated!
|
||||||
|
date._date.toString().should.eql(d.toString());
|
||||||
|
});
|
||||||
|
it('should return custom inspect output', function() {
|
||||||
|
var date = new DateString('2015-01-01');
|
||||||
|
var result = inspect(date);
|
||||||
|
result.should.not.eql(null);
|
||||||
|
result.should.eql(fmt('DateString ' + inspect({
|
||||||
|
when: date.when,
|
||||||
|
_date: date._date,
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return JSON output', function() {
|
||||||
|
var date = new DateString('2015-01-01');
|
||||||
|
var result = date.toJSON();
|
||||||
|
result.should.eql(JSON.stringify({when: date.when}));
|
||||||
|
});
|
||||||
|
|
||||||
|
function testValidInput(msg, val) {
|
||||||
|
it(msg, function() {
|
||||||
|
var theDate = new DateString(val);
|
||||||
|
theDate.when.should.eql(val);
|
||||||
|
var d = new Date(val);
|
||||||
|
theDate._date.toString().should.eql(d.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInvalidInput(msg, val, err) {
|
||||||
|
it(msg, () => {
|
||||||
|
var fn = () => {
|
||||||
|
var theDate = new DateString(val);
|
||||||
|
};
|
||||||
|
fn.should.throw(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue