版博士V2.0程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

160 lines
4.5 KiB

  1. import { matchIconName } from '../icon/name.mjs';
  2. import { defaultExtendedIconProps } from '../icon/defaults.mjs';
  3. import { getIconsTree } from './tree.mjs';
  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 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 (typeof data.prefix !== "string" || !data.prefix.match(matchIconName)) {
  44. throw new Error("Invalid prefix");
  45. }
  46. if (options && typeof options.provider === "string") {
  47. data.provider = options.provider;
  48. } else if (data.provider !== void 0) {
  49. const value = data.provider;
  50. if (typeof value !== "string" || value !== "" && !value.match(matchIconName)) {
  51. if (fix) {
  52. delete data.provider;
  53. } else {
  54. throw new Error("Invalid provider");
  55. }
  56. }
  57. }
  58. if (data.aliases !== void 0) {
  59. if (typeof data.aliases !== "object" || data.aliases === null) {
  60. if (fix) {
  61. delete data.aliases;
  62. } else {
  63. throw new Error("Invalid aliases list");
  64. }
  65. }
  66. }
  67. const tree = getIconsTree(data);
  68. const icons = data.icons;
  69. const aliases = data.aliases || /* @__PURE__ */ Object.create(null);
  70. for (const name in tree) {
  71. const treeItem = tree[name];
  72. const isAlias = !icons[name];
  73. const parentObj = isAlias ? aliases : icons;
  74. if (!treeItem) {
  75. if (fix) {
  76. delete parentObj[name];
  77. continue;
  78. }
  79. throw new Error(`Invalid alias: ${name}`);
  80. }
  81. if (!name.match(matchIconName)) {
  82. if (fix) {
  83. delete parentObj[name];
  84. continue;
  85. }
  86. throw new Error(`Invalid icon name: "${name}"`);
  87. }
  88. const item = parentObj[name];
  89. if (!isAlias) {
  90. if (typeof item.body !== "string") {
  91. if (fix) {
  92. delete parentObj[name];
  93. continue;
  94. }
  95. throw new Error(`Invalid icon: "${name}"`);
  96. }
  97. }
  98. const requiredProp = isAlias ? "parent" : "body";
  99. const key = typeof item[requiredProp] !== "string" ? requiredProp : validateIconProps(item, fix, true);
  100. if (key !== null) {
  101. throw new Error(`Invalid property "${key}" in "${name}"`);
  102. }
  103. }
  104. if (data.not_found !== void 0 && !(data.not_found instanceof Array)) {
  105. if (fix) {
  106. delete data.not_found;
  107. } else {
  108. throw new Error("Invalid not_found list");
  109. }
  110. }
  111. if (!Object.keys(data.icons).length && !(data.not_found && data.not_found.length)) {
  112. throw new Error("Icon set is empty");
  113. }
  114. if (fix && !Object.keys(aliases).length) {
  115. delete data.aliases;
  116. }
  117. const failedOptionalProp = validateIconProps(data, false, false);
  118. if (failedOptionalProp) {
  119. throw new Error(`Invalid value type for "${failedOptionalProp}"`);
  120. }
  121. if (data.chars !== void 0) {
  122. if (typeof data.chars !== "object" || data.chars === null) {
  123. if (fix) {
  124. delete data.chars;
  125. } else {
  126. throw new Error("Invalid characters map");
  127. }
  128. }
  129. }
  130. if (typeof data.chars === "object") {
  131. const chars = data.chars;
  132. Object.keys(chars).forEach((char) => {
  133. if (!matchChar.exec(char) || typeof chars[char] !== "string") {
  134. if (fix) {
  135. delete chars[char];
  136. return;
  137. }
  138. throw new Error(`Invalid character "${char}"`);
  139. }
  140. const target = chars[char];
  141. if (!data.icons[target] && (!data.aliases || !data.aliases[target])) {
  142. if (fix) {
  143. delete chars[char];
  144. return;
  145. }
  146. throw new Error(
  147. `Character "${char}" points to missing icon "${target}"`
  148. );
  149. }
  150. });
  151. if (fix && !Object.keys(data.chars).length) {
  152. delete data.chars;
  153. }
  154. }
  155. return data;
  156. }
  157. export { matchChar, validateIconSet };