validate.cjs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. 'use strict';
  2. const icon_defaults = require('../icon/defaults.cjs');
  3. const iconSet_tree = require('./tree.cjs');
  4. const matchChar = /^[a-f0-9]+(-[a-f0-9]+)*$/;
  5. function validateIconProps(item, fix, checkOtherProps) {
  6. for (const key in item) {
  7. const attr = key;
  8. const value = item[attr];
  9. const type = typeof value;
  10. if (type === "undefined") {
  11. delete item[attr];
  12. continue;
  13. }
  14. const expectedType = typeof icon_defaults.defaultExtendedIconProps[attr];
  15. if (expectedType !== "undefined") {
  16. if (type !== expectedType) {
  17. if (fix) {
  18. delete item[attr];
  19. continue;
  20. }
  21. return attr;
  22. }
  23. continue;
  24. }
  25. if (checkOtherProps && type === "object") {
  26. if (fix) {
  27. delete item[attr];
  28. } else {
  29. return key;
  30. }
  31. }
  32. }
  33. return null;
  34. }
  35. function validateIconSet(obj, options) {
  36. const fix = !!(options && options.fix);
  37. if (typeof obj !== "object" || obj === null || typeof obj.icons !== "object" || !obj.icons) {
  38. throw new Error("Bad icon set");
  39. }
  40. const data = obj;
  41. if (options && typeof options.prefix === "string") {
  42. data.prefix = options.prefix;
  43. } else if (
  44. // Prefix must be a string and not empty
  45. typeof data.prefix !== "string" || !data.prefix
  46. ) {
  47. throw new Error("Invalid prefix");
  48. }
  49. if (options && typeof options.provider === "string") {
  50. data.provider = options.provider;
  51. } else if (data.provider !== void 0) {
  52. const value = data.provider;
  53. if (typeof value !== "string") {
  54. if (fix) {
  55. delete data.provider;
  56. } else {
  57. throw new Error("Invalid provider");
  58. }
  59. }
  60. }
  61. if (data.aliases !== void 0) {
  62. if (typeof data.aliases !== "object" || data.aliases === null) {
  63. if (fix) {
  64. delete data.aliases;
  65. } else {
  66. throw new Error("Invalid aliases list");
  67. }
  68. }
  69. }
  70. const tree = iconSet_tree.getIconsTree(data);
  71. const icons = data.icons;
  72. const aliases = data.aliases || /* @__PURE__ */ Object.create(null);
  73. for (const name in tree) {
  74. const treeItem = tree[name];
  75. const isAlias = !icons[name];
  76. const parentObj = isAlias ? aliases : icons;
  77. if (!treeItem) {
  78. if (fix) {
  79. delete parentObj[name];
  80. continue;
  81. }
  82. throw new Error(`Invalid alias: ${name}`);
  83. }
  84. if (!name) {
  85. if (fix) {
  86. delete parentObj[name];
  87. continue;
  88. }
  89. throw new Error(`Invalid icon name: "${name}"`);
  90. }
  91. const item = parentObj[name];
  92. if (!isAlias) {
  93. if (typeof item.body !== "string") {
  94. if (fix) {
  95. delete parentObj[name];
  96. continue;
  97. }
  98. throw new Error(`Invalid icon: "${name}"`);
  99. }
  100. }
  101. const requiredProp = isAlias ? "parent" : "body";
  102. const key = typeof item[requiredProp] !== "string" ? requiredProp : validateIconProps(item, fix, true);
  103. if (key !== null) {
  104. throw new Error(`Invalid property "${key}" in "${name}"`);
  105. }
  106. }
  107. if (data.not_found !== void 0 && !(data.not_found instanceof Array)) {
  108. if (fix) {
  109. delete data.not_found;
  110. } else {
  111. throw new Error("Invalid not_found list");
  112. }
  113. }
  114. if (!Object.keys(data.icons).length && !(data.not_found && data.not_found.length)) {
  115. throw new Error("Icon set is empty");
  116. }
  117. if (fix && !Object.keys(aliases).length) {
  118. delete data.aliases;
  119. }
  120. const failedOptionalProp = validateIconProps(data, false, false);
  121. if (failedOptionalProp) {
  122. throw new Error(`Invalid value type for "${failedOptionalProp}"`);
  123. }
  124. if (data.chars !== void 0) {
  125. if (typeof data.chars !== "object" || data.chars === null) {
  126. if (fix) {
  127. delete data.chars;
  128. } else {
  129. throw new Error("Invalid characters map");
  130. }
  131. }
  132. }
  133. if (typeof data.chars === "object") {
  134. const chars = data.chars;
  135. Object.keys(chars).forEach((char) => {
  136. if (!matchChar.exec(char) || typeof chars[char] !== "string") {
  137. if (fix) {
  138. delete chars[char];
  139. return;
  140. }
  141. throw new Error(`Invalid character "${char}"`);
  142. }
  143. const target = chars[char];
  144. if (!data.icons[target] && (!data.aliases || !data.aliases[target])) {
  145. if (fix) {
  146. delete chars[char];
  147. return;
  148. }
  149. throw new Error(
  150. `Character "${char}" points to missing icon "${target}"`
  151. );
  152. }
  153. });
  154. if (fix && !Object.keys(data.chars).length) {
  155. delete data.chars;
  156. }
  157. }
  158. return data;
  159. }
  160. exports.matchChar = matchChar;
  161. exports.validateIconSet = validateIconSet;