index.cjs 13 KB

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