index.cjs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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. projectData: () => projectData,
  26. validateProjectionSchema: () => validateProjectionSchema,
  27. validateProjectionSchemaDefinition: () => validateProjectionSchemaDefinition
  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, validatedSchemas = /* @__PURE__ */ new Set()) {
  35. if (!schema && schema !== false || typeof schema !== "boolean" && typeof schema !== "object" && typeof schema !== "function" && typeof schema !== "string" || Array.isArray(schema)) {
  36. throw new import_js_format.InvalidArgumentError(
  37. "Projection schema must be a Boolean, an Object, a Function or a non-empty String, but %v was given.",
  38. schema
  39. );
  40. }
  41. if (typeof shallowMode !== "boolean") {
  42. throw new import_js_format.InvalidArgumentError(
  43. 'Argument "shallowMode" must be a Boolean, but %v was given.',
  44. shallowMode
  45. );
  46. }
  47. if (!(validatedSchemas instanceof Set)) {
  48. throw new import_js_format.InvalidArgumentError(
  49. 'Argument "validatedSchemas" must be an instance of Set, but %v was given.',
  50. validatedSchemas
  51. );
  52. }
  53. if (validatedSchemas.has(schema)) {
  54. return;
  55. }
  56. if (typeof schema !== "object") {
  57. return;
  58. }
  59. validatedSchemas.add(schema);
  60. Object.keys(schema).forEach((propName) => {
  61. const propSchema = schema[propName];
  62. if (propSchema === void 0) {
  63. return;
  64. }
  65. if (!propSchema && propSchema !== false || typeof propSchema !== "boolean" && typeof propSchema !== "object" && typeof propSchema !== "function" && typeof propSchema !== "string" || Array.isArray(propSchema)) {
  66. throw new import_js_format.InvalidArgumentError(
  67. "Projection schema of the property %v must be a Boolean, an Object, a Function or a non-empty String, but %v was given.",
  68. propName,
  69. propSchema
  70. );
  71. }
  72. if (!shallowMode && typeof propSchema === "object") {
  73. validateProjectionSchema(propSchema, shallowMode, validatedSchemas);
  74. }
  75. });
  76. }
  77. __name(validateProjectionSchema, "validateProjectionSchema");
  78. // src/project-data.js
  79. var DATA_SCHEMA_INLINE_OPTIONS = ["$keepUnknown"];
  80. function projectData(data, schema, options) {
  81. if (options !== void 0) {
  82. if (!options || typeof options !== "object" || Array.isArray(options)) {
  83. throw new import_js_format2.InvalidArgumentError(
  84. "Projection options must be an Object, but %v was given.",
  85. options
  86. );
  87. }
  88. if (options.keepUnknown !== void 0 && typeof options.keepUnknown !== "boolean") {
  89. throw new import_js_format2.InvalidArgumentError(
  90. 'Projection option "keepUnknown" must be a Boolean, but %v was given.',
  91. options.keepUnknown
  92. );
  93. }
  94. if (options.nameResolver !== void 0 && typeof options.nameResolver !== "function") {
  95. throw new import_js_format2.InvalidArgumentError(
  96. 'Projection option "nameResolver" must be a Function, but %v was given.',
  97. options.nameResolver
  98. );
  99. }
  100. if (options.factoryArgs !== void 0 && !Array.isArray(options.factoryArgs)) {
  101. throw new import_js_format2.InvalidArgumentError(
  102. 'Projection option "factoryArgs" must be an Array, but %v was given.',
  103. options.factoryArgs
  104. );
  105. }
  106. }
  107. if (typeof schema === "function") {
  108. const factoryArgs = options && options.factoryArgs || [];
  109. schema = schema(...factoryArgs);
  110. if (!schema && schema !== false || typeof schema !== "boolean" && typeof schema !== "object" && typeof schema !== "string" || Array.isArray(schema)) {
  111. throw new import_js_format2.InvalidArgumentError(
  112. "Schema factory must return a Boolean, an Object or a non-empty String, but %v was given.",
  113. schema
  114. );
  115. }
  116. }
  117. if (typeof schema === "string") {
  118. if (!options || !options.nameResolver) {
  119. throw new import_js_format2.InvalidArgumentError(
  120. 'Failed to resolve the schema name %v because the option "nameResolver" is missing.',
  121. schema
  122. );
  123. }
  124. schema = options.nameResolver(schema);
  125. if (!schema && schema !== false || typeof schema !== "boolean" && typeof schema !== "object" && typeof schema !== "function" && typeof schema !== "string" || Array.isArray(schema)) {
  126. throw new import_js_format2.InvalidArgumentError(
  127. "Name resolver must return a Boolean, an Object, a Function or a non-empty String, but %v was given.",
  128. schema
  129. );
  130. }
  131. if (typeof schema === "function" || typeof schema === "string") {
  132. return projectData(data, schema, options);
  133. }
  134. }
  135. if (typeof schema === "boolean") {
  136. return schema ? data : void 0;
  137. }
  138. validateProjectionSchema(schema, true);
  139. if (data == null) {
  140. return data;
  141. }
  142. if (typeof data !== "object") {
  143. throw new import_js_format2.InvalidArgumentError(
  144. "Data source of the object projection must be an Object or an Array, but %v was given.",
  145. data
  146. );
  147. }
  148. if (Array.isArray(data)) {
  149. return data.map((item) => projectData(item, schema, options));
  150. }
  151. const result = {};
  152. if (schema.$keepUnknown !== void 0 && typeof schema.$keepUnknown !== "boolean") {
  153. throw new import_js_format2.InvalidArgumentError(
  154. 'Schema property "$keepUnknown" must be a Boolean, but %v was given.',
  155. schema.$keepUnknown
  156. );
  157. }
  158. const keepUnknown = Boolean(
  159. typeof schema.$keepUnknown === "boolean" ? schema.$keepUnknown : options && options.keepUnknown
  160. );
  161. const propNames = Object.keys(keepUnknown ? data : schema);
  162. propNames.forEach((propName) => {
  163. if (!(propName in data) || DATA_SCHEMA_INLINE_OPTIONS.includes(propName)) {
  164. return;
  165. }
  166. const propSchema = schema[propName];
  167. const propValue = data[propName];
  168. if (typeof propSchema === "boolean") {
  169. if (propSchema) {
  170. result[propName] = propValue;
  171. }
  172. return;
  173. }
  174. if (propSchema != null) {
  175. result[propName] = projectData(propValue, propSchema, options);
  176. return;
  177. }
  178. if (keepUnknown) {
  179. result[propName] = propValue;
  180. }
  181. });
  182. return result;
  183. }
  184. __name(projectData, "projectData");
  185. // src/data-projector.js
  186. var import_js_service2 = require("@e22m4u/js-service");
  187. // src/projection-schema-registry.js
  188. var import_js_service = require("@e22m4u/js-service");
  189. var import_js_format4 = require("@e22m4u/js-format");
  190. // src/validate-projection-schema-definition.js
  191. var import_js_format3 = require("@e22m4u/js-format");
  192. function validateProjectionSchemaDefinition(schemaDef) {
  193. if (!schemaDef || typeof schemaDef !== "object" || Array.isArray(schemaDef)) {
  194. throw new import_js_format3.InvalidArgumentError(
  195. "Schema definition must be an Object, but %v was given.",
  196. schemaDef
  197. );
  198. }
  199. if (!schemaDef.name || typeof schemaDef.name !== "string") {
  200. throw new import_js_format3.InvalidArgumentError(
  201. 'Definition option "name" must be a non-empty String, but %v was given.',
  202. schemaDef.name
  203. );
  204. }
  205. if (!schemaDef.schema || typeof schemaDef.schema !== "object" && typeof schemaDef.schema !== "function" && typeof schemaDef.schema !== "string" || Array.isArray(schemaDef.schema)) {
  206. throw new import_js_format3.InvalidArgumentError(
  207. 'Definition option "schema" must be an Object, a Function or a non-empty String, but %v was given.',
  208. schemaDef.schema
  209. );
  210. }
  211. validateProjectionSchema(schemaDef.schema);
  212. }
  213. __name(validateProjectionSchemaDefinition, "validateProjectionSchemaDefinition");
  214. // src/projection-schema-registry.js
  215. var _ProjectionSchemaRegistry = class _ProjectionSchemaRegistry extends import_js_service.Service {
  216. /**
  217. * Definitions.
  218. */
  219. _definitions = /* @__PURE__ */ new Map();
  220. /**
  221. * Define schema.
  222. *
  223. * @param {object} schemaDef
  224. * @returns {this}
  225. */
  226. defineSchema(schemaDef) {
  227. validateProjectionSchemaDefinition(schemaDef);
  228. this._definitions.set(schemaDef.name, schemaDef);
  229. return this;
  230. }
  231. /**
  232. * Has schema.
  233. *
  234. * @param {string} schemaName
  235. * @returns {boolean}
  236. */
  237. hasSchema(schemaName) {
  238. return this._definitions.has(schemaName);
  239. }
  240. /**
  241. * Get schema.
  242. *
  243. * @param {string} schemaName
  244. * @returns {object}
  245. */
  246. getSchema(schemaName) {
  247. const schemaDef = this._definitions.get(schemaName);
  248. if (!schemaDef) {
  249. throw new import_js_format4.InvalidArgumentError(
  250. "Projection schema %v is not found.",
  251. schemaName
  252. );
  253. }
  254. return schemaDef.schema;
  255. }
  256. /**
  257. * Get definition.
  258. *
  259. * @param {string} schemaName
  260. * @returns {object}
  261. */
  262. getDefinition(schemaName) {
  263. const schemaDef = this._definitions.get(schemaName);
  264. if (!schemaDef) {
  265. throw new import_js_format4.InvalidArgumentError(
  266. "Schema definition %v is not found.",
  267. schemaName
  268. );
  269. }
  270. return schemaDef;
  271. }
  272. };
  273. __name(_ProjectionSchemaRegistry, "ProjectionSchemaRegistry");
  274. var ProjectionSchemaRegistry = _ProjectionSchemaRegistry;
  275. // src/data-projector.js
  276. var _DataProjector = class _DataProjector extends import_js_service2.Service {
  277. /**
  278. * Define schema.
  279. *
  280. * @param {object} schemaDef
  281. * @returns {this}
  282. */
  283. defineSchema(schemaDef) {
  284. this.getService(ProjectionSchemaRegistry).defineSchema(schemaDef);
  285. return this;
  286. }
  287. /**
  288. * Has schema.
  289. *
  290. * @param {string} schemaName
  291. * @returns {boolean}
  292. */
  293. hasSchema(schemaName) {
  294. return this.getService(ProjectionSchemaRegistry).hasSchema(schemaName);
  295. }
  296. /**
  297. * Get schema.
  298. *
  299. * @param {string} schemaName
  300. * @returns {object}
  301. */
  302. getSchema(schemaName) {
  303. return this.getService(ProjectionSchemaRegistry).getSchema(schemaName);
  304. }
  305. /**
  306. * Project.
  307. *
  308. * @param {object|object[]|*} data
  309. * @param {object|Function|string} schema
  310. * @param {object} [options]
  311. * @returns {*}
  312. */
  313. project(data, schema, options) {
  314. const registry = this.getService(ProjectionSchemaRegistry);
  315. const defaultNameResolver = /* @__PURE__ */ __name((name) => registry.getSchema(name), "defaultNameResolver");
  316. const nameResolver = options && options.nameResolver || defaultNameResolver;
  317. const factoryArgs = options && options.factoryArgs || [this.container];
  318. return projectData(data, schema, { ...options, nameResolver, factoryArgs });
  319. }
  320. };
  321. __name(_DataProjector, "DataProjector");
  322. var DataProjector = _DataProjector;
  323. // Annotate the CommonJS export names for ESM import in node:
  324. 0 && (module.exports = {
  325. DataProjector,
  326. ProjectionSchemaRegistry,
  327. projectData,
  328. validateProjectionSchema,
  329. validateProjectionSchemaDefinition
  330. });