data-projector.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {Service} from '@e22m4u/js-service';
  2. import {projectData} from './project-data.js';
  3. import {ProjectionScope} from './projection-scope.js';
  4. import {InvalidArgumentError} from '@e22m4u/js-format';
  5. import {ProjectionSchemaRegistry} from './projection-schema-registry.js';
  6. /**
  7. * Data projector.
  8. */
  9. export class DataProjector extends Service {
  10. /**
  11. * Define schema.
  12. *
  13. * @param {string} name
  14. * @param {object} schema
  15. * @returns {this}
  16. */
  17. defineSchema(name, schema) {
  18. this.getService(ProjectionSchemaRegistry).defineSchema(name, schema);
  19. return this;
  20. }
  21. /**
  22. * Project.
  23. *
  24. * @param {object|string} schemaOrName
  25. * @param {object} data
  26. * @param {object|undefined} options
  27. * @returns {*}
  28. */
  29. project(schemaOrName, data, options = undefined) {
  30. // schemaOrName
  31. if (
  32. !schemaOrName ||
  33. (typeof schemaOrName !== 'string' && typeof schemaOrName !== 'object') ||
  34. Array.isArray(schemaOrName)
  35. ) {
  36. throw new InvalidArgumentError(
  37. 'Projection schema must be an Object or a non-empty String ' +
  38. 'that represents a schema name, but %v was given.',
  39. schemaOrName,
  40. );
  41. }
  42. // options
  43. if (options !== undefined) {
  44. if (!options || typeof options !== 'object' || Array.isArray(options)) {
  45. throw new InvalidArgumentError(
  46. 'Parameter "options" must be an Object, but %v was given.',
  47. options,
  48. );
  49. }
  50. // options.strict
  51. if (options.strict !== undefined && typeof options.strict !== 'boolean') {
  52. throw new InvalidArgumentError(
  53. 'Option "strict" must be a Boolean, but %v was given.',
  54. options.strict,
  55. );
  56. }
  57. // options.scope
  58. if (
  59. options.scope !== undefined &&
  60. (!options.scope || typeof options.scope !== 'string')
  61. ) {
  62. throw new InvalidArgumentError(
  63. 'Option "scope" must be a non-empty String, but %v was given.',
  64. options.scope,
  65. );
  66. }
  67. // options.resolver
  68. if (options.resolver !== undefined) {
  69. throw new InvalidArgumentError(
  70. 'Option "resolver" is not supported for the DataProjector.',
  71. );
  72. }
  73. }
  74. const registry = this.getService(ProjectionSchemaRegistry);
  75. return projectData(schemaOrName, data, {
  76. ...options,
  77. resolver: name => registry.getSchema(name),
  78. });
  79. }
  80. /**
  81. * Project with "input" scope.
  82. *
  83. * @param {object|string} schemaOrName
  84. * @param {object} data
  85. * @param {object|undefined} options
  86. * @returns {*}
  87. */
  88. projectInput(schemaOrName, data, options = undefined) {
  89. options = {...options, scope: ProjectionScope.INPUT};
  90. return this.project(schemaOrName, data, options);
  91. }
  92. /**
  93. * Project with "output" scope.
  94. *
  95. * @param {object|string} schemaOrName
  96. * @param {object} data
  97. * @param {object|undefined} options
  98. * @returns {*}
  99. */
  100. projectOutput(schemaOrName, data, options = undefined) {
  101. options = {...options, scope: ProjectionScope.OUTPUT};
  102. return this.project(schemaOrName, data, options);
  103. }
  104. }