index.mjs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. function genString(input, options = {}) {
  2. const str = JSON.stringify(input);
  3. if (!options.singleQuotes) {
  4. return str;
  5. }
  6. return `'${escapeString(str).slice(1, -1)}'`;
  7. }
  8. const NEEDS_ESCAPE_RE = /[\n\r'\\\u2028\u2029]/;
  9. const QUOTE_NEWLINE_RE = /([\n\r'\u2028\u2029])/g;
  10. const BACKSLASH_RE = /\\/g;
  11. function escapeString(id) {
  12. if (!NEEDS_ESCAPE_RE.test(id)) {
  13. return id;
  14. }
  15. return id.replace(BACKSLASH_RE, "\\\\").replace(QUOTE_NEWLINE_RE, "\\$1");
  16. }
  17. function genSafeVariableName(name) {
  18. if (reservedNames.has(name)) {
  19. return `_${name}`;
  20. }
  21. return name.replace(/^\d/, (r) => `_${r}`).replace(/\W/g, (r) => "_" + r.charCodeAt(0));
  22. }
  23. const reservedNames = /* @__PURE__ */ new Set([
  24. "Infinity",
  25. "NaN",
  26. "arguments",
  27. "await",
  28. "break",
  29. "case",
  30. "catch",
  31. "class",
  32. "const",
  33. "continue",
  34. "debugger",
  35. "default",
  36. "delete",
  37. "do",
  38. "else",
  39. "enum",
  40. "eval",
  41. "export",
  42. "extends",
  43. "false",
  44. "finally",
  45. "for",
  46. "function",
  47. "if",
  48. "implements",
  49. "import",
  50. "in",
  51. "instanceof",
  52. "interface",
  53. "let",
  54. "new",
  55. "null",
  56. "package",
  57. "private",
  58. "protected",
  59. "public",
  60. "return",
  61. "static",
  62. "super",
  63. "switch",
  64. "this",
  65. "throw",
  66. "true",
  67. "try",
  68. "typeof",
  69. "undefined",
  70. "var",
  71. "void",
  72. "while",
  73. "with",
  74. "yield"
  75. ]);
  76. function _genStatement(type, specifier, names, options = {}) {
  77. const specifierString = genString(specifier, options);
  78. if (!names) {
  79. return `${type} ${specifierString};`;
  80. }
  81. const nameArray = Array.isArray(names);
  82. const _names = (nameArray ? names : [names]).map((index) => {
  83. if (typeof index === "string") {
  84. return { name: index };
  85. }
  86. if (index.name === index.as) {
  87. index = { name: index.name };
  88. }
  89. return index;
  90. });
  91. const namesString = _names.map((index) => index.as ? `${index.name} as ${index.as}` : index.name).join(", ");
  92. if (nameArray) {
  93. return `${type} { ${namesString} } from ${genString(
  94. specifier,
  95. options
  96. )}${_genImportAttributes(type, options)};`;
  97. }
  98. return `${type} ${namesString} from ${genString(
  99. specifier,
  100. options
  101. )}${_genImportAttributes(type, options)};`;
  102. }
  103. function _genImportAttributes(type, options) {
  104. if (type === "import type" || type === "export type") {
  105. return "";
  106. }
  107. if (typeof options.attributes?.type === "string") {
  108. return ` with { type: ${genString(options.attributes.type)} }`;
  109. }
  110. if (typeof options.assert?.type === "string") {
  111. return ` assert { type: ${genString(options.assert.type)} }`;
  112. }
  113. return "";
  114. }
  115. function genImport(specifier, imports, options = {}) {
  116. return _genStatement("import", specifier, imports, options);
  117. }
  118. function genTypeImport(specifier, imports, options = {}) {
  119. return _genStatement("import type", specifier, imports, options);
  120. }
  121. function genExport(specifier, exports, options = {}) {
  122. return _genStatement("export", specifier, exports, options);
  123. }
  124. function genDynamicImport(specifier, options = {}) {
  125. const commentString = options.comment ? ` /* ${options.comment} */` : "";
  126. const wrapperString = options.wrapper === false ? "" : "() => ";
  127. const ineropString = options.interopDefault ? ".then(m => m.default || m)" : "";
  128. const optionsString = _genDynamicImportAttributes(options);
  129. return `${wrapperString}import(${genString(
  130. specifier,
  131. options
  132. )}${commentString}${optionsString})${ineropString}`;
  133. }
  134. function _genDynamicImportAttributes(options = {}) {
  135. if (typeof options.assert?.type === "string") {
  136. return `, { assert: { type: ${genString(options.assert.type)} } }`;
  137. }
  138. if (typeof options.attributes?.type === "string") {
  139. return `, { with: { type: ${genString(options.attributes.type)} } }`;
  140. }
  141. return "";
  142. }
  143. function wrapInDelimiters(lines, indent = "", delimiters = "{}", withComma = true) {
  144. if (lines.length === 0) {
  145. return delimiters;
  146. }
  147. const [start, end] = delimiters;
  148. return `${start}
  149. ` + lines.join(withComma ? ",\n" : "\n") + `
  150. ${indent}${end}`;
  151. }
  152. const VALID_IDENTIFIER_RE = /^[$_]?([A-Z_a-z]\w*|\d)$/;
  153. function genObjectKey(key) {
  154. return VALID_IDENTIFIER_RE.test(key) ? key : genString(key);
  155. }
  156. function genObjectFromRaw(object, indent = "", options = {}) {
  157. return genObjectFromRawEntries(Object.entries(object), indent, options);
  158. }
  159. function genObjectFromValues(obj, indent = "", options = {}) {
  160. return genObjectFromRaw(obj, indent, { preserveTypes: true, ...options });
  161. }
  162. function genArrayFromRaw(array, indent = "", options = {}) {
  163. const newIdent = indent + " ";
  164. return wrapInDelimiters(
  165. array.map((index) => `${newIdent}${genRawValue(index, newIdent, options)}`),
  166. indent,
  167. "[]"
  168. );
  169. }
  170. function genObjectFromRawEntries(array, indent = "", options = {}) {
  171. const newIdent = indent + " ";
  172. return wrapInDelimiters(
  173. array.map(
  174. ([key, value]) => `${newIdent}${genObjectKey(key)}: ${genRawValue(value, newIdent, options)}`
  175. ),
  176. indent,
  177. "{}"
  178. );
  179. }
  180. function genRawValue(value, indent = "", options = {}) {
  181. if (value === void 0) {
  182. return "undefined";
  183. }
  184. if (value === null) {
  185. return "null";
  186. }
  187. if (Array.isArray(value)) {
  188. return genArrayFromRaw(value, indent, options);
  189. }
  190. if (value && typeof value === "object") {
  191. return genObjectFromRaw(value, indent, options);
  192. }
  193. if (options.preserveTypes && typeof value !== "function") {
  194. return JSON.stringify(value);
  195. }
  196. return value.toString();
  197. }
  198. function genTypeExport(specifier, imports, options = {}) {
  199. return _genStatement("export type", specifier, imports, options);
  200. }
  201. function genInlineTypeImport(specifier, name = "default", options = {}) {
  202. return `typeof ${genDynamicImport(specifier, {
  203. ...options,
  204. wrapper: false
  205. })}.${name}`;
  206. }
  207. function genTypeObject(object, indent = "") {
  208. const newIndent = indent + " ";
  209. return wrapInDelimiters(
  210. Object.entries(object).map(([key, value]) => {
  211. const [, k = key, optional = ""] = key.match(/^(.*[^?])(\?)?$/) || [];
  212. if (typeof value === "string") {
  213. return `${newIndent}${genObjectKey(k)}${optional}: ${value}`;
  214. }
  215. return `${newIndent}${genObjectKey(k)}${optional}: ${genTypeObject(
  216. value,
  217. newIndent
  218. )}`;
  219. }),
  220. indent,
  221. "{}",
  222. false
  223. );
  224. }
  225. function genInterface(name, contents, options = {}, indent = "") {
  226. const result = [
  227. options.export && "export",
  228. `interface ${name}`,
  229. options.extends && `extends ${Array.isArray(options.extends) ? options.extends.join(", ") : options.extends}`,
  230. contents ? genTypeObject(contents, indent) : "{}"
  231. ].filter(Boolean).join(" ");
  232. return result;
  233. }
  234. function genAugmentation(specifier, interfaces) {
  235. return `declare module ${genString(specifier)} ${wrapInDelimiters(
  236. Object.entries(interfaces || {}).map(
  237. ([key, entry]) => " " + (Array.isArray(entry) ? genInterface(key, ...entry) : genInterface(key, entry, {}, " "))
  238. )
  239. )}`;
  240. }
  241. export { escapeString, genArrayFromRaw, genAugmentation, genDynamicImport, genExport, genImport, genInlineTypeImport, genInterface, genObjectFromRaw, genObjectFromRawEntries, genObjectFromValues, genObjectKey, genSafeVariableName, genString, genTypeExport, genTypeImport, genTypeObject, wrapInDelimiters };