misc.ts 2.3 KB

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