validate-projection-schema.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import {InvalidArgumentError} from '@e22m4u/js-format';
  2. /**
  3. * Validate projection schema.
  4. *
  5. * @param {object|Function|string} schema
  6. * @param {boolean} [shallowMode]
  7. */
  8. export function validateProjectionSchema(schema, shallowMode = false) {
  9. // schema
  10. if (
  11. !schema ||
  12. (typeof schema !== 'object' &&
  13. typeof schema !== 'function' &&
  14. typeof schema !== 'string') ||
  15. Array.isArray(schema)
  16. ) {
  17. throw new InvalidArgumentError(
  18. 'Projection schema must be an Object, a Function ' +
  19. 'or a non-empty String, but %v was given.',
  20. schema,
  21. );
  22. }
  23. if (typeof schema !== 'object') {
  24. return;
  25. }
  26. // schema[k]
  27. Object.keys(schema).forEach(propName => {
  28. const propOptions = schema[propName];
  29. if (propOptions === undefined) {
  30. return;
  31. }
  32. if (
  33. propOptions === null ||
  34. (typeof propOptions !== 'object' && typeof propOptions !== 'boolean') ||
  35. Array.isArray(propOptions)
  36. ) {
  37. throw new InvalidArgumentError(
  38. 'Property options must be an Object or a Boolean, but %v was given.',
  39. propOptions,
  40. );
  41. }
  42. if (typeof propOptions === 'boolean') {
  43. return;
  44. }
  45. // schema[k].select
  46. if (
  47. propOptions.select !== undefined &&
  48. typeof propOptions.select !== 'boolean'
  49. ) {
  50. throw new InvalidArgumentError(
  51. 'Property option "select" must be a Boolean, but %v was given.',
  52. propOptions.select,
  53. );
  54. }
  55. // schema[k].scopes
  56. if (propOptions.scopes !== undefined) {
  57. if (
  58. !propOptions.scopes ||
  59. typeof propOptions.scopes !== 'object' ||
  60. Array.isArray(propOptions.scopes)
  61. ) {
  62. throw new InvalidArgumentError(
  63. 'Property option "scopes" must be an Object, but %v was given.',
  64. propOptions.scopes,
  65. );
  66. }
  67. Object.values(propOptions.scopes).forEach(scopeOptions => {
  68. if (scopeOptions === undefined) {
  69. return;
  70. }
  71. // schema[k].scopes[k]
  72. if (
  73. scopeOptions === null ||
  74. (typeof scopeOptions !== 'object' &&
  75. typeof scopeOptions !== 'boolean') ||
  76. Array.isArray(scopeOptions)
  77. ) {
  78. throw new InvalidArgumentError(
  79. 'Scope options must be an Object or a Boolean, but %v was given.',
  80. scopeOptions,
  81. );
  82. }
  83. // schema[k].scopes[k].select
  84. if (
  85. scopeOptions.select !== undefined &&
  86. typeof scopeOptions.select !== 'boolean'
  87. ) {
  88. throw new InvalidArgumentError(
  89. 'Scope option "select" must be a Boolean, but %v was given.',
  90. scopeOptions.select,
  91. );
  92. }
  93. });
  94. }
  95. // schema[k].schema
  96. if (propOptions.schema !== undefined) {
  97. if (
  98. !propOptions.schema ||
  99. (typeof propOptions.schema !== 'object' &&
  100. typeof propOptions.schema !== 'function' &&
  101. typeof propOptions.schema !== 'string') ||
  102. Array.isArray(propOptions.schema)
  103. ) {
  104. throw new InvalidArgumentError(
  105. 'Property option "schema" must be an Object, a Function' +
  106. ' or a non-empty String, but %v was given.',
  107. propOptions.schema,
  108. );
  109. }
  110. if (!shallowMode && typeof propOptions.schema === 'object') {
  111. validateProjectionSchema(propOptions.schema, shallowMode);
  112. }
  113. }
  114. });
  115. }