版博士V2.0程序
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 

183 行
4.6 KiB

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