From aaeac27d80b290b2f105dea67c64330d8ef63c70 Mon Sep 17 00:00:00 2001 From: Patrick Camacho Date: Sun, 5 Jul 2026 21:08:44 +0200 Subject: [PATCH 1/2] convert directory-tree to TypeScript: dist packaging, changeset --- .changeset/ts-directory-tree.md | 5 +++ packages/directory-tree/README.md | 19 ++++++---- ...{index.spec.js.snap => index.spec.ts.snap} | 0 .../directory-tree/{example.js => example.ts} | 2 +- .../{index.spec.js => index.spec.ts} | 2 +- .../directory-tree/{index.js => index.ts} | 38 ++++++++++++++----- packages/directory-tree/package.json | 15 ++++++-- packages/directory-tree/tsconfig.build.json | 18 +++++++++ packages/directory-tree/types.ts | 17 +++++++++ pnpm-lock.yaml | 14 +++++++ 10 files changed, 107 insertions(+), 23 deletions(-) create mode 100644 .changeset/ts-directory-tree.md rename packages/directory-tree/__snapshots__/{index.spec.js.snap => index.spec.ts.snap} (100%) rename packages/directory-tree/{example.js => example.ts} (89%) rename packages/directory-tree/{index.spec.js => index.spec.ts} (95%) rename packages/directory-tree/{index.js => index.ts} (61%) create mode 100644 packages/directory-tree/tsconfig.build.json create mode 100644 packages/directory-tree/types.ts diff --git a/.changeset/ts-directory-tree.md b/.changeset/ts-directory-tree.md new file mode 100644 index 0000000..ab0674d --- /dev/null +++ b/.changeset/ts-directory-tree.md @@ -0,0 +1,5 @@ +--- +'markdown-magic-directory-tree': minor +--- + +TypeScript: ship type declarations diff --git a/packages/directory-tree/README.md b/packages/directory-tree/README.md index 1878065..249593f 100644 --- a/packages/directory-tree/README.md +++ b/packages/directory-tree/README.md @@ -10,14 +10,14 @@ npm i markdown-magic markdown-magic-directory-tree --save-dev ## Adding the plugin -See `example.js` for usage. +See `example.ts` for usage. - + -```js +```ts import path from 'path'; import { markdownMagic } from 'markdown-magic'; -import DIRTREE from './index.js'; +import DIRTREE from './index.ts'; const config = { matchWord: 'AUTO-GENERATED-CONTENT', @@ -40,12 +40,15 @@ await markdownMagic(markdownPath, config); directory-tree/ ├── __fixtures__/ ├── __snapshots__/ -├── example.js -├── index.js -├── index.spec.js +├── dist/ +├── example.ts +├── index.spec.ts +├── index.ts ├── LICENSE ├── package.json -└── README.md +├── README.md +├── tsconfig.build.json +└── types.ts ``` diff --git a/packages/directory-tree/__snapshots__/index.spec.js.snap b/packages/directory-tree/__snapshots__/index.spec.ts.snap similarity index 100% rename from packages/directory-tree/__snapshots__/index.spec.js.snap rename to packages/directory-tree/__snapshots__/index.spec.ts.snap diff --git a/packages/directory-tree/example.js b/packages/directory-tree/example.ts similarity index 89% rename from packages/directory-tree/example.js rename to packages/directory-tree/example.ts index 27b841a..ec80a55 100644 --- a/packages/directory-tree/example.js +++ b/packages/directory-tree/example.ts @@ -1,6 +1,6 @@ import path from 'path'; import { markdownMagic } from 'markdown-magic'; -import DIRTREE from './index.js'; +import DIRTREE from './index.ts'; const config = { matchWord: 'AUTO-GENERATED-CONTENT', diff --git a/packages/directory-tree/index.spec.js b/packages/directory-tree/index.spec.ts similarity index 95% rename from packages/directory-tree/index.spec.js rename to packages/directory-tree/index.spec.ts index 5e3038e..7f9c853 100644 --- a/packages/directory-tree/index.spec.js +++ b/packages/directory-tree/index.spec.ts @@ -1,6 +1,6 @@ import path from 'path'; import { describe, expect, it } from 'vitest'; -import format from './index.js'; +import format from './index.ts'; const srcPath = path.join(import.meta.dirname, 'README.md'); diff --git a/packages/directory-tree/index.js b/packages/directory-tree/index.ts similarity index 61% rename from packages/directory-tree/index.js rename to packages/directory-tree/index.ts index 42cfda5..818f974 100644 --- a/packages/directory-tree/index.js +++ b/packages/directory-tree/index.ts @@ -1,20 +1,36 @@ import path from 'path'; import archy from 'archy'; import dirTree from 'directory-tree'; +import type { TransformArgs, TransformOptions } from './types.ts'; -const defaults = { +export type { TransformArgs, TransformOptions } from './types.ts'; + +interface Defaults { + depth: number; + dir: string; + onlyDirs: boolean; +} + +const defaults: Defaults = { depth: Infinity, dir: '.', onlyDirs: false, }; -const sortEntries = (a, b) => { +type DirNode = ReturnType; + +const sortEntries = (a: DirNode, b: DirNode): number => { if (a.type === 'directory' && b.type !== 'directory') return -1; if (a.type !== 'directory' && b.type === 'directory') return 1; return a.name.localeCompare(b.name); }; -const processNode = (node, ignore, options, depth = 0) => { +const processNode = ( + node: DirNode, + ignore: string[], + options: Defaults & TransformOptions, + depth = 0, +): archy.Data | undefined => { if ( ignore.includes(node.name) || depth > options.depth || @@ -22,23 +38,27 @@ const processNode = (node, ignore, options, depth = 0) => { ) return; - const response = { + const response: archy.Data = { label: `${node.name}${node.type === 'directory' ? '/' : ''}`, }; if (node.type === 'directory' && depth < options.depth) { depth++; - response.nodes = node.children + response.nodes = (node.children ?? []) .sort(sortEntries) .map((child) => processNode(child, ignore, options, depth)) - .filter((child) => !!child); + .filter((child): child is archy.Data => !!child); } return response; }; -export default function DIRTREE({ content: _content, options = {}, srcPath }) { - const opts = { ...defaults, ...options }; +export default function DIRTREE({ + content: _content, + options = {}, + srcPath, +}: TransformArgs): string { + const opts: Defaults & TransformOptions = { ...defaults, ...options }; const dir = path.resolve(path.dirname(srcPath), opts.dir); const ignore = opts.ignore || [ '.git', @@ -51,7 +71,7 @@ export default function DIRTREE({ content: _content, options = {}, srcPath }) { // caller opts in to extra attributes; `type` is required for our // directory-vs-file logic (attributes docs: https://github.com/mihneadb/node-directory-tree#options) const tree = archy( - processNode(dirTree(dir, { attributes: ['type'] }), ignore, opts), + processNode(dirTree(dir, { attributes: ['type'] }), ignore, opts)!, ); return ['```', tree.trim(), '```'].join('\n'); diff --git a/packages/directory-tree/package.json b/packages/directory-tree/package.json index f9b9dc6..c00408f 100644 --- a/packages/directory-tree/package.json +++ b/packages/directory-tree/package.json @@ -3,9 +3,10 @@ "version": "2.0.0", "description": "Print an archy tree for markdown file", "type": "module", - "main": "index.js", + "main": "dist/index.js", + "types": "dist/index.d.ts", "exports": { - ".": "./index.js", + ".": "./dist/index.js", "./package.json": "./package.json" }, "engines": { @@ -33,8 +34,11 @@ "plugin" ], "scripts": { + "prebuild": "rm -rf dist", + "build": "tsc --project tsconfig.build.json", + "prepack": "pnpm build", "test": "vitest run", - "docs": "node example.js && prettier --write README.md", + "docs": "node example.ts && prettier --write README.md", "format": "prettier --write ." }, "dependencies": { @@ -45,11 +49,14 @@ "markdown-magic": "^4" }, "devDependencies": { + "@types/archy": "^0.0.36", + "@types/node": "^24.13.2", "markdown-magic": "catalog:", "prettier": "catalog:", + "typescript": "^6.0.3", "vitest": "catalog:" }, "files": [ - "index.js" + "dist" ] } diff --git a/packages/directory-tree/tsconfig.build.json b/packages/directory-tree/tsconfig.build.json new file mode 100644 index 0000000..d7ec333 --- /dev/null +++ b/packages/directory-tree/tsconfig.build.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": false, + "outDir": "dist", + "rootDir": ".", + "types": ["node"] + }, + "exclude": [ + "node_modules", + "dist", + "*.spec.ts", + "example.ts", + "__fixtures__", + "__snapshots__" + ], + "include": ["*.ts"] +} diff --git a/packages/directory-tree/types.ts b/packages/directory-tree/types.ts new file mode 100644 index 0000000..20f1917 --- /dev/null +++ b/packages/directory-tree/types.ts @@ -0,0 +1,17 @@ +// Transform interface shared by markdown-magic plugins. Adapted from +// format-package's scripts/markdown-transformers.ts TransformArgs/TransformOptions +// (content: unknown -> content: string, the plugins' actual contract), plus +// this package's own directory-tree options. +export interface TransformOptions { + depth?: number; + dir?: string; + ignore?: string[]; + onlyDirs?: boolean; + [key: string]: unknown; +} + +export interface TransformArgs { + content: string; + options: TransformOptions; + srcPath: string; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c1e0321..54bb276 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -101,12 +101,21 @@ importers: specifier: ^3.0.0 version: 3.6.0 devDependencies: + '@types/archy': + specifier: ^0.0.36 + version: 0.0.36 + '@types/node': + specifier: ^24.13.2 + version: 24.13.2 markdown-magic: specifier: 'catalog:' version: 4.10.5 prettier: specifier: 'catalog:' version: 3.9.1 + typescript: + specifier: ^6.0.3 + version: 6.0.3 vitest: specifier: 'catalog:' version: 4.1.9(@types/node@24.13.2)(vite@8.1.0(@types/node@24.13.2)) @@ -543,6 +552,9 @@ packages: '@tybys/wasm-util@0.10.3': resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + '@types/archy@0.0.36': + resolution: {integrity: sha512-toTRTGD8trLtJsOaYbReoU/fyvRF1a4C5WtqjDZ3NnT/zvO807opSBRBJBr5VhD66JnY3BUz2UvnY5/KMAt6mw==} + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -2358,6 +2370,8 @@ snapshots: tslib: 2.8.1 optional: true + '@types/archy@0.0.36': {} + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 From 3156115828d62613b75bf1b14fc03ef42519bb5f Mon Sep 17 00:00:00 2001 From: Patrick Camacho Date: Sun, 5 Jul 2026 21:11:33 +0200 Subject: [PATCH 2/2] ignore dist in default tree output --- .changeset/ts-directory-tree.md | 2 ++ packages/directory-tree/README.md | 1 - packages/directory-tree/index.ts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.changeset/ts-directory-tree.md b/.changeset/ts-directory-tree.md index ab0674d..6cc98d4 100644 --- a/.changeset/ts-directory-tree.md +++ b/.changeset/ts-directory-tree.md @@ -3,3 +3,5 @@ --- TypeScript: ship type declarations + +Also adds `dist` to the default ignore list so build artifacts never render in the generated tree (this package self-demos DIRTREE on its own README; a docs regen with a locally-built `dist/` present would otherwise diverge from CI, which regenerates before `pnpm -r build` runs). diff --git a/packages/directory-tree/README.md b/packages/directory-tree/README.md index 249593f..76e49d7 100644 --- a/packages/directory-tree/README.md +++ b/packages/directory-tree/README.md @@ -40,7 +40,6 @@ await markdownMagic(markdownPath, config); directory-tree/ ├── __fixtures__/ ├── __snapshots__/ -├── dist/ ├── example.ts ├── index.spec.ts ├── index.ts diff --git a/packages/directory-tree/index.ts b/packages/directory-tree/index.ts index 818f974..9f868bc 100644 --- a/packages/directory-tree/index.ts +++ b/packages/directory-tree/index.ts @@ -66,6 +66,7 @@ export default function DIRTREE({ '.gitignore', 'node_modules', '.DS_Store', + 'dist', ]; // directory-tree@3 only returns `name`/`path` (+`children`) unless the // caller opts in to extra attributes; `type` is required for our