index.cjs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. "use strict";
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  4. var __getOwnPropNames = Object.getOwnPropertyNames;
  5. var __hasOwnProp = Object.prototype.hasOwnProperty;
  6. var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
  7. var __export = (target, all) => {
  8. for (var name in all)
  9. __defProp(target, name, { get: all[name], enumerable: true });
  10. };
  11. var __copyProps = (to, from, except, desc) => {
  12. if (from && typeof from === "object" || typeof from === "function") {
  13. for (let key of __getOwnPropNames(from))
  14. if (!__hasOwnProp.call(to, key) && key !== except)
  15. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  16. }
  17. return to;
  18. };
  19. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  20. // src/index.js
  21. var index_exports = {};
  22. __export(index_exports, {
  23. DataProjector: () => DataProjector,
  24. ProjectionSchemaRegistry: () => ProjectionSchemaRegistry,
  25. ProjectionScope: () => ProjectionScope,
  26. projectData: () => projectData,
  27. validateProjectionSchema: () => validateProjectionSchema
  28. });
  29. module.exports = __toCommonJS(index_exports);
  30. // src/project-data.js
  31. var import_js_format2 = require("@e22m4u/js-format");
  32. // src/validate-projection-schema.js
  33. var import_js_format = require("@e22m4u/js-format");
  34. function validateProjectionSchema(schema, shallowMode = false) {
  35. if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
  36. throw new import_js_format.InvalidArgumentError(
  37. "Projection schema must be an Object, but %v was given.",
  38. schema
  39. );
  40. }
  41. if (typeof shallowMode !== "boolean") {
  42. throw new import_js_format.InvalidArgumentError(
  43. 'Parameter "shallowMode" must be a Boolean, but %v was given.',
  44. shallowMode
  45. );
  46. }
  47. Object.keys(schema).forEach((propName) => {
  48. const options = schema[propName];
  49. if (options === void 0) {
  50. return;
  51. }
  52. if (options === null || typeof options !== "boolean" && typeof options !== "object" || Array.isArray(options)) {
  53. throw new import_js_format.InvalidArgumentError(
  54. "Property options must be a Boolean or an Object, but %v was given.",
  55. options
  56. );
  57. }
  58. if (typeof options === "boolean") {
  59. return;
  60. }
  61. if (options.select !== void 0 && typeof options.select !== "boolean") {
  62. throw new import_js_format.InvalidArgumentError(
  63. 'Property option "select" must be a Boolean, but %v was given.',
  64. options.select
  65. );
  66. }
  67. if (options.schema !== void 0) {
  68. if (!options.schema || typeof options.schema !== "string" && typeof options.schema !== "object" || Array.isArray(options.schema)) {
  69. throw new import_js_format.InvalidArgumentError(
  70. "Embedded schema must be an Object or a non-empty String that represents a schema name, but %v was given.",
  71. options.schema
  72. );
  73. }
  74. if (!shallowMode && typeof options.schema === "object") {
  75. validateProjectionSchema(options.schema, shallowMode);
  76. }
  77. }
  78. if (options.scopes !== void 0) {
  79. if (!options.scopes || typeof options.scopes !== "object" || Array.isArray(options.scopes)) {
  80. throw new import_js_format.InvalidArgumentError(
  81. 'Property option "scopes" must be an Object, but %v was given.',
  82. options.scopes
  83. );
  84. }
  85. Object.keys(options.scopes).forEach((scopeName) => {
  86. const scopeOptions = options.scopes[scopeName];
  87. if (scopeOptions === void 0) {
  88. return;
  89. }
  90. if (scopeOptions === null || typeof scopeOptions !== "boolean" && typeof scopeOptions !== "object" || Array.isArray(scopeOptions)) {
  91. throw new import_js_format.InvalidArgumentError(
  92. "Scope options must be a Boolean or an Object, but %v was given.",
  93. scopeOptions
  94. );
  95. }
  96. if (typeof scopeOptions === "boolean") {
  97. return;
  98. }
  99. if (scopeOptions.select !== void 0) {
  100. if (typeof scopeOptions.select !== "boolean") {
  101. throw new import_js_format.InvalidArgumentError(
  102. 'Scope option "select" must be a Boolean, but %v was given.',
  103. scopeOptions.select
  104. );
  105. }
  106. }
  107. });
  108. }
  109. });
  110. }
  111. __name(validateProjectionSchema, "validateProjectionSchema");
  112. // src/project-data.js
  113. function projectData(schemaOrName, data, options = void 0) {
  114. if (!schemaOrName || typeof schemaOrName !== "string" && typeof schemaOrName !== "object" || Array.isArray(schemaOrName)) {
  115. throw new import_js_format2.InvalidArgumentError(
  116. "Projection schema must be an Object or a non-empty String that represents a schema name, but %v was given.",
  117. schemaOrName
  118. );
  119. }
  120. if (options !== void 0) {
  121. if (!options || typeof options !== "object" || Array.isArray(options)) {
  122. throw new import_js_format2.InvalidArgumentError(
  123. 'Parameter "options" must be an Object, but %v was given.',
  124. options
  125. );
  126. }
  127. if (options.strict !== void 0 && typeof options.strict !== "boolean") {
  128. throw new import_js_format2.InvalidArgumentError(
  129. 'Option "strict" must be a Boolean, but %v was given.',
  130. options.strict
  131. );
  132. }
  133. if (options.scope !== void 0 && (!options.scope || typeof options.scope !== "string")) {
  134. throw new import_js_format2.InvalidArgumentError(
  135. 'Option "scope" must be a non-empty String, but %v was given.',
  136. options.scope
  137. );
  138. }
  139. if (options.resolver !== void 0 && (!options.resolver || typeof options.resolver !== "function")) {
  140. throw new import_js_format2.InvalidArgumentError(
  141. 'Option "resolver" must be a Function, but %v was given.',
  142. options.resolver
  143. );
  144. }
  145. }
  146. const strict = Boolean(options && options.strict);
  147. const scope = options && options.scope || void 0;
  148. const resolver = options && options.resolver || void 0;
  149. let schema = schemaOrName;
  150. if (typeof schemaOrName === "string") {
  151. if (!resolver) {
  152. throw new import_js_format2.InvalidArgumentError(
  153. "Unable to resolve the named schema %v without a specified projection schema resolver.",
  154. schemaOrName
  155. );
  156. }
  157. schema = resolver(schemaOrName);
  158. if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
  159. throw new import_js_format2.InvalidArgumentError(
  160. "Projection schema resolver must return an Object, but %v was given.",
  161. schema
  162. );
  163. }
  164. }
  165. validateProjectionSchema(schema, true);
  166. if (data === null || typeof data !== "object") {
  167. return data;
  168. }
  169. if (Array.isArray(data)) {
  170. return data.map(
  171. (item) => projectData(schema, item, { strict, scope, resolver })
  172. );
  173. }
  174. const result = {};
  175. const keys = Object.keys(strict ? schema : data);
  176. for (const key of keys) {
  177. if (!(key in data)) continue;
  178. const propOptionsOrBoolean = schema[key];
  179. if (_shouldSelect(propOptionsOrBoolean, strict, scope)) {
  180. const value = data[key];
  181. if (propOptionsOrBoolean && typeof propOptionsOrBoolean === "object" && propOptionsOrBoolean.schema) {
  182. result[key] = projectData(propOptionsOrBoolean.schema, value, {
  183. strict,
  184. scope,
  185. resolver
  186. });
  187. } else {
  188. result[key] = value;
  189. }
  190. }
  191. }
  192. return result;
  193. }
  194. __name(projectData, "projectData");
  195. function _shouldSelect(propOptionsOrBoolean, strict, scope) {
  196. if (typeof propOptionsOrBoolean === "boolean") {
  197. return propOptionsOrBoolean;
  198. }
  199. if (typeof propOptionsOrBoolean === "object") {
  200. const propOptions = propOptionsOrBoolean;
  201. if (scope && propOptions.scopes && typeof propOptions.scopes === "object" && propOptions.scopes[scope] != null) {
  202. const scopeOptionsOrBoolean = propOptions.scopes[scope];
  203. if (typeof scopeOptionsOrBoolean === "boolean") {
  204. return scopeOptionsOrBoolean;
  205. }
  206. if (scopeOptionsOrBoolean && typeof scopeOptionsOrBoolean === "object" && typeof scopeOptionsOrBoolean.select === "boolean") {
  207. return scopeOptionsOrBoolean.select;
  208. }
  209. }
  210. if (typeof propOptionsOrBoolean.select === "boolean") {
  211. return propOptionsOrBoolean.select;
  212. }
  213. }
  214. return !strict;
  215. }
  216. __name(_shouldSelect, "_shouldSelect");
  217. // src/data-projector.js
  218. var import_js_service2 = require("@e22m4u/js-service");
  219. // src/projection-scope.js
  220. var ProjectionScope = {
  221. INPUT: "input",
  222. OUTPUT: "output"
  223. };
  224. // src/data-projector.js
  225. var import_js_format4 = require("@e22m4u/js-format");
  226. // src/projection-schema-registry.js
  227. var import_js_service = require("@e22m4u/js-service");
  228. var import_js_format3 = require("@e22m4u/js-format");
  229. var _ProjectionSchemaRegistry = class _ProjectionSchemaRegistry extends import_js_service.Service {
  230. /**
  231. * Schema map.
  232. */
  233. _schemas = /* @__PURE__ */ new Map();
  234. /**
  235. * Define schema.
  236. *
  237. * @param {string} name
  238. * @param {object} schema
  239. * @returns {this}
  240. */
  241. defineSchema(name, schema) {
  242. if (!name || typeof name !== "string") {
  243. throw new import_js_format3.InvalidArgumentError(
  244. "Schema name must be a non-empty String, but %v was given.",
  245. name
  246. );
  247. }
  248. if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
  249. throw new import_js_format3.InvalidArgumentError(
  250. "Projection schema must be an Object, but %v was given.",
  251. schema
  252. );
  253. }
  254. if (this._schemas.has(name)) {
  255. throw new import_js_format3.InvalidArgumentError(
  256. "Projection schema %v is already registered.",
  257. name
  258. );
  259. }
  260. validateProjectionSchema(schema);
  261. this._schemas.set(name, schema);
  262. return this;
  263. }
  264. /**
  265. * Get schema.
  266. *
  267. * @param {string} name
  268. * @returns {object}
  269. */
  270. getSchema(name) {
  271. if (!name || typeof name !== "string") {
  272. throw new import_js_format3.InvalidArgumentError(
  273. "Schema name must be a non-empty String, but %v was given.",
  274. name
  275. );
  276. }
  277. const schema = this._schemas.get(name);
  278. if (!schema) {
  279. throw new import_js_format3.InvalidArgumentError(
  280. "Projection schema %v is not found.",
  281. name
  282. );
  283. }
  284. return schema;
  285. }
  286. };
  287. __name(_ProjectionSchemaRegistry, "ProjectionSchemaRegistry");
  288. var ProjectionSchemaRegistry = _ProjectionSchemaRegistry;
  289. // src/data-projector.js
  290. var _DataProjector = class _DataProjector extends import_js_service2.Service {
  291. /**
  292. * Define schema.
  293. *
  294. * @param {string} name
  295. * @param {object} schema
  296. * @returns {this}
  297. */
  298. defineSchema(name, schema) {
  299. this.getService(ProjectionSchemaRegistry).defineSchema(name, schema);
  300. return this;
  301. }
  302. /**
  303. * Project.
  304. *
  305. * @param {object|string} schemaOrName
  306. * @param {object} data
  307. * @param {object|undefined} options
  308. * @returns {*}
  309. */
  310. project(schemaOrName, data, options = void 0) {
  311. if (!schemaOrName || typeof schemaOrName !== "string" && typeof schemaOrName !== "object" || Array.isArray(schemaOrName)) {
  312. throw new import_js_format4.InvalidArgumentError(
  313. "Projection schema must be an Object or a non-empty String that represents a schema name, but %v was given.",
  314. schemaOrName
  315. );
  316. }
  317. if (options !== void 0) {
  318. if (!options || typeof options !== "object" || Array.isArray(options)) {
  319. throw new import_js_format4.InvalidArgumentError(
  320. 'Parameter "options" must be an Object, but %v was given.',
  321. options
  322. );
  323. }
  324. if (options.strict !== void 0 && typeof options.strict !== "boolean") {
  325. throw new import_js_format4.InvalidArgumentError(
  326. 'Option "strict" must be a Boolean, but %v was given.',
  327. options.strict
  328. );
  329. }
  330. if (options.scope !== void 0 && (!options.scope || typeof options.scope !== "string")) {
  331. throw new import_js_format4.InvalidArgumentError(
  332. 'Option "scope" must be a non-empty String, but %v was given.',
  333. options.scope
  334. );
  335. }
  336. if (options.resolver !== void 0) {
  337. throw new import_js_format4.InvalidArgumentError(
  338. 'Option "resolver" is not supported for the DataProjector.'
  339. );
  340. }
  341. }
  342. const registry = this.getService(ProjectionSchemaRegistry);
  343. return projectData(schemaOrName, data, {
  344. ...options,
  345. resolver: /* @__PURE__ */ __name((name) => registry.getSchema(name), "resolver")
  346. });
  347. }
  348. /**
  349. * Project with "input" scope.
  350. *
  351. * @param {object|string} schemaOrName
  352. * @param {object} data
  353. * @param {object|undefined} options
  354. * @returns {*}
  355. */
  356. projectInput(schemaOrName, data, options = void 0) {
  357. options = { ...options, scope: ProjectionScope.INPUT };
  358. return this.project(schemaOrName, data, options);
  359. }
  360. /**
  361. * Project with "output" scope.
  362. *
  363. * @param {object|string} schemaOrName
  364. * @param {object} data
  365. * @param {object|undefined} options
  366. * @returns {*}
  367. */
  368. projectOutput(schemaOrName, data, options = void 0) {
  369. options = { ...options, scope: ProjectionScope.OUTPUT };
  370. return this.project(schemaOrName, data, options);
  371. }
  372. };
  373. __name(_DataProjector, "DataProjector");
  374. var DataProjector = _DataProjector;
  375. // Annotate the CommonJS export names for ESM import in node:
  376. 0 && (module.exports = {
  377. DataProjector,
  378. ProjectionSchemaRegistry,
  379. ProjectionScope,
  380. projectData,
  381. validateProjectionSchema
  382. });