misc.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { dirname } from 'node:path';
  2. import fs from 'node:fs';
  3. import type { PathLike } from 'node:fs';
  4. import fsp from 'node:fs/promises';
  5. export type MaybePromise<T> = T | Promise<T>;
  6. export function fastStringCompare(a: string, b: string) {
  7. const lenA = a.length;
  8. const lenB = b.length;
  9. const minLen = lenA < lenB ? lenA : lenB;
  10. for (let i = 0; i < minLen; ++i) {
  11. const ca = a.charCodeAt(i);
  12. const cb = b.charCodeAt(i);
  13. if (ca > cb) return 1;
  14. if (ca < cb) return -1;
  15. }
  16. if (lenA === lenB) {
  17. return 0;
  18. }
  19. return lenA > lenB ? 1 : -1;
  20. };
  21. interface Write {
  22. (
  23. destination: string,
  24. input: NodeJS.TypedArray | string,
  25. ): Promise<void>
  26. }
  27. export function mkdirp(dir: string) {
  28. if (fs.existsSync(dir)) {
  29. return;
  30. }
  31. return fsp.mkdir(dir, { recursive: true });
  32. }
  33. export const writeFile: Write = async (destination: string, input, dir = dirname(destination)): Promise<void> => {
  34. const p = mkdirp(dir);
  35. if (p) {
  36. await p;
  37. }
  38. return fsp.writeFile(destination, input, { encoding: 'utf-8' });
  39. };
  40. export const removeFiles = async (files: string[]) => Promise.all(files.map((file) => fsp.rm(file, { force: true })));
  41. export function withBannerArray(title: string, description: string[] | readonly string[], date: Date, content: string[]) {
  42. return [
  43. '#########################################',
  44. `# ${title}`,
  45. `# Last Updated: ${date.toISOString()}`,
  46. `# Size: ${content.length}`,
  47. ...description.map(line => (line ? `# ${line}` : '#')),
  48. '#########################################',
  49. ...content,
  50. '################## EOF ##################'
  51. ];
  52. };
  53. export function notSupported(name: string) {
  54. return (...args: unknown[]) => {
  55. console.error(`${name}: not supported.`, args);
  56. throw new Error(`${name}: not implemented.`);
  57. };
  58. }
  59. export function withIdentityContent(title: string, description: string[] | readonly string[], date: Date, content: string[]) {
  60. return content;
  61. };
  62. export function isDirectoryEmptySync(path: PathLike) {
  63. const directoryHandle = fs.opendirSync(path);
  64. try {
  65. return directoryHandle.readSync() === null;
  66. } finally {
  67. directoryHandle.closeSync();
  68. }
  69. }
  70. export function fastIpVersion(ip: string) {
  71. return ip.includes(':') ? 6 : (ip.includes('.') ? 4 : 0);
  72. }