{"id":16974618,"url":"https://github.com/alttiri/util-node-js","last_synced_at":"2026-03-01T10:35:03.741Z","repository":{"id":37498996,"uuid":"487366659","full_name":"AlttiRi/util-node-js","owner":"AlttiRi","description":"Some Node.js util functions. Mostly it's a draft version for personal use.","archived":false,"fork":false,"pushed_at":"2025-06-18T14:39:29.000Z","size":139,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-02T20:06:10.559Z","etag":null,"topics":["js","nodejs"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@alttiri/util-node-js","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlttiRi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-30T19:42:47.000Z","updated_at":"2025-06-18T14:39:33.000Z","dependencies_parsed_at":"2024-08-21T15:18:12.146Z","dependency_job_id":"619055a6-6eb9-49e4-a5aa-f1bce7cb7e83","html_url":"https://github.com/AlttiRi/util-node-js","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/AlttiRi/util-node-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Futil-node-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Futil-node-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Futil-node-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Futil-node-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlttiRi","download_url":"https://codeload.github.com/AlttiRi/util-node-js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Futil-node-js/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266229388,"owners_count":23896253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["js","nodejs"],"created_at":"2024-10-14T01:07:16.034Z","updated_at":"2026-03-01T10:35:03.667Z","avatar_url":"https://github.com/AlttiRi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [util-node-js](https://github.com/AlttiRi/util-node-js)\n\nSome Node.js util functions. \n\nMostly it's a draft version for personal use.\n\n## *.d.ts\n\n```ts\ntype ANSIColor = \"black\" | \"red\" | \"green\" | \"yellow\" | \"blue\" | \"magenta\" | \"cyan\" | \"white\";\ntype ColoringFunc = (text: any) =\u003e string;\n/**\n * [ANSI_escape_code#SGR]{@link https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters}\n * \\```\n * \"32\" - Green [ANSI]\n * \"36\" - Cyan  [ANSI]\n * \"38;5;208\" - Orange #ff8700 [8-bit]\n * \"38;5;99\"  - Violet #875fff [8-bit]\n * \"38;2;173;255;47\" - Green-Yellow #adff2f [24-bit]\n * \\```\n * @example\n * const COL_VIOLET_DARK = getColoring(\"38;5;92\");\n * console.log(COL_VIOLET_DARK(\"This text is 8-bit dark violet\"));\n *\n * @param {string} mode\n * @return {ColoringFunc}\n */\nexport declare function getColoring(mode: string): ColoringFunc;\nexport type AnsiColoringOpts = {\n    bright?: boolean;\n    bold?: boolean;\n};\n/**\n * @example\n * const ANSI_RED_BOLD = getAnsiColoring(\"RED\", {bold: true});\n * console.log(ANSI_RED_BOLD(\"This text is bold red\"));\n * @param {ANSIColor?} color = \"white\"\n * @param {AnsiColoringOpts?} opts\n * @param {boolean?} opts.bright = false\n * @param {boolean?} opts.bold   = false\n * @return {ColoringFunc}\n */\nexport declare function getAnsiColoring(color?: ANSIColor, opts?: AnsiColoringOpts): ColoringFunc;\n\nexport declare const ANSI_BLUE: (text: any) =\u003e string;\nexport declare const ANSI_CYAN: (text: any) =\u003e string;\nexport declare const ANSI_GREEN: (text: any) =\u003e string;\nexport declare const ANSI_GRAY: (text: any) =\u003e string;\nexport declare const ANSI_GREEN_BOLD: (text: any) =\u003e string;\nexport declare const ANSI_RED_BOLD: (text: any) =\u003e string;\nexport declare const COL_ORANGE: (text: any) =\u003e string;\nexport declare const COL_VIOLET: (text: any) =\u003e string;\nexport declare const COL_GRAY: (text: any) =\u003e string;\n\nexport declare const saveCursorPosition: () =\u003e boolean;\nexport declare const restoreCursorPosition: () =\u003e boolean;\nexport declare const eraseCursorLine: () =\u003e boolean;\nexport declare const moveCursorToTop: (num?: number) =\u003e boolean;\nexport declare function stdWrite(text: string): Promise\u003cvoid\u003e;\n\nexport declare function exists(path: string, followSymbol?: boolean): Promise\u003cboolean\u003e;\n/** Is the passed symlink looped — if referrers to a parent directory. */\nexport declare function isSymLooped(filepath: string): Promise\u003cboolean\u003e;\ntype FileInfo = {\n    path: string;\n    stats: Stats;\n    link?: LinkInfo;\n};\ntype LinkInfo = {\n    pathTo: string;\n    content: string;\n};\nexport declare function getFileInfo(filepath: string): Promise\u003cFileInfo\u003e;\nexport declare function readLink(filepath: string): Promise\u003c{\n    pathTo: string;\n    content: string;\n}\u003e;\n\nexport type ConstructorOpts = {\n    printSuccess?: boolean;\n    testOnly?: number[];\n    stackDeep?: number;\n    autoReport?: boolean;\n};\nexport type TestOpts = {\n    result: any;\n    expect: any;\n    stackDeep?: number;\n    name?: string;\n    printLink?: boolean;\n    autoReport?: boolean;\n    printSuccess?: boolean;\n};\nexport type TesterMethods = {\n    /** @deprecated */\n    eq(name: string, result: any, expect: any): void;\n    t(opt: TestOpts): void;\n    report(): void;\n};\nexport declare class Tester {\n    private readonly passed;\n    private readonly failed;\n    private readonly printSuccess;\n    private num;\n    private readonly testOnly;\n    private readonly stackDeep;\n    private timerId;\n    private readonly autoReport;\n    /** @deprecated */\n    eq(name: string, result: any, expect: any): void;\n    destructible(): TesterMethods;\n    constructor(opt?: ConstructorOpts);\n    t(opt: TestOpts): void;\n    private delayReport;\n    report(): void;\n}\nexport type LineNumType = {\n    relFilePath: string;\n    lineNum?: string;\n    column?: string;\n};\n```\n\n## *.d.ts (fs-list)\n\n```ts\nexport declare function toListEntryDirent(dirEntry: Dirent, settings: FileListingSetting): ListEntryDirent;\nexport declare function toListEntryDirentError(error: IOError, listEntry: ListEntryDirent): ListEntryDirentError;\nexport declare function toLinkInfo(entry: ListEntryDirent): Promise\u003cListEntryDirent | ListEntryDirentLink\u003e;\nexport declare function toListEntryStatsError(entry: ListEntryBaseEx, err: IOError): ListEntryStats;\nexport declare function direntsToEntries(dirents: Dirent[], settings: FileListingSetting): Promise\u003c(ListEntryDirent | ListEntryDirentLink)[]\u003e;\n/** 100 lines of code to handle edge cases to create the root entry */\nexport declare function getRootEntry({ filepath, _map, bigint }: FileListingSetting): Promise\u003cListEntryStatsAny\u003e;\n\nexport declare function listFiles(initSettings: FileListingSettingInit \u0026 {\n    stats: false;\n}): AsyncGenerator\u003cListEntryBaseEx\u003e;\nexport declare function listFiles(initSettings: FileListingSettingInit \u0026 {\n    bigint: true;\n}): AsyncGenerator\u003cListEntryStatsBigInt\u003e;\n\n/**\n Returns an object:\n\\```ts\n{\n    path: string,\n    dirent: Dirent,\n    stats?: Stats | BigIntStats,\n    link?: LinkInfo,\n    errors?: {\n        [name in \"readdir\" | \"stats\" | \"readlink\"]?: IOError\n    },\n}\n\\```\nThe return object's keys info:\n\\```\n- path   — `string`.\n    The full path with the filename.\n\n- dirent — `Dirent`.\n     A `Dirent` from `fs.readdir`.\n     For the root folder a \"fake\" `Dirent` is used:\n        - \"DirentLike\"  — created based on `Stats`\n        - \"DirentDummy\" — if there were errors (`errors: {stats, readdir}`)\n\n- stats? — `Stats | BigIntStats`.\n    Optional, exists only when the scan option `stats` is `true`.\n    Type depends on `bigint` option.\n    Is missed if there is `errors.stats` error.\n\n- link? — `LinkInfo`.\n    Optional, exists only for symlinks.\n    `LinkInfo` is an alias for `{\n        pathTo: string,\n        content: string,\n    }`.\n    Is missed if there is `errors.readlink` error.\n\n- errors? — an `object` with `IOError`s.\n    Optional, exists only one or more errors occurred.\n    Possible errors:\n    - \"readdir\"\n    - \"stats\"\n    - \"readlink\"\n\\```\n @note `listFiles` does not follow symlinks.\n @options\n\\```js\n - filepath:    string  = process.cwd(), // filepath of a (root) directory to list\n - recursively: boolean = true,\n - yieldDir:    boolean = false,\n - yieldRoot:   boolean = true,         // (is used only if `yieldDir` is `true`)\n - depthFirst:  boolean = true,         // travel strategy\n - breadthFirstRoot: boolean = false,   // breadth first strategy for the root folder (if `depthFirst` is `true`)\n - stats:       boolean = true,\n - bigint:      boolean = false,        // (use only if `stats` is `true`)\n - parallels:   number  = 4,            // count of `fs.stats` executed in parallel\n\\```\n */\nexport declare function listFiles(initSettings: FileListingSettingInit): AsyncGenerator\u003cListEntryStats\u003e;\n\nexport declare function _listFilesWithStat(settings: FileListingSetting, listEntries: ListEntryDirent): AsyncGenerator\u003cListEntryStatsAny\u003e;\nexport type FileListingSettingInit = Partial\u003cFileListingSetting\u003e;\n/** An entry of the listing of the content of a directory. */\nexport type FileListingSetting = {\n    /** filepath of a directory to list */\n    filepath: string;\n    recursively: boolean;\n    yieldDir: boolean;\n    yieldRoot: boolean;\n    /** travel strategy */\n    depthFirst: boolean;\n    /** breadth first strategy for the root folder (if `depthFirst` is `true`) */\n    breadthFirstRoot: boolean;\n    stats: boolean;\n    bigint: boolean;\n    /** The count of `fs.stats` executed in parallel */\n    parallels: number;\n    _currentDeep: number;\n    _map: Map\u003cListEntryDirent, Dirent[]\u003e;\n};\nexport declare function getDefaultSettings(): FileListingSetting;\n```\n\n## *.d.ts (fs-list types)\n\n```ts\n/**\n * The error object that happens while scanning.\n * @example\n * [Error: EPERM: operation not permitted, scandir \"C:\\\\$Recycle.Bin\\\\S-1-5-18\"] {\n *   errno: -4048,\n *   code: \"EPERM\",\n *   syscall: \"scandir\",\n *   path: \"C:\\\\$Recycle.Bin\\\\S-1-5-18\"\n * }\n * [Error: EACCES: permission denied, scandir '/boot/efi'] {\n *   errno: -13,\n *   code: 'EACCES',\n *   syscall: 'scandir',\n *   path: '/boot/efi'\n * }\n * // [note] It is missed for \"read\" (`createReadStream`) of a folder.\n * [Error: EISDIR: illegal operation on a directory, read] {\n *   errno: -4068,\n *   code: 'EISDIR',\n *   syscall: 'read'\n * }\n */\nexport interface IOError extends Error {\n    syscall: string;\n    code: string;\n    errno: number;\n    path: string;\n}\nimport { Dirent, BigIntStats, Stats } from \"node:fs\";\nimport { IOError } from \"./IOError.js\";\n/**\n * The simplified type example:\n * @example\n * type ListEntrySimplifiedFullType = {\n *     path: string,\n *     dirent: Dirent,\n *     stats?: Stats | BigIntStats,\n *     link?: LinkInfo,\n *     errors?: {\n *         [name in \"readdir\" | \"stats\" | \"readlink\"]?: IOError\n *     },\n * };\n */\nexport type ListEntryBase = ListEntryDirent | ListEntryDirentError;\nexport type ListEntryDirent = {\n    path: string;\n    dirent: Dirent;\n};\nexport type ListEntryDirentError = {\n    path: string;\n    dirent: Dirent;\n    errors: DirError;\n};\nexport type DirError = {\n    readdir: IOError;\n};\nexport type StatError = {\n    stats: IOError;\n};\nexport type LinkError = {\n    readlink: IOError;\n};\nexport type LinkInfo = {\n    pathTo: string;\n    content: string;\n};\nexport type LinkEntry = {\n    link: LinkInfo;\n};\nexport type LinkEntryError = {\n    errors: LinkError;\n};\nexport type LinkEntryBase = LinkEntry | LinkEntryError;\nexport type ListEntryDirentLink = ListEntryDirent \u0026 LinkEntryBase;\nexport type ListEntryBaseEx = ListEntryBase | ListEntryDirentLink;\nexport type StatEntry = {\n    stats: Stats;\n};\nexport type StatEntryBigInt = {\n    stats: BigIntStats;\n};\nexport type StatEntryAny = {\n    stats: Stats | BigIntStats;\n};\nexport type StatEntryError = {\n    errors: StatError;\n};\nexport type StatEntryBase = StatEntry | StatEntryError;\nexport type StatEntryBaseBigInt = StatEntryBigInt | StatEntryError;\nexport type StatEntryBaseAny = StatEntryAny | StatEntryError;\nexport type ListEntryStats = StatEntryBase \u0026 ListEntryBaseEx;\nexport type ListEntryStatsBigInt = StatEntryBaseBigInt \u0026 ListEntryBaseEx;\nexport type ListEntryStatsAny = StatEntryBaseAny \u0026 ListEntryBaseEx;\n```\n\n## Installation\n\n### From NPM\n\n```bash\nnpm install @alttiri/util-node-js\n```\n\n\u003cdetails\u003e\n\n\u003csummary\u003eFrom GitHub Packages\u003c/summary\u003e\n\n\n### From GitHub Packages:\nTo install you need first to create `.npmrc` file with `@alttiri:registry=https://npm.pkg.github.com` content:\n```bash\necho @alttiri:registry=https://npm.pkg.github.com \u003e\u003e .npmrc\n```\n\nonly then run\n\n```bash\nnpm install @alttiri/util-node-js\n```\nNote, that GitHub Packages requires to have also `~/.npmrc` file (`.npmrc` in your home dir) with `//npm.pkg.github.com/:_authToken=TOKEN` content, where `TOKEN` is a token with the `read:packages` permission, take it here https://github.com/settings/tokens/new. \n\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falttiri%2Futil-node-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falttiri%2Futil-node-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falttiri%2Futil-node-js/lists"}