convert-info.mjs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. const minDisplayHeight = 16;
  2. const maxDisplayHeight = 24;
  3. function validateDisplayHeight(value) {
  4. while (value < minDisplayHeight) {
  5. value *= 2;
  6. }
  7. while (value > maxDisplayHeight) {
  8. value /= 2;
  9. }
  10. return value === Math.round(value) && value >= minDisplayHeight && value <= maxDisplayHeight ? value : 0;
  11. }
  12. function convertIconSetInfo(data, expectedPrefix = "") {
  13. if (typeof data !== "object" || data === null) {
  14. return null;
  15. }
  16. const source = data;
  17. const getSourceNestedString = (field, key, defaultValue = "") => {
  18. if (typeof source[field] !== "object") {
  19. return defaultValue;
  20. }
  21. const obj = source[field];
  22. return typeof obj[key] === "string" ? obj[key] : defaultValue;
  23. };
  24. let name;
  25. if (typeof source.name === "string") {
  26. name = source.name;
  27. } else if (typeof source.title === "string") {
  28. name = source.title;
  29. } else {
  30. return null;
  31. }
  32. if (expectedPrefix !== "" && typeof source.prefix === "string" && source.prefix !== expectedPrefix) {
  33. return null;
  34. }
  35. const info = {
  36. name
  37. };
  38. switch (typeof source.total) {
  39. case "number":
  40. info.total = source.total;
  41. break;
  42. case "string": {
  43. const num = parseInt(source.total);
  44. if (num > 0) {
  45. info.total = num;
  46. }
  47. break;
  48. }
  49. }
  50. if (typeof source.version === "string") {
  51. info.version = source.version;
  52. }
  53. info.author = {
  54. name: getSourceNestedString(
  55. "author",
  56. "name",
  57. typeof source.author === "string" ? source.author : ""
  58. )
  59. };
  60. if (typeof source.author === "object") {
  61. const sourceAuthor = source.author;
  62. if (typeof sourceAuthor.url === "string") {
  63. info.author.url = sourceAuthor.url;
  64. }
  65. }
  66. info.license = {
  67. title: getSourceNestedString(
  68. "license",
  69. "title",
  70. typeof source.license === "string" ? source.license : ""
  71. )
  72. };
  73. if (typeof source.license === "object") {
  74. const sourceLicense = source.license;
  75. if (typeof sourceLicense.spdx === "string") {
  76. info.license.spdx = sourceLicense.spdx;
  77. }
  78. if (typeof sourceLicense.url === "string") {
  79. info.license.url = sourceLicense.url;
  80. }
  81. }
  82. if (source.samples instanceof Array) {
  83. const samples = [];
  84. source.samples.forEach((item) => {
  85. if (typeof item === "string" && !samples.includes(item)) {
  86. samples.push(item);
  87. }
  88. });
  89. if (samples.length) {
  90. info.samples = samples;
  91. }
  92. }
  93. if (typeof source.height === "number" || typeof source.height === "string") {
  94. const num = parseInt(source.height);
  95. if (num > 0) {
  96. info.height = num;
  97. }
  98. }
  99. if (source.height instanceof Array) {
  100. source.height.forEach((item) => {
  101. const num = parseInt(item);
  102. if (num > 0) {
  103. if (!(info.height instanceof Array)) {
  104. info.height = [];
  105. }
  106. info.height.push(num);
  107. }
  108. });
  109. switch (info.height.length) {
  110. case 0:
  111. delete info.height;
  112. break;
  113. case 1:
  114. info.height = info.height[0];
  115. }
  116. }
  117. if (typeof info.height === "number") {
  118. const displayHeight = validateDisplayHeight(info.height);
  119. if (displayHeight && displayHeight !== info.height) {
  120. info.displayHeight = displayHeight;
  121. }
  122. }
  123. ["samplesHeight", "displayHeight"].forEach((prop) => {
  124. const value = source[prop];
  125. if (typeof value === "number" || typeof value === "string") {
  126. const displayHeight = validateDisplayHeight(
  127. parseInt(value)
  128. );
  129. if (displayHeight) {
  130. info.displayHeight = displayHeight;
  131. }
  132. }
  133. });
  134. if (typeof source.category === "string") {
  135. info.category = source.category;
  136. }
  137. if (source.tags instanceof Array) {
  138. info.tags = source.tags;
  139. }
  140. switch (typeof source.palette) {
  141. case "boolean":
  142. info.palette = source.palette;
  143. break;
  144. case "string":
  145. switch (source.palette.toLowerCase()) {
  146. case "colorless":
  147. case "false":
  148. info.palette = false;
  149. break;
  150. case "colorful":
  151. case "true":
  152. info.palette = true;
  153. }
  154. break;
  155. }
  156. if (source.hidden === true) {
  157. info.hidden = true;
  158. }
  159. Object.keys(source).forEach((key) => {
  160. const value = source[key];
  161. if (typeof value !== "string") {
  162. return;
  163. }
  164. switch (key) {
  165. case "url":
  166. case "uri":
  167. info.author.url = value;
  168. break;
  169. case "licenseURL":
  170. case "licenseURI":
  171. info.license.url = value;
  172. break;
  173. case "licenseID":
  174. case "licenseSPDX":
  175. info.license.spdx = value;
  176. break;
  177. }
  178. });
  179. return info;
  180. }
  181. export { convertIconSetInfo };