build-two-headed-schema-cursor.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /**
  2. * Module dependencies
  3. */
  4. var _ = require('@sailshq/lodash');
  5. var TYPES = require('./types');
  6. /**
  7. * Builds a two-headed cursor useful for comparing type schemas.
  8. *
  9. * @param {[type]} isExemplar
  10. * @param {[type]} onFacetDict [description]
  11. * @param {[type]} onPatternArray [description]
  12. * @param {[type]} onGenericDict [description]
  13. * @param {[type]} onGenericArray [description]
  14. * @param {[type]} onJson [description]
  15. * @param {[type]} onRef [description]
  16. * @param {[type]} onLamda [description]
  17. * @param {[type]} onString [description]
  18. * @param {[type]} onNumber [description]
  19. * @param {[type]} onBoolean [description]
  20. * @return {[type]} [description]
  21. */
  22. module.exports = function buildTwoHeadedSchemaCursor(isExemplar, onFacetDict, onPatternArray, onGenericDict, onGenericArray, onJson, onRef, onLamda, onString, onNumber, onBoolean) {
  23. // If the `isExemplar` option is set, then the provided values will be
  24. // treated as exemplars instead of type schemas.
  25. isExemplar = !!isExemplar;
  26. // exemplar-vs-type-schema-agnostic type check helper
  27. function thisSchema(schema){
  28. return {
  29. is: function (){
  30. var acceptableTypes = Array.prototype.slice.call(arguments);
  31. if (!isExemplar) {
  32. return _.contains(acceptableTypes, schema);
  33. }
  34. return _.any(acceptableTypes, function (typeName){
  35. return TYPES[typeName].isExemplar(schema);
  36. });
  37. }
  38. };
  39. }
  40. function _iterator(subSchema0, subSchema1, keyOrIndex){
  41. if (_.isArray(subSchema0)) {
  42. if (_.isEqual(subSchema0, [])) {
  43. return onGenericArray(subSchema0, subSchema1, keyOrIndex);
  44. }
  45. return onPatternArray(subSchema0, subSchema1, keyOrIndex, function (nextIndex){
  46. var nextSchema0 = subSchema0[nextIndex];
  47. var nextSchema1 = subSchema1[nextIndex];
  48. return _iterator(nextSchema0, nextSchema1, nextIndex);
  49. });
  50. }
  51. else if (_.isObject(subSchema0)) {
  52. if (_.isEqual(subSchema0, {})) {
  53. return onGenericDict(subSchema0, subSchema1, keyOrIndex);
  54. }
  55. return onFacetDict(subSchema0, subSchema1, keyOrIndex, function (nextKey) {
  56. var nextSchema0 = subSchema0[nextKey];
  57. var nextSchema1 = subSchema1[nextKey];
  58. return _iterator(nextSchema0, nextSchema1, nextKey);
  59. });
  60. }
  61. else if ( thisSchema(subSchema0).is('json') ) {
  62. return onJson(subSchema0, subSchema1, keyOrIndex);
  63. }
  64. else if ( thisSchema(subSchema0).is('boolean') ) {
  65. return onBoolean(subSchema0, subSchema1, keyOrIndex);
  66. }
  67. else if ( thisSchema(subSchema0).is('number') ) {
  68. return onNumber(subSchema0, subSchema1, keyOrIndex);
  69. }
  70. else if ( thisSchema(subSchema0).is('string') ) {
  71. return onString(subSchema0, subSchema1, keyOrIndex);
  72. }
  73. else if ( thisSchema(subSchema0).is('lamda') ) {
  74. return onLamda(subSchema0, subSchema1, keyOrIndex);
  75. }
  76. else if ( thisSchema(subSchema0).is('ref') ) {
  77. return onRef(subSchema0, subSchema1, keyOrIndex);
  78. }
  79. else {
  80. throw new Error('Unrecognized type.');
  81. }
  82. }
  83. /**
  84. * @param {*} thingToTraverse0
  85. * @param {*} thingToTraverse1
  86. * @return {*}
  87. */
  88. return function (thingToTraverse0, thingToTraverse1){
  89. return _iterator(thingToTraverse0, thingToTraverse1);
  90. };
  91. };