get-display-type-label.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /**
  2. * Module dependencies
  3. */
  4. var _ = require('@sailshq/lodash');
  5. var getRdt = require('./get-rdt');
  6. /**
  7. * Given an RTTC "display type" aka "typeclass" string,
  8. * return the appropriate human-readable label for that type.
  9. * Useful for error messages, user interfaces, etc.
  10. *
  11. *
  12. * @param {String} type
  13. * Recognizes any of the standard RTTC types:
  14. * • string
  15. * • number
  16. * • boolean
  17. * • lamda
  18. * • dictionary
  19. * • array
  20. * • json
  21. * • ref
  22. *
  23. * (Also tolerates type schemas.)
  24. *
  25. * @optional {Dictionary} options
  26. *
  27. * @property {Boolean} plural
  28. * If enabled, the returned display type will be plural.
  29. * @default false
  30. *
  31. * @property {String} capitalization
  32. * One of:
  33. * • "title" (e.g. "JSON-Compatible Value", or "String")
  34. * • "start" (e.g. "JSON-compatible value", or "String")
  35. * • "fragment" (e.g. "JSON-compatible value", or "string")
  36. * @default "title"
  37. *
  38. *
  39. * @return {String}
  40. */
  41. module.exports = function getDisplayTypeLabel(type, options){
  42. if (typeof type === 'string') {
  43. // OK! This is probably an RDT, so we'll try it.
  44. } else if (!!type && typeof type === 'object') {
  45. // This might be a type schema, so we'll parsing an RDT from it first and use that.
  46. type = getRdt(type);
  47. } else {
  48. throw new Error('Usage error: rttc.getDisplayTypeLabel() expects a string display type such as '+
  49. '`dictionary` or `ref`. If you are trying to get the display type label for an exemplar, do '+
  50. '`rttc.getDisplayTypeLabel(rttc.inferDisplayType(exemplar))`. If you are trying to get a display '+
  51. 'type label to represent voidness (i.e. a null exemplar), then you should determine that on a '+
  52. 'case-by-case basis-- there\'s no good sane default.');
  53. }
  54. // Set up defaults
  55. options = options || {};
  56. options = _.defaults(options, {
  57. plural: false,
  58. capitalization: 'title'
  59. });
  60. if (!_.contains(['title', 'start', 'fragment'], options.capitalization)) {
  61. throw new Error('Usage error: Unrecognized `capitalization` option: `'+options.capitalization+'`. '+
  62. 'Should be either "title", "start", or "fragment". (defaults to "title")');
  63. }
  64. if (type === 'string') {
  65. switch (options.capitalization) {
  66. case 'title':
  67. case 'start': return !options.plural ? 'String' : 'Strings';
  68. case 'fragment': return !options.plural ? 'string' : 'strings';
  69. }
  70. }
  71. else if (type === 'number') {
  72. switch (options.capitalization) {
  73. case 'title':
  74. case 'start': return !options.plural ? 'Number' : 'Numbers';
  75. case 'fragment': return !options.plural ? 'number' : 'numbers';
  76. }
  77. }
  78. else if (type === 'boolean') {
  79. switch (options.capitalization) {
  80. case 'title':
  81. case 'start': return !options.plural ? 'Boolean' : 'Booleans';
  82. case 'fragment': return !options.plural ? 'boolean' : 'booleans';
  83. }
  84. }
  85. else if (type === 'lamda') {
  86. switch (options.capitalization) {
  87. case 'title':
  88. case 'start': return !options.plural ? 'Function' : 'Functions';
  89. case 'fragment': return !options.plural ? 'function' : 'functions';
  90. }
  91. }
  92. else if (type === 'dictionary') {
  93. switch (options.capitalization) {
  94. case 'title':
  95. case 'start': return !options.plural ? 'Dictionary' : 'Dictionaries';
  96. case 'fragment': return !options.plural ? 'dictionary' : 'dictionaries';
  97. }
  98. }
  99. else if (type === 'array') {
  100. switch (options.capitalization) {
  101. case 'title':
  102. case 'start': return !options.plural ? 'Array' : 'Arrays';
  103. case 'fragment': return !options.plural ? 'array' : 'arrays';
  104. }
  105. }
  106. else if (type === 'json') {
  107. switch (options.capitalization) {
  108. case 'title': return !options.plural ? 'JSON-Compatible Value' : 'JSON-Compatible Values';
  109. case 'start':
  110. case 'fragment': return !options.plural ? 'JSON-compatible value' : 'JSON-compatible values';
  111. }
  112. }
  113. else if (type === 'ref') {
  114. switch (options.capitalization) {
  115. case 'title': return !options.plural ? 'Value' : 'Values';
  116. case 'start': return !options.plural ? 'Value' : 'Values';
  117. case 'fragment': return !options.plural ? 'value' : 'values';
  118. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  119. // Note: This was changed for flexibility. Here's the old way, for reference:
  120. // ```
  121. // case 'title': return !options.plural ? 'Anything' : 'Any Values';
  122. // case 'start': return !options.plural ? 'Value of any type' : 'Values of any type';
  123. // case 'fragment': return !options.plural ? 'value of any type' : 'values of any type';
  124. // ```
  125. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  126. }
  127. }
  128. else {
  129. throw new Error('Unknown type: `'+type+'`');
  130. }
  131. // (should never make it here!)
  132. throw new Error('Consistency violation: Could not get display type due to an internal error in RTTC.');
  133. };