convert-info.cjs 4.6 KB

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