index.cjs 31 KB

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