Skip to content

Commit

Permalink
Improved NodeJS support for uuid
Browse files Browse the repository at this point in the history
  • Loading branch information
amarzavery committed Mar 4, 2016
1 parent f6edb1b commit 309b3a2
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3603,7 +3603,7 @@ ArrayModel.prototype.getUuidValid = function (options, callback) {
name: 'Sequence',
element: {
required: false,
serializedName: 'StringElementType',
serializedName: 'UuidElementType',
type: {
name: 'String'
}
Expand Down Expand Up @@ -3663,8 +3663,8 @@ ArrayModel.prototype.putUuidValid = function (arrayBody, options, callback) {
throw new Error('arrayBody cannot be null or undefined and it must be of type array.');
}
for (var i = 0; i < arrayBody.length; i++) {
if (arrayBody[i] !== null && arrayBody[i] !== undefined && typeof arrayBody[i].valueOf() !== 'string') {
throw new Error('arrayBody[i] must be of type string.');
if (arrayBody[i] !== null && arrayBody[i] !== undefined && !(typeof arrayBody[i].valueOf() === 'string' && msRest.isValidUuid(arrayBody[i]))) {
throw new Error('arrayBody[i] must be of type string and must be a valid uuid.');
}
}
} catch (error) {
Expand Down Expand Up @@ -3704,7 +3704,7 @@ ArrayModel.prototype.putUuidValid = function (arrayBody, options, callback) {
name: 'Sequence',
element: {
required: false,
serializedName: 'StringElementType',
serializedName: 'UuidElementType',
type: {
name: 'String'
}
Expand Down Expand Up @@ -3859,7 +3859,7 @@ ArrayModel.prototype.getUuidInvalidChars = function (options, callback) {
name: 'Sequence',
element: {
required: false,
serializedName: 'StringElementType',
serializedName: 'UuidElementType',
type: {
name: 'String'
}
Expand Down
19 changes: 18 additions & 1 deletion AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ private static string ValidatePrimaryType(this PrimaryType primary, IScopeProvid
builder.AppendLine("if ({0} !== null && {0} !== undefined && typeof {0}.valueOf() !== '{1}') {{", valueReference, lowercaseTypeName);
return ConstructValidationCheck(builder, typeErrorMessage, valueReference, primary.Name).ToString();
}
else if (primary.Type == KnownPrimaryType.String || primary.Type == KnownPrimaryType.Uuid) //treat Uuid as strings in NodeJS
else if (primary.Type == KnownPrimaryType.String)
{
if (isRequired)
{
Expand All @@ -223,6 +223,19 @@ private static string ValidatePrimaryType(this PrimaryType primary, IScopeProvid
builder.AppendLine("if ({0} !== null && {0} !== undefined && typeof {0}.valueOf() !== '{1}') {{", valueReference, lowercaseTypeName);
return ConstructValidationCheck(builder, typeErrorMessage, valueReference, primary.Name).ToString();
}
else if (primary.Type == KnownPrimaryType.Uuid)
{
if (isRequired)
{
requiredTypeErrorMessage = "throw new Error('{0} cannot be null or undefined and it must be of type string and must be a valid {1}.');";
//empty string can be a valid value hence we cannot implement the simple check if (!{0})
builder.AppendLine("if ({0} === null || {0} === undefined || typeof {0}.valueOf() !== 'string' || !msRest.isValidUuid({0})) {{", valueReference);
return ConstructValidationCheck(builder, requiredTypeErrorMessage, valueReference, primary.Name).ToString();
}
typeErrorMessage = "throw new Error('{0} must be of type string and must be a valid {1}.');";
builder.AppendLine("if ({0} !== null && {0} !== undefined && !(typeof {0}.valueOf() === 'string' && msRest.isValidUuid({0}))) {{", valueReference);
return ConstructValidationCheck(builder, typeErrorMessage, valueReference, primary.Name).ToString();
}
else if (primary.Type == KnownPrimaryType.ByteArray)
{
if (isRequired)
Expand Down Expand Up @@ -735,6 +748,10 @@ public static string ConstructMapper(this IType type, string serializedName, IPa
{
builder.AppendLine("type: {").Indent().AppendLine("name: 'String'").Outdent().AppendLine("}");
}
else if (primary.Type == KnownPrimaryType.Uuid)
{
builder.AppendLine("type: {").Indent().AppendLine("name: 'Uuid'").Outdent().AppendLine("}");
}
else if (primary.Type == KnownPrimaryType.ByteArray)
{
builder.AppendLine("type: {").Indent().AppendLine("name: 'ByteArray'").Outdent().AppendLine("}");
Expand Down
2 changes: 1 addition & 1 deletion AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ private static IType NormalizePrimaryType(PrimaryType primaryType)
}
else if (primaryType.Type == KnownPrimaryType.Uuid)
{
primaryType.Name = "String";
primaryType.Name = "Uuid";
}
else if (primaryType.Type == KnownPrimaryType.Object)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1182,7 +1182,8 @@ def get_uuid_valid(
:param dict custom_headers: headers that will be added to the request
:param boolean raw: returns the direct response alongside the
deserialized response
:rtype: list or msrest.pipeline.ClientRawResponse
:rtype: list
:rtype: msrest.pipeline.ClientRawResponse if raw=True
"""
# Construct URL
url = '/array/prim/uuid/valid'
Expand Down Expand Up @@ -1226,7 +1227,8 @@ def put_uuid_valid(
:param dict custom_headers: headers that will be added to the request
:param boolean raw: returns the direct response alongside the
deserialized response
:rtype: None or msrest.pipeline.ClientRawResponse
:rtype: None
:rtype: msrest.pipeline.ClientRawResponse if raw=True
"""
# Construct URL
url = '/array/prim/uuid/valid'
Expand Down Expand Up @@ -1263,7 +1265,8 @@ def get_uuid_invalid_chars(
:param dict custom_headers: headers that will be added to the request
:param boolean raw: returns the direct response alongside the
deserialized response
:rtype: list or msrest.pipeline.ClientRawResponse
:rtype: list
:rtype: msrest.pipeline.ClientRawResponse if raw=True
"""
# Construct URL
url = '/array/prim/uuid/invalidchars'
Expand Down
2 changes: 1 addition & 1 deletion ClientRuntimes/NodeJS/ms-rest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var msrest = require('ms-rest');
## Serialization/Deserialization
Features
- Type checking
- (String, Number, Boolean, ByteArray, Date, DateTime, Enum, TimeSpan, DateTimeRfc1123, Object, Stream, Sequence, Dictionary, Composite)
- (String, Number, Boolean, ByteArray, Date, DateTime, Enum, TimeSpan, DateTimeRfc1123, Object, Stream, Sequence, Dictionary, Composite, Uuid(as a string))
- Validation of specified constraints
- ExclusiveMaximum, ExclusiveMinimum, InclusiveMaximum, InclusiveMinimum, MaxItems, MaxLength, MinItems, MinLength, MultipleOf, Pattern, UniqueItems
- Flattening/Unflattening properties
Expand Down
1 change: 1 addition & 0 deletions ClientRuntimes/NodeJS/ms-rest/lib/msRest.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ exports.ExponentialRetryPolicyFilter = require('./filters/exponentialRetryPolicy
exports.requestPipeline = require('./requestPipeline');
exports.stripResponse = utils.stripResponse;
exports.stripRequest = utils.stripRequest;
exports.isValidUuid = utils.isValidUuid;

//serialization
exports.serializeObject = require('./serialization').serializeObject;
Expand Down
15 changes: 10 additions & 5 deletions ClientRuntimes/NodeJS/ms-rest/lib/serialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
var util = require('util');
var moment = require('moment');
var stream = require('stream');
var utils = require('./utils');

/**
* Serializes the JSON Object. It serializes Buffer object to a
Expand Down Expand Up @@ -69,7 +70,7 @@ exports.serialize = function (mapper, object, objectName) {
if (mapper.isConstant) object = mapper.defaultValue;
//Validate Constraints if any
validateConstraints.call(this, mapper, object, objectName);
if (mapperType.match(/^(Number|String|Boolean|Object|Stream)$/ig) !== null) {
if (mapperType.match(/^(Number|String|Boolean|Object|Stream|Uuid)$/ig) !== null) {
payload = serializeBasicTypes.call(this, mapperType, objectName, object);
} else if (mapperType.match(/^Enum$/ig) !== null) {
payload = serializeEnumType.call(this, objectName, mapper.type.allowedValues, object);
Expand Down Expand Up @@ -283,15 +284,19 @@ function serializeBasicTypes(typeName, objectName, value) {
if (value !== null && value !== undefined) {
if (typeName.match(/^Number$/ig) !== null) {
if (typeof value !== 'number') {
throw new Error(util.format('%s must be of type number.', objectName));
throw new Error(util.format('%s with value %s must be of type number.', objectName, value));
}
} else if (typeName.match(/^String$/ig) !== null) {
if (typeof value.valueOf() !== 'string') {
throw new Error(util.format('%s must be of type string.', objectName));
throw new Error(util.format('%s with value \'%s\' must be of type string.', objectName, value));
}
} else if (typeName.match(/^Uuid$/ig) !== null) {
if (!(typeof value.valueOf() === 'string' && utils.isValidUuid(value))) {
throw new Error(util.format('%s with value \'%s\' must be of type string and a valid uuid.', objectName, value));
}
} else if (typeName.match(/^Boolean$/ig) !== null) {
if (typeof value !== 'boolean') {
throw new Error(util.format('%s must be of type boolean.', objectName));
throw new Error(util.format('%s with value %s must be of type boolean.', objectName, value));
}
} else if (typeName.match(/^Object$/ig) !== null) {
if (typeof value !== 'object') {
Expand Down Expand Up @@ -375,7 +380,7 @@ exports.deserialize = function (mapper, responseBody, objectName) {
if (!objectName) objectName = mapper.serializedName;
if (mapperType.match(/^Sequence$/ig) !== null) payload = [];

if (mapperType.match(/^(Number|String|Boolean|Enum|Object|Stream)$/ig) !== null) {
if (mapperType.match(/^(Number|String|Boolean|Enum|Object|Stream|Uuid)$/ig) !== null) {
payload = responseBody;
} else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/ig) !== null) {
payload = new Date(responseBody);
Expand Down
12 changes: 12 additions & 0 deletions ClientRuntimes/NodeJS/ms-rest/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,16 @@ exports.stripRequest = function (request) {
return strippedRequest;
};

/**
* Validates the given uuid as a string
*
* @param {string} uuid - The uuid as a string that needs to be validated
*
* @return {boolean} result - True if the uuid is valid; false otherwise.
*/
exports.isValidUuid = function(uuid) {
var validUuidRegex = new RegExp('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$', 'ig');
return validUuidRegex.test(uuid);
};

exports = module.exports;
3 changes: 2 additions & 1 deletion ClientRuntimes/NodeJS/ms-rest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"jshint": "2.6.3",
"xunit-file": "0.0.5",
"mocha": "2.2.5",
"should": "5.2.0"
"should": "5.2.0",
"node-uuid": "*"
},
"homepage": "https://github.com/Azure/AutoRest",
"repository": {
Expand Down
23 changes: 23 additions & 0 deletions ClientRuntimes/NodeJS/ms-rest/test/serializationTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var msRest = require('../lib/msRest');
var testClient = require('./data/TestClient/lib/testClient');

var tokenCredentials = new msRest.TokenCredentials('dummy');
var valid_uuid = 'ceaafd1e-f936-429f-bbfc-82ee75dddc33';

describe('msrest', function () {
describe('serializeObject', function () {
Expand Down Expand Up @@ -115,12 +116,28 @@ describe('msrest', function () {

describe('serialize', function () {
var mapper = {};
var invalid_uuid = 'abcd-efgd90-90890jkh';
it('should correctly serialize a string', function (done) {
mapper = { type : { name: 'String' } };
var serializedObject = msRest.serialize(mapper, 'foo', 'stringBody');
serializedObject.should.equal('foo');
done();
});
it('should correctly serialize a uuid', function (done) {
mapper = { type : { name: 'Uuid' } };
var serializedObject = msRest.serialize(mapper, valid_uuid, 'uuidBody');
serializedObject.should.equal(valid_uuid);
done();
});
it('should throw an error if the value is not a valid Uuid', function (done) {
mapper = { type : { name: 'Uuid' } };
try {
var serializedObject = msRest.serialize(mapper, invalid_uuid, 'uuidBody');
} catch (error) {
error.message.should.match(/.*with value.*must be of type string and a valid uuid/ig);
done();
}
});
it('should correctly serialize a number', function (done) {
mapper = { type : { name: 'Number' } };
var serializedObject = msRest.serialize(mapper, 1.506, 'stringBody');
Expand Down Expand Up @@ -372,6 +389,12 @@ describe('msrest', function () {
});

describe('deserialize', function () {
it('should correctly deserialize a uuid', function (done) {
mapper = { type : { name: 'Uuid' } };
var serializedObject = msRest.deserialize(mapper, valid_uuid, 'uuidBody');
serializedObject.should.equal(valid_uuid);
done();
});
it('should correctly deserialize a composite type', function (done) {
var client = new testClient('http://localhost:9090');
var product = new client.models['Product']();
Expand Down

0 comments on commit 309b3a2

Please sign in to comment.