normalizeIds.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. const { isObject } = require('../utils/objectUtils');
  2. // ids is of type RelationProperty.
  3. module.exports = (ids, prop, opt) => {
  4. opt = opt || {};
  5. let isComposite = prop.size > 1;
  6. let ret;
  7. if (isComposite) {
  8. // For composite ids these are okay:
  9. //
  10. // 1. [1, 'foo', 4]
  11. // 2. {a: 1, b: 'foo', c: 4}
  12. // 3. [[1, 'foo', 4], [4, 'bar', 1]]
  13. // 4. [{a: 1, b: 'foo', c: 4}, {a: 4, b: 'bar', c: 1}]
  14. //
  15. if (Array.isArray(ids)) {
  16. if (Array.isArray(ids[0])) {
  17. ret = new Array(ids.length);
  18. // 3.
  19. for (let i = 0, l = ids.length; i < l; ++i) {
  20. ret[i] = convertIdArrayToObject(ids[i], prop);
  21. }
  22. } else if (isObject(ids[0])) {
  23. ret = new Array(ids.length);
  24. // 4.
  25. for (let i = 0, l = ids.length; i < l; ++i) {
  26. ret[i] = ensureObject(ids[i], prop);
  27. }
  28. } else {
  29. // 1.
  30. ret = [convertIdArrayToObject(ids, prop)];
  31. }
  32. } else if (isObject(ids)) {
  33. // 2.
  34. ret = [ids];
  35. } else {
  36. throw new Error(`invalid composite key ${JSON.stringify(ids)}`);
  37. }
  38. } else {
  39. // For non-composite ids, these are okay:
  40. //
  41. // 1. 1
  42. // 2. {id: 1}
  43. // 3. [1, 'foo', 4]
  44. // 4. [{id: 1}, {id: 'foo'}, {id: 4}]
  45. //
  46. if (Array.isArray(ids)) {
  47. if (isObject(ids[0])) {
  48. ret = new Array(ids.length);
  49. // 4.
  50. for (let i = 0, l = ids.length; i < l; ++i) {
  51. ret[i] = ensureObject(ids[i]);
  52. }
  53. } else {
  54. ret = new Array(ids.length);
  55. // 3.
  56. for (let i = 0, l = ids.length; i < l; ++i) {
  57. ret[i] = {};
  58. prop.setProp(ret[i], 0, ids[i]);
  59. }
  60. }
  61. } else if (isObject(ids)) {
  62. // 2.
  63. ret = [ids];
  64. } else {
  65. // 1.
  66. const obj = {};
  67. prop.setProp(obj, 0, ids);
  68. ret = [obj];
  69. }
  70. }
  71. checkProperties(ret, prop);
  72. if (opt.arrayOutput) {
  73. return normalizedToArray(ret, prop);
  74. } else {
  75. return ret;
  76. }
  77. };
  78. function convertIdArrayToObject(ids, prop) {
  79. if (!Array.isArray(ids)) {
  80. throw new Error(`invalid composite key ${JSON.stringify(ids)}`);
  81. }
  82. if (ids.length != prop.size) {
  83. throw new Error(`composite identifier ${JSON.stringify(ids)} should have ${prop.size} values`);
  84. }
  85. const obj = {};
  86. for (let i = 0; i < ids.length; ++i) {
  87. prop.setProp(obj, i, ids[i]);
  88. }
  89. return obj;
  90. }
  91. function ensureObject(ids) {
  92. if (isObject(ids)) {
  93. return ids;
  94. } else {
  95. throw new Error(`invalid composite key ${JSON.stringify(ids)}`);
  96. }
  97. }
  98. function checkProperties(ret, prop) {
  99. for (let i = 0, l = ret.length; i < l; ++i) {
  100. const obj = ret[i];
  101. for (let j = 0, lp = prop.size; j < lp; ++j) {
  102. const val = prop.getProp(obj, j);
  103. if (typeof val === 'undefined') {
  104. throw new Error(
  105. `expected id ${JSON.stringify(obj)} to have property ${prop.propDescription(j)}`
  106. );
  107. }
  108. }
  109. }
  110. }
  111. function normalizedToArray(ret, prop) {
  112. const arr = new Array(ret.length);
  113. for (let i = 0, l = ret.length; i < l; ++i) {
  114. arr[i] = prop.getProps(ret[i]);
  115. }
  116. return arr;
  117. }