index.cjs 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  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. DATA_TYPE_LIST: () => DATA_TYPE_LIST,
  24. DataParser: () => DataParser,
  25. DataParsingError: () => DataParsingError,
  26. DataSchemaRegistry: () => DataSchemaRegistry,
  27. DataSchemaResolver: () => DataSchemaResolver,
  28. DataType: () => DataType,
  29. DataValidationError: () => DataValidationError,
  30. DataValidator: () => DataValidator,
  31. arrayTypeParser: () => arrayTypeParser,
  32. arrayTypeValidator: () => arrayTypeValidator,
  33. booleanTypeParser: () => booleanTypeParser,
  34. booleanTypeValidator: () => booleanTypeValidator,
  35. getDataTypeFromValue: () => getDataTypeFromValue,
  36. numberTypeParser: () => numberTypeParser,
  37. numberTypeValidator: () => numberTypeValidator,
  38. objectTypeParser: () => objectTypeParser,
  39. objectTypeValidator: () => objectTypeValidator,
  40. requiredValueValidator: () => requiredValueValidator,
  41. stringTypeParser: () => stringTypeParser,
  42. stringTypeValidator: () => stringTypeValidator,
  43. validateDataSchema: () => validateDataSchema,
  44. validateDataSchemaDefinition: () => validateDataSchemaDefinition
  45. });
  46. module.exports = __toCommonJS(index_exports);
  47. // src/data-type.js
  48. var DataType = {
  49. ANY: "any",
  50. STRING: "string",
  51. NUMBER: "number",
  52. BOOLEAN: "boolean",
  53. ARRAY: "array",
  54. OBJECT: "object"
  55. };
  56. var DATA_TYPE_LIST = Object.values(DataType);
  57. function getDataTypeFromValue(value) {
  58. if (value == null) return DataType.ANY;
  59. const baseType = typeof value;
  60. if (baseType === "string") return DataType.STRING;
  61. if (baseType === "number") return DataType.NUMBER;
  62. if (baseType === "boolean") return DataType.BOOLEAN;
  63. if (Array.isArray(value)) return DataType.ARRAY;
  64. if (baseType === "object") return DataType.OBJECT;
  65. return DataType.ANY;
  66. }
  67. __name(getDataTypeFromValue, "getDataTypeFromValue");
  68. // src/data-parser.js
  69. var import_js_service15 = require("@e22m4u/js-service");
  70. // src/data-validator.js
  71. var import_js_service9 = require("@e22m4u/js-service");
  72. var import_js_format7 = require("@e22m4u/js-format");
  73. // src/data-schema-resolver.js
  74. var import_js_service2 = require("@e22m4u/js-service");
  75. var import_js_format4 = require("@e22m4u/js-format");
  76. // src/validate-data-schema.js
  77. var import_js_format = require("@e22m4u/js-format");
  78. function validateDataSchema(schema, shallowMode = false, validatedSchemas = /* @__PURE__ */ new Set()) {
  79. if (typeof shallowMode !== "boolean") {
  80. throw new import_js_format.InvalidArgumentError(
  81. 'Argument "shallowMode" must be a Boolean, but %v was given.',
  82. shallowMode
  83. );
  84. }
  85. if (!(validatedSchemas instanceof Set)) {
  86. throw new import_js_format.InvalidArgumentError(
  87. 'Argument "validatedSchemas" must be an instance of Set, but %v was given.',
  88. validatedSchemas
  89. );
  90. }
  91. if (validatedSchemas.has(schema)) {
  92. return;
  93. }
  94. if (!schema || typeof schema !== "object" && typeof schema !== "function" && typeof schema !== "string" || Array.isArray(schema)) {
  95. throw new import_js_format.InvalidArgumentError(
  96. "Data schema must be an Object, a Function or a non-empty String, but %v was given.",
  97. schema
  98. );
  99. }
  100. if (typeof schema !== "object") {
  101. return;
  102. }
  103. validatedSchemas.add(schema);
  104. if (schema.type !== void 0) {
  105. if (!schema.type || !DATA_TYPE_LIST.includes(schema.type)) {
  106. throw new import_js_format.InvalidArgumentError(
  107. 'Schema option "type" must be one of values: %l, but %v was given.',
  108. DATA_TYPE_LIST,
  109. schema.type
  110. );
  111. }
  112. }
  113. if (schema.items !== void 0) {
  114. if (!schema.items || typeof schema.items !== "object" && typeof schema.items !== "function" && typeof schema.items !== "string" || Array.isArray(schema.items)) {
  115. throw new import_js_format.InvalidArgumentError(
  116. 'Schema option "items" must be an Object, a Function or a non-empty String, but %v was given.',
  117. schema.items
  118. );
  119. }
  120. if (schema.type !== DataType.ARRAY) {
  121. throw new import_js_format.InvalidArgumentError(
  122. 'Schema option "items" is only allowed for the "array" type, but %v was given.',
  123. schema.type
  124. );
  125. }
  126. if (!shallowMode && typeof schema.items === "object") {
  127. validateDataSchema(schema.items, shallowMode, validatedSchemas);
  128. }
  129. }
  130. if (schema.properties !== void 0) {
  131. if (!schema.properties || typeof schema.properties !== "object" && typeof schema.properties !== "function" && typeof schema.properties !== "string" || Array.isArray(schema.properties)) {
  132. throw new import_js_format.InvalidArgumentError(
  133. 'Schema option "properties" must be an Object, a Function or a non-empty String, but %v was given.',
  134. schema.properties
  135. );
  136. }
  137. if (schema.type !== DataType.OBJECT) {
  138. throw new import_js_format.InvalidArgumentError(
  139. 'Schema option "properties" is only allowed for the "object" type, but %v was given.',
  140. schema.type
  141. );
  142. }
  143. if (typeof schema.properties === "object") {
  144. Object.values(schema.properties).forEach((propSchema) => {
  145. if (propSchema === void 0) {
  146. return;
  147. }
  148. if (!propSchema || typeof propSchema !== "object" && typeof propSchema !== "function" && typeof propSchema !== "string" || Array.isArray(propSchema)) {
  149. throw new import_js_format.InvalidArgumentError(
  150. "Property schema must be an Object, a Function or a non-empty String, but %v was given.",
  151. propSchema
  152. );
  153. }
  154. if (!shallowMode && typeof propSchema === "object") {
  155. validateDataSchema(propSchema, shallowMode, validatedSchemas);
  156. }
  157. });
  158. }
  159. }
  160. if (schema.required !== void 0 && typeof schema.required !== "boolean") {
  161. throw new import_js_format.InvalidArgumentError(
  162. 'Schema option "required" must be a Boolean, but %v was given.',
  163. schema.required
  164. );
  165. }
  166. }
  167. __name(validateDataSchema, "validateDataSchema");
  168. // src/data-schema-registry.js
  169. var import_js_service = require("@e22m4u/js-service");
  170. var import_js_format3 = require("@e22m4u/js-format");
  171. // src/validate-data-schema-definition.js
  172. var import_js_format2 = require("@e22m4u/js-format");
  173. function validateDataSchemaDefinition(schemaDef) {
  174. if (!schemaDef || typeof schemaDef !== "object" || Array.isArray(schemaDef)) {
  175. throw new import_js_format2.InvalidArgumentError(
  176. "Schema definition must be an Object, but %v was given.",
  177. schemaDef
  178. );
  179. }
  180. if (!schemaDef.name || typeof schemaDef.name !== "string") {
  181. throw new import_js_format2.InvalidArgumentError(
  182. 'Definition option "name" must be a non-empty String, but %v was given.',
  183. schemaDef.name
  184. );
  185. }
  186. if (!schemaDef.schema || typeof schemaDef.schema !== "object" && typeof schemaDef.schema !== "function" && typeof schemaDef.schema !== "string" || Array.isArray(schemaDef.schema)) {
  187. throw new import_js_format2.InvalidArgumentError(
  188. 'Definition option "schema" must be an Object, a Function or a non-empty String, but %v was given.',
  189. schemaDef.schema
  190. );
  191. }
  192. validateDataSchema(schemaDef.schema);
  193. }
  194. __name(validateDataSchemaDefinition, "validateDataSchemaDefinition");
  195. // src/data-schema-registry.js
  196. var _DataSchemaRegistry = class _DataSchemaRegistry extends import_js_service.Service {
  197. /**
  198. * Definitions.
  199. *
  200. * @type {Map<string, object>}
  201. */
  202. _definitions = /* @__PURE__ */ new Map();
  203. /**
  204. * Define schema.
  205. *
  206. * @param {object} schemaDef
  207. * @returns {this}
  208. */
  209. defineSchema(schemaDef) {
  210. validateDataSchemaDefinition(schemaDef);
  211. if (this._definitions.has(schemaDef.name)) {
  212. throw new import_js_format3.InvalidArgumentError(
  213. "Data schema %v is already registered.",
  214. schemaDef.name
  215. );
  216. }
  217. this._definitions.set(schemaDef.name, schemaDef);
  218. return this;
  219. }
  220. /**
  221. * Has schema.
  222. *
  223. * @param {string} schemaName
  224. * @returns {boolean}
  225. */
  226. hasSchema(schemaName) {
  227. return this._definitions.has(schemaName);
  228. }
  229. /**
  230. * Get schema.
  231. *
  232. * @param {string} schemaName
  233. * @returns {object}
  234. */
  235. getSchema(schemaName) {
  236. const schemaDef = this._definitions.get(schemaName);
  237. if (!schemaDef) {
  238. throw new import_js_format3.InvalidArgumentError(
  239. "Data schema %v is not found.",
  240. schemaName
  241. );
  242. }
  243. return schemaDef.schema;
  244. }
  245. /**
  246. * Get definition.
  247. *
  248. * @param {string} schemaName
  249. * @returns {object}
  250. */
  251. getDefinition(schemaName) {
  252. const schemaDef = this._definitions.get(schemaName);
  253. if (!schemaDef) {
  254. throw new import_js_format3.InvalidArgumentError(
  255. "Schema definition %v is not found.",
  256. schemaName
  257. );
  258. }
  259. return schemaDef;
  260. }
  261. };
  262. __name(_DataSchemaRegistry, "DataSchemaRegistry");
  263. var DataSchemaRegistry = _DataSchemaRegistry;
  264. // src/data-schema-resolver.js
  265. var _DataSchemaResolver = class _DataSchemaResolver extends import_js_service2.Service {
  266. /**
  267. * Resolve schema.
  268. *
  269. * @param {object|Function|string} schema
  270. * @returns {object}
  271. */
  272. resolve(schema) {
  273. if (typeof schema === "function") {
  274. schema = schema(this.container);
  275. if (!schema || typeof schema !== "object" && typeof schema !== "string" || Array.isArray(schema)) {
  276. throw new import_js_format4.InvalidArgumentError(
  277. "Schema factory must return an Object or a non-empty String, but %v was given.",
  278. schema
  279. );
  280. }
  281. }
  282. if (schema && typeof schema === "string") {
  283. schema = this.getService(DataSchemaRegistry).getSchema(schema);
  284. if (!schema || typeof schema !== "object" && typeof schema !== "function" && typeof schema !== "string" || Array.isArray(schema)) {
  285. throw new import_js_format4.InvalidArgumentError(
  286. "Named schema must be an Object, a Function or a non-empty String, but %v was given.",
  287. schema
  288. );
  289. }
  290. if (typeof schema === "string" || typeof schema === "function") {
  291. return this.resolve(schema);
  292. }
  293. }
  294. validateDataSchema(schema, true);
  295. return schema;
  296. }
  297. };
  298. __name(_DataSchemaResolver, "DataSchemaResolver");
  299. var DataSchemaResolver = _DataSchemaResolver;
  300. // src/data-validators/array-type-validator.js
  301. var import_js_service3 = require("@e22m4u/js-service");
  302. // src/utils/to-pascal-case.js
  303. function toPascalCase(input) {
  304. if (!input) return "";
  305. return input.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([0-9])([a-zA-Z])/g, "$1 $2").replace(/[-_]+|[^\p{L}\p{N}]/gu, " ").toLowerCase().replace(new RegExp("(?:^|\\s)(\\p{L})", "gu"), (_, letter) => letter.toUpperCase()).replace(/\s+/g, "");
  306. }
  307. __name(toPascalCase, "toPascalCase");
  308. // src/errors/data-parsing-error.js
  309. var import_js_format5 = require("@e22m4u/js-format");
  310. var _DataParsingError = class _DataParsingError extends import_js_format5.InvalidArgumentError {
  311. /**
  312. * Value.
  313. *
  314. * @type {*}
  315. */
  316. value;
  317. /**
  318. * Target type.
  319. *
  320. * @type {string}
  321. */
  322. targetType;
  323. /**
  324. * Source path.
  325. *
  326. * @type {string|undefined}
  327. */
  328. sourcePath;
  329. /**
  330. * Constructor.
  331. *
  332. * @param {*} value
  333. * @param {string} targetType
  334. * @param {string} [sourcePath]
  335. */
  336. constructor(value, targetType, sourcePath) {
  337. const targetTypePc = toPascalCase(targetType);
  338. let message = "";
  339. if (sourcePath) {
  340. message = (0, import_js_format5.format)(
  341. "Unable to parse %v from %v as %s.",
  342. value,
  343. sourcePath,
  344. targetTypePc
  345. );
  346. } else {
  347. message = (0, import_js_format5.format)("Unable to parse %v as %s.", value, targetTypePc);
  348. }
  349. super(message);
  350. this.value = value;
  351. this.targetType = targetType;
  352. this.sourcePath = sourcePath;
  353. }
  354. };
  355. __name(_DataParsingError, "DataParsingError");
  356. var DataParsingError = _DataParsingError;
  357. // src/errors/data-validation-error.js
  358. var import_js_format6 = require("@e22m4u/js-format");
  359. var _DataValidationError = class _DataValidationError extends import_js_format6.InvalidArgumentError {
  360. };
  361. __name(_DataValidationError, "DataValidationError");
  362. var DataValidationError = _DataValidationError;
  363. // src/data-validators/array-type-validator.js
  364. var import_js_empty_values = require("@e22m4u/js-empty-values");
  365. function arrayTypeValidator(value, schema, options, container) {
  366. if (schema.type !== DataType.ARRAY) {
  367. return;
  368. }
  369. const emptyValues = container.get(import_js_empty_values.EmptyValuesService);
  370. const dataType = schema.type || DataType.ANY;
  371. if (emptyValues.isEmptyOf(dataType, value)) {
  372. return;
  373. }
  374. if (Array.isArray(value)) {
  375. return;
  376. }
  377. const sourcePath = options && options.sourcePath;
  378. if (sourcePath) {
  379. throw new DataValidationError(
  380. "Value of %v must be an Array, but %v was given.",
  381. sourcePath,
  382. value
  383. );
  384. } else {
  385. throw new DataValidationError(
  386. "Value must be an Array, but %v was given.",
  387. value
  388. );
  389. }
  390. }
  391. __name(arrayTypeValidator, "arrayTypeValidator");
  392. // src/data-validators/object-type-validator.js
  393. var import_js_service4 = require("@e22m4u/js-service");
  394. var import_js_empty_values2 = require("@e22m4u/js-empty-values");
  395. function objectTypeValidator(value, schema, options, container) {
  396. if (schema.type !== DataType.OBJECT) {
  397. return;
  398. }
  399. const emptyValues = container.get(import_js_empty_values2.EmptyValuesService);
  400. const dataType = schema.type || DataType.ANY;
  401. if (emptyValues.isEmptyOf(dataType, value)) {
  402. return;
  403. }
  404. if (value !== null && typeof value === "object" && !Array.isArray(value)) {
  405. return;
  406. }
  407. const sourcePath = options && options.sourcePath;
  408. if (sourcePath) {
  409. throw new DataValidationError(
  410. "Value of %v must be an Object, but %v was given.",
  411. sourcePath,
  412. value
  413. );
  414. } else {
  415. throw new DataValidationError(
  416. "Value must be an Object, but %v was given.",
  417. value
  418. );
  419. }
  420. }
  421. __name(objectTypeValidator, "objectTypeValidator");
  422. // src/data-validators/string-type-validator.js
  423. var import_js_service5 = require("@e22m4u/js-service");
  424. var import_js_empty_values3 = require("@e22m4u/js-empty-values");
  425. function stringTypeValidator(value, schema, options, container) {
  426. if (schema.type !== DataType.STRING) {
  427. return;
  428. }
  429. const emptyValues = container.get(import_js_empty_values3.EmptyValuesService);
  430. const dataType = schema.type || DataType.ANY;
  431. if (emptyValues.isEmptyOf(dataType, value)) {
  432. return;
  433. }
  434. if (typeof value === "string") {
  435. return;
  436. }
  437. const sourcePath = options && options.sourcePath;
  438. if (sourcePath) {
  439. throw new DataValidationError(
  440. "Value of %v must be a String, but %v was given.",
  441. sourcePath,
  442. value
  443. );
  444. } else {
  445. throw new DataValidationError(
  446. "Value must be a String, but %v was given.",
  447. value
  448. );
  449. }
  450. }
  451. __name(stringTypeValidator, "stringTypeValidator");
  452. // src/data-validators/number-type-validator.js
  453. var import_js_service6 = require("@e22m4u/js-service");
  454. var import_js_empty_values4 = require("@e22m4u/js-empty-values");
  455. function numberTypeValidator(value, schema, options, container) {
  456. if (schema.type !== DataType.NUMBER) {
  457. return;
  458. }
  459. const emptyValues = container.get(import_js_empty_values4.EmptyValuesService);
  460. const dataType = schema.type || DataType.ANY;
  461. if (emptyValues.isEmptyOf(dataType, value)) {
  462. return;
  463. }
  464. if (typeof value === "number") {
  465. return;
  466. }
  467. const sourcePath = options && options.sourcePath;
  468. if (sourcePath) {
  469. throw new DataValidationError(
  470. "Value of %v must be a Number, but %v was given.",
  471. sourcePath,
  472. value
  473. );
  474. } else {
  475. throw new DataValidationError(
  476. "Value must be a Number, but %v was given.",
  477. value
  478. );
  479. }
  480. }
  481. __name(numberTypeValidator, "numberTypeValidator");
  482. // src/data-validators/boolean-type-validator.js
  483. var import_js_service7 = require("@e22m4u/js-service");
  484. var import_js_empty_values5 = require("@e22m4u/js-empty-values");
  485. function booleanTypeValidator(value, schema, options, container) {
  486. if (schema.type !== DataType.BOOLEAN) {
  487. return;
  488. }
  489. const emptyValues = container.get(import_js_empty_values5.EmptyValuesService);
  490. const dataType = schema.type || DataType.ANY;
  491. if (emptyValues.isEmptyOf(dataType, value)) {
  492. return;
  493. }
  494. if (typeof value === "boolean") {
  495. return;
  496. }
  497. const sourcePath = options && options.sourcePath;
  498. if (sourcePath) {
  499. throw new DataValidationError(
  500. "Value of %v must be a Boolean, but %v was given.",
  501. sourcePath,
  502. value
  503. );
  504. } else {
  505. throw new DataValidationError(
  506. "Value must be a Boolean, but %v was given.",
  507. value
  508. );
  509. }
  510. }
  511. __name(booleanTypeValidator, "booleanTypeValidator");
  512. // src/data-validators/required-value-validator.js
  513. var import_js_service8 = require("@e22m4u/js-service");
  514. var import_js_empty_values6 = require("@e22m4u/js-empty-values");
  515. function requiredValueValidator(value, schema, options, container) {
  516. if (schema.required !== true) {
  517. return;
  518. }
  519. const emptyValues = container.get(import_js_empty_values6.EmptyValuesService);
  520. const dataType = schema.type || DataType.ANY;
  521. if (!emptyValues.isEmptyOf(dataType, value)) {
  522. return;
  523. }
  524. const sourcePath = options && options.sourcePath;
  525. if (sourcePath) {
  526. throw new DataValidationError(
  527. "Value of %v is required, but %v was given.",
  528. sourcePath,
  529. value
  530. );
  531. } else {
  532. throw new DataValidationError(
  533. "Value is required, but %v was given.",
  534. value
  535. );
  536. }
  537. }
  538. __name(requiredValueValidator, "requiredValueValidator");
  539. // src/data-validator.js
  540. var _DataValidator = class _DataValidator extends import_js_service9.Service {
  541. /**
  542. * Validators.
  543. *
  544. * @type {Function[]}
  545. */
  546. _validators = [
  547. stringTypeValidator,
  548. booleanTypeValidator,
  549. numberTypeValidator,
  550. objectTypeValidator,
  551. arrayTypeValidator,
  552. requiredValueValidator
  553. ];
  554. /**
  555. * Get validators.
  556. *
  557. * @returns {Function[]}
  558. */
  559. getValidators() {
  560. return [...this._validators];
  561. }
  562. /**
  563. * Set validators.
  564. *
  565. * @param {Function[]} list
  566. * @returns {this}
  567. */
  568. setValidators(list) {
  569. if (!Array.isArray(list)) {
  570. throw new import_js_format7.InvalidArgumentError(
  571. "Data validators must be an Array, but %v was given.",
  572. list
  573. );
  574. }
  575. list.forEach((validator) => {
  576. if (typeof validator !== "function") {
  577. throw new import_js_format7.InvalidArgumentError(
  578. "Data validator must be a Function, but %v was given.",
  579. validator
  580. );
  581. }
  582. });
  583. this._validators = [...list];
  584. return this;
  585. }
  586. /**
  587. * Define schema.
  588. *
  589. * @param {object} schemaDef
  590. * @returns {this}
  591. */
  592. defineSchema(schemaDef) {
  593. this.getService(DataSchemaRegistry).defineSchema(schemaDef);
  594. return this;
  595. }
  596. /**
  597. * Has schema.
  598. *
  599. * @param {string} schemaName
  600. * @returns {boolean}
  601. */
  602. hasSchema(schemaName) {
  603. return this.getService(DataSchemaRegistry).hasSchema(schemaName);
  604. }
  605. /**
  606. * Get schema.
  607. *
  608. * @param {string} schemaName
  609. * @returns {object}
  610. */
  611. getSchema(schemaName) {
  612. return this.getService(DataSchemaRegistry).getSchema(schemaName);
  613. }
  614. /**
  615. * Validate.
  616. *
  617. * @param {*} value
  618. * @param {object|Function|string} schema
  619. * @param {object} [options]
  620. */
  621. validate(value, schema, options) {
  622. if (options !== void 0) {
  623. if (options === null || typeof options !== "object" || Array.isArray(options)) {
  624. throw new import_js_format7.InvalidArgumentError(
  625. "Validation options must be an Object, but %v was given.",
  626. options
  627. );
  628. }
  629. if (options.sourcePath !== void 0) {
  630. if (!options.sourcePath || typeof options.sourcePath !== "string") {
  631. throw new import_js_format7.InvalidArgumentError(
  632. 'Option "sourcePath" must be a non-empty String, but %v was given.',
  633. options.sourcePath
  634. );
  635. }
  636. }
  637. if (options.shallowMode !== void 0) {
  638. if (typeof options.shallowMode !== "boolean") {
  639. throw new import_js_format7.InvalidArgumentError(
  640. 'Option "shallowMode" must be a Boolean, but %v was given.',
  641. options.shallowMode
  642. );
  643. }
  644. }
  645. }
  646. const sourcePath = options && options.sourcePath || void 0;
  647. const shallowMode = Boolean(options && options.shallowMode);
  648. validateDataSchema(schema, true);
  649. const schemaResolver = this.getService(DataSchemaResolver);
  650. if (typeof schema !== "object") {
  651. schema = schemaResolver.resolve(schema);
  652. }
  653. this._validators.forEach((validate) => {
  654. validate(value, schema, options, this.container);
  655. });
  656. if (shallowMode) {
  657. return;
  658. }
  659. if (Array.isArray(value) && schema.items !== void 0) {
  660. value.forEach((item, index) => {
  661. const itemPath = (sourcePath || "array") + `[${index}]`;
  662. const itemOptions = { ...options, sourcePath: itemPath };
  663. this.validate(item, schema.items, itemOptions);
  664. });
  665. } else if (value !== null && typeof value === "object" && schema.properties !== void 0) {
  666. let propsSchema = schema.properties;
  667. if (typeof propsSchema !== "object") {
  668. const resolvedSchema = schemaResolver.resolve(propsSchema);
  669. if (resolvedSchema.type !== DataType.OBJECT) {
  670. throw new import_js_format7.InvalidArgumentError(
  671. 'Unable to get the "properties" option from the data schema of %v type.',
  672. resolvedSchema.type || DataType.ANY
  673. );
  674. }
  675. propsSchema = resolvedSchema.properties || {};
  676. }
  677. Object.keys(propsSchema).forEach((propName) => {
  678. const propSchema = propsSchema[propName];
  679. if (propSchema === void 0) {
  680. return;
  681. }
  682. const propValue = value[propName];
  683. const propPath = sourcePath ? sourcePath + `.${propName}` : propName;
  684. const propOptions = { ...options, sourcePath: propPath };
  685. this.validate(propValue, propSchema, propOptions);
  686. });
  687. }
  688. }
  689. };
  690. __name(_DataValidator, "DataValidator");
  691. var DataValidator = _DataValidator;
  692. // src/data-parser.js
  693. var import_js_format8 = require("@e22m4u/js-format");
  694. // src/data-parsers/array-type-parser.js
  695. var import_js_service10 = require("@e22m4u/js-service");
  696. var import_js_empty_values7 = require("@e22m4u/js-empty-values");
  697. function arrayTypeParser(value, schema, options, container) {
  698. if (schema.type !== DataType.ARRAY) {
  699. return value;
  700. }
  701. if (Array.isArray(value)) {
  702. return value;
  703. }
  704. if (typeof value === "string") {
  705. value = value.trim();
  706. let newValue;
  707. try {
  708. newValue = JSON.parse(value);
  709. } catch {
  710. }
  711. if (Array.isArray(newValue)) {
  712. return newValue;
  713. }
  714. }
  715. const dataType = schema.type || DataType.ANY;
  716. const emptyValues = container.get(import_js_empty_values7.EmptyValuesService);
  717. if (emptyValues.isEmptyOf(dataType, value)) {
  718. return value;
  719. }
  720. if (!options || !options.noParsingErrors) {
  721. const sourcePath = options && options.sourcePath;
  722. throw new DataParsingError(value, dataType, sourcePath);
  723. }
  724. return value;
  725. }
  726. __name(arrayTypeParser, "arrayTypeParser");
  727. // src/data-parsers/string-type-parser.js
  728. var import_js_service11 = require("@e22m4u/js-service");
  729. var import_js_empty_values8 = require("@e22m4u/js-empty-values");
  730. function stringTypeParser(value, schema, options, container) {
  731. if (schema.type !== DataType.STRING) {
  732. return value;
  733. }
  734. if (typeof value === "string") {
  735. return value;
  736. }
  737. if (typeof value === "number") {
  738. return String(value);
  739. }
  740. const dataType = schema.type || DataType.ANY;
  741. const emptyValues = container.get(import_js_empty_values8.EmptyValuesService);
  742. if (emptyValues.isEmptyOf(dataType, value)) {
  743. return value;
  744. }
  745. if (!options || !options.noParsingErrors) {
  746. const sourcePath = options && options.sourcePath;
  747. throw new DataParsingError(value, dataType, sourcePath);
  748. }
  749. return value;
  750. }
  751. __name(stringTypeParser, "stringTypeParser");
  752. // src/data-parsers/number-type-parser.js
  753. var import_js_service12 = require("@e22m4u/js-service");
  754. var import_js_empty_values9 = require("@e22m4u/js-empty-values");
  755. function numberTypeParser(value, schema, options, container) {
  756. if (schema.type !== DataType.NUMBER) {
  757. return value;
  758. }
  759. if (typeof value === "number") {
  760. return value;
  761. }
  762. if (value && typeof value === "string") {
  763. if (value.length <= 20) {
  764. const newValue = Number(value.trim());
  765. if (!isNaN(newValue)) {
  766. return newValue;
  767. }
  768. }
  769. }
  770. const dataType = schema.type || DataType.ANY;
  771. const emptyValues = container.get(import_js_empty_values9.EmptyValuesService);
  772. if (emptyValues.isEmptyOf(dataType, value)) {
  773. return value;
  774. }
  775. if (!options || !options.noParsingErrors) {
  776. const sourcePath = options && options.sourcePath;
  777. throw new DataParsingError(value, dataType, sourcePath);
  778. }
  779. return value;
  780. }
  781. __name(numberTypeParser, "numberTypeParser");
  782. // src/data-parsers/object-type-parser.js
  783. var import_js_service13 = require("@e22m4u/js-service");
  784. var import_js_empty_values10 = require("@e22m4u/js-empty-values");
  785. function objectTypeParser(value, schema, options, container) {
  786. if (schema.type !== DataType.OBJECT) {
  787. return value;
  788. }
  789. if (value !== null && typeof value === "object" && !Array.isArray(value)) {
  790. return value;
  791. }
  792. if (typeof value === "string") {
  793. value = value.trim();
  794. let newValue;
  795. try {
  796. newValue = JSON.parse(value);
  797. } catch {
  798. }
  799. if (newValue !== null && typeof newValue === "object" && !Array.isArray(newValue)) {
  800. return newValue;
  801. }
  802. }
  803. const dataType = schema.type || DataType.ANY;
  804. const emptyValues = container.get(import_js_empty_values10.EmptyValuesService);
  805. if (emptyValues.isEmptyOf(dataType, value)) {
  806. return value;
  807. }
  808. if (!options || !options.noParsingErrors) {
  809. const sourcePath = options && options.sourcePath;
  810. throw new DataParsingError(value, dataType, sourcePath);
  811. }
  812. return value;
  813. }
  814. __name(objectTypeParser, "objectTypeParser");
  815. // src/data-parsers/boolean-type-parser.js
  816. var import_js_service14 = require("@e22m4u/js-service");
  817. var import_js_empty_values11 = require("@e22m4u/js-empty-values");
  818. function booleanTypeParser(value, schema, options, container) {
  819. if (schema.type !== DataType.BOOLEAN) {
  820. return value;
  821. }
  822. if (typeof value === "boolean") {
  823. return value;
  824. }
  825. if (typeof value === "string") {
  826. value = value.trim();
  827. if (value === "1") return true;
  828. if (value === "0") return false;
  829. if (value === "true") return true;
  830. if (value === "false") return false;
  831. } else if (typeof value === "number") {
  832. if (value === 1) return true;
  833. if (value === 0) return false;
  834. }
  835. const dataType = schema.type || DataType.ANY;
  836. const emptyValues = container.get(import_js_empty_values11.EmptyValuesService);
  837. if (emptyValues.isEmptyOf(dataType, value)) {
  838. return value;
  839. }
  840. if (!options || !options.noParsingErrors) {
  841. const sourcePath = options && options.sourcePath;
  842. throw new DataParsingError(value, dataType, sourcePath);
  843. }
  844. return value;
  845. }
  846. __name(booleanTypeParser, "booleanTypeParser");
  847. // src/data-parser.js
  848. var _DataParser = class _DataParser extends import_js_service15.Service {
  849. /**
  850. * Parsers.
  851. *
  852. * @type {Function[]}
  853. */
  854. _parsers = [
  855. stringTypeParser,
  856. booleanTypeParser,
  857. numberTypeParser,
  858. arrayTypeParser,
  859. objectTypeParser
  860. ];
  861. /**
  862. * Get parsers.
  863. *
  864. * @returns {Function[]}
  865. */
  866. getParsers() {
  867. return [...this._parsers];
  868. }
  869. /**
  870. * Set parsers.
  871. *
  872. * @param {Function[]} list
  873. * @returns {this}
  874. */
  875. setParsers(list) {
  876. if (!Array.isArray(list)) {
  877. throw new import_js_format8.InvalidArgumentError(
  878. "Data parsers must be an Array, but %v was given.",
  879. list
  880. );
  881. }
  882. list.forEach((parser) => {
  883. if (typeof parser !== "function") {
  884. throw new import_js_format8.InvalidArgumentError(
  885. "Data parser must be a Function, but %v was given.",
  886. parser
  887. );
  888. }
  889. });
  890. this._parsers = [...list];
  891. return this;
  892. }
  893. /**
  894. * Define schema.
  895. *
  896. * @param {object} schemaDef
  897. * @returns {this}
  898. */
  899. defineSchema(schemaDef) {
  900. this.getService(DataSchemaRegistry).defineSchema(schemaDef);
  901. return this;
  902. }
  903. /**
  904. * Has schema.
  905. *
  906. * @param {string} schemaName
  907. * @returns {boolean}
  908. */
  909. hasSchema(schemaName) {
  910. return this.getService(DataSchemaRegistry).hasSchema(schemaName);
  911. }
  912. /**
  913. * Get schema.
  914. *
  915. * @param {string} schemaName
  916. * @returns {object}
  917. */
  918. getSchema(schemaName) {
  919. return this.getService(DataSchemaRegistry).getSchema(schemaName);
  920. }
  921. /**
  922. * Parse.
  923. *
  924. * @param {*} value
  925. * @param {object|Function|string} schema
  926. * @param {object} [options]
  927. * @returns {*}
  928. */
  929. parse(value, schema, options) {
  930. if (options !== void 0) {
  931. if (options === null || typeof options !== "object" || Array.isArray(options)) {
  932. throw new import_js_format8.InvalidArgumentError(
  933. "Parsing options must be an Object, but %v was given.",
  934. options
  935. );
  936. }
  937. if (options.sourcePath !== void 0) {
  938. if (!options.sourcePath || typeof options.sourcePath !== "string") {
  939. throw new import_js_format8.InvalidArgumentError(
  940. 'Option "sourcePath" must be a non-empty String, but %v was given.',
  941. options.sourcePath
  942. );
  943. }
  944. }
  945. if (options.shallowMode !== void 0) {
  946. if (typeof options.shallowMode !== "boolean") {
  947. throw new import_js_format8.InvalidArgumentError(
  948. 'Option "shallowMode" must be a Boolean, but %v was given.',
  949. options.shallowMode
  950. );
  951. }
  952. }
  953. if (options.noParsingErrors !== void 0) {
  954. if (typeof options.noParsingErrors !== "boolean") {
  955. throw new import_js_format8.InvalidArgumentError(
  956. 'Option "noParsingErrors" must be a Boolean, but %v was given.',
  957. options.noParsingErrors
  958. );
  959. }
  960. }
  961. }
  962. const sourcePath = options && options.sourcePath || void 0;
  963. const shallowMode = Boolean(options && options.shallowMode);
  964. const noParsingErrors = Boolean(options && options.noParsingErrors);
  965. validateDataSchema(schema, true);
  966. const schemaResolver = this.getService(DataSchemaResolver);
  967. if (typeof schema !== "object") {
  968. schema = schemaResolver.resolve(schema);
  969. }
  970. value = this._parsers.reduce((input, parser) => {
  971. return parser(input, schema, options, this.container);
  972. }, value);
  973. if (!shallowMode) {
  974. if (Array.isArray(value) && schema.items !== void 0) {
  975. value = [...value];
  976. value.forEach((item, index) => {
  977. const itemPath = (sourcePath || "array") + `[${index}]`;
  978. const itemOptions = { ...options, sourcePath: itemPath };
  979. value[index] = this.parse(item, schema.items, itemOptions);
  980. });
  981. } else if (value !== null && typeof value === "object" && schema.properties !== void 0) {
  982. let propsSchema = schema.properties;
  983. value = { ...value };
  984. if (typeof propsSchema !== "object") {
  985. const resolvedSchema = schemaResolver.resolve(propsSchema);
  986. if (resolvedSchema.type !== DataType.OBJECT) {
  987. throw new import_js_format8.InvalidArgumentError(
  988. 'Unable to get the "properties" option from the data schema of %v type.',
  989. resolvedSchema.type || DataType.ANY
  990. );
  991. }
  992. propsSchema = resolvedSchema.properties || {};
  993. }
  994. Object.keys(propsSchema).forEach((propName) => {
  995. const propSchema = propsSchema[propName];
  996. if (propSchema === void 0) {
  997. return;
  998. }
  999. const propValue = value[propName];
  1000. const propPath = sourcePath ? sourcePath + `.${propName}` : propName;
  1001. const propOptions = { ...options, sourcePath: propPath };
  1002. const newPropValue = this.parse(propValue, propSchema, propOptions);
  1003. if (value[propName] !== newPropValue) {
  1004. value[propName] = newPropValue;
  1005. }
  1006. });
  1007. }
  1008. }
  1009. if (!noParsingErrors) {
  1010. const validator = this.getService(DataValidator);
  1011. validator.validate(value, schema, { shallowMode: true });
  1012. }
  1013. return value;
  1014. }
  1015. };
  1016. __name(_DataParser, "DataParser");
  1017. var DataParser = _DataParser;
  1018. // Annotate the CommonJS export names for ESM import in node:
  1019. 0 && (module.exports = {
  1020. DATA_TYPE_LIST,
  1021. DataParser,
  1022. DataParsingError,
  1023. DataSchemaRegistry,
  1024. DataSchemaResolver,
  1025. DataType,
  1026. DataValidationError,
  1027. DataValidator,
  1028. arrayTypeParser,
  1029. arrayTypeValidator,
  1030. booleanTypeParser,
  1031. booleanTypeValidator,
  1032. getDataTypeFromValue,
  1033. numberTypeParser,
  1034. numberTypeValidator,
  1035. objectTypeParser,
  1036. objectTypeValidator,
  1037. requiredValueValidator,
  1038. stringTypeParser,
  1039. stringTypeValidator,
  1040. validateDataSchema,
  1041. validateDataSchemaDefinition
  1042. });