@kubb/fabric-core 0.2.16 → 0.2.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Fabric-CBrTERuf.d.cts → Fabric-BezqNTQ9.d.cts} +12 -7
- package/dist/{Fabric-AmREkq58.d.ts → Fabric-CVe8cc8b.d.ts} +12 -7
- package/dist/{defineProperty-Dlhh3lSJ.cjs → defineProperty-DZi5DvrW.cjs} +13 -1
- package/dist/{defineProperty-Dlhh3lSJ.cjs.map → defineProperty-DZi5DvrW.cjs.map} +1 -1
- package/dist/{defineProperty-_FBdEen_.js → defineProperty-DcP1vZ2K.js} +2 -2
- package/dist/{defineProperty-_FBdEen_.js.map → defineProperty-DcP1vZ2K.js.map} +1 -1
- package/dist/index.cjs +28 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +28 -5
- package/dist/index.js.map +1 -1
- package/dist/parsers/typescript.d.cts +2 -2
- package/dist/parsers/typescript.d.ts +2 -2
- package/dist/parsers.d.cts +2 -2
- package/dist/parsers.d.ts +2 -2
- package/dist/plugins.cjs +3 -5
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.d.cts +7 -1
- package/dist/plugins.d.ts +7 -1
- package/dist/plugins.js +3 -5
- package/dist/plugins.js.map +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/{typescriptParser-DaOfAlmM.d.ts → typescriptParser-B5SxjtvV.d.ts} +2 -2
- package/dist/{typescriptParser-C3B3dzh_.d.cts → typescriptParser-PfAO0SSm.d.cts} +2 -2
- package/package.json +1 -1
- package/src/Fabric.ts +7 -8
- package/src/FileManager.ts +16 -1
- package/src/defineFabric.ts +1 -1
- package/src/plugins/barrelPlugin.ts +7 -1
- package/src/plugins/fsPlugin.ts +1 -1
- package/src/utils/AsyncEventEmitter.ts +14 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["e","NodeEventEmitter","parser: Parser | undefined","resolvedFiles: Array<KubbFile.ResolvedFile>","files: Array<KubbFile.ResolvedFile>","context: FabricContext<T>","fabric: Fabric<T>","isFunction"],"sources":["../../../node_modules/.pnpm/remeda@2.32.0/node_modules/remeda/dist/isFunction-BJjFuZR7.js","../src/utils/AsyncEventEmitter.ts","../src/FileProcessor.ts","../src/utils/Cache.ts","../src/FileManager.ts","../src/defineFabric.ts","../src/createFabric.ts"],"sourcesContent":["const e=e=>typeof e==`function`;export{e as isFunction};\n//# sourceMappingURL=isFunction-BJjFuZR7.js.map","import { EventEmitter as NodeEventEmitter } from 'node:events'\nimport type { FabricMode } from '../Fabric.ts'\n\ntype Options = {\n mode?: FabricMode\n maxListener?: number\n}\n\nexport class AsyncEventEmitter<TEvents extends Record<string, any>> {\n constructor({ maxListener = 100, mode = 'sequential' }: Options = {}) {\n this.#emitter.setMaxListeners(maxListener)\n this.#mode = mode\n }\n\n #emitter = new NodeEventEmitter()\n #mode: FabricMode\n\n async emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void> {\n const listeners = this.#emitter.listeners(eventName) as Array<(...args: TEvents[TEventName]) => any>\n\n if (listeners.length === 0) {\n return\n }\n\n if (this.#mode === 'sequential') {\n // Run listeners one by one, in order\n for (const listener of listeners) {\n try {\n await listener(...eventArgs)\n } catch (err) {\n console.error(`Error in listener for \"${eventName}\":`, err)\n }\n }\n } else {\n // Run all listeners concurrently\n const promises = listeners.map(async (listener) => {\n try {\n await listener(...eventArgs)\n } catch (err) {\n console.error(`Error in listener for \"${eventName}\":`, err)\n }\n })\n await Promise.all(promises)\n }\n }\n\n on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {\n this.#emitter.on(eventName, handler as any)\n }\n\n onOnce<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArgs: TEvents[TEventName]) => void): void {\n const wrapper = (...args: TEvents[TEventName]) => {\n this.off(eventName, wrapper)\n handler(...args)\n }\n this.on(eventName, wrapper)\n }\n\n off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {\n this.#emitter.off(eventName, handler as any)\n }\n\n removeAll(): void {\n this.#emitter.removeAllListeners()\n }\n}\n","import pLimit from 'p-limit'\nimport type { FabricEvents, FabricMode } from './Fabric.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport { defaultParser } from './parsers/defaultParser.ts'\nimport type { Parser } from './parsers/types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\n\nexport type ProcessFilesProps = {\n parsers?: Set<Parser>\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n dryRun?: boolean\n /**\n * @default 'sequential'\n */\n mode?: FabricMode\n}\n\ntype GetParseOptions = {\n parsers?: Set<Parser>\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n}\n\ntype Options = {\n events?: AsyncEventEmitter<FabricEvents>\n}\n\nexport class FileProcessor {\n #limit = pLimit(100)\n events: AsyncEventEmitter<FabricEvents>\n\n constructor({ events = new AsyncEventEmitter<FabricEvents>() }: Options = {}) {\n this.events = events\n\n return this\n }\n\n async parse(file: KubbFile.ResolvedFile, { parsers, extension }: GetParseOptions = {}): Promise<string> {\n const parseExtName = extension?.[file.extname] || undefined\n\n if (!parsers) {\n console.warn('No parsers provided, using default parser. If you want to use a specific parser, please provide it in the options.')\n\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n if (!file.extname) {\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n let parser: Parser | undefined\n for (const item of parsers) {\n if (item.extNames?.includes(file.extname)) {\n parser = item\n break\n }\n }\n\n if (!parser) {\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n return parser.parse(file, { extname: parseExtName })\n }\n\n async run(\n files: Array<KubbFile.ResolvedFile>,\n { parsers, mode = 'sequential', dryRun, extension }: ProcessFilesProps = {},\n ): Promise<KubbFile.ResolvedFile[]> {\n await this.events.emit('process:start', { files })\n\n let processed = 0\n const total = files.length\n\n const processOne = async (resolvedFile: KubbFile.ResolvedFile, index: number) => {\n const percentage = (processed / total) * 100\n\n await this.events.emit('file:start', { file: resolvedFile, index, total })\n\n const source = dryRun ? undefined : await this.parse(resolvedFile, { extension, parsers })\n\n await this.events.emit('process:progress', {\n file: resolvedFile,\n source,\n processed,\n percentage,\n total,\n })\n\n processed++\n\n await this.events.emit('file:end', { file: resolvedFile, index, total })\n }\n\n if (mode === 'sequential') {\n async function* asyncFiles() {\n for (let index = 0; index < files.length; index++) {\n yield [files[index], index] as const\n }\n }\n\n for await (const [file, index] of asyncFiles()) {\n if (file) {\n await processOne(file, index)\n }\n }\n } else {\n const promises = files.map((resolvedFile, index) => this.#limit(() => processOne(resolvedFile, index)))\n await Promise.all(promises)\n }\n\n await this.events.emit('process:end', { files })\n\n return files\n }\n}\n","export class Cache<T> {\n #buffer = new Map<string, T>()\n\n get(key: string): T | null {\n return this.#buffer.get(key) ?? null\n }\n\n set(key: string, value: T): void {\n this.#buffer.set(key, value)\n }\n\n delete(key: string): void {\n this.#buffer.delete(key)\n }\n\n clear(): void {\n this.#buffer.clear()\n }\n\n keys(): string[] {\n return [...this.#buffer.keys()]\n }\n\n values(): Array<T> {\n return [...this.#buffer.values()]\n }\n\n flush(): void {\n // No-op for base cache\n }\n}\n","import { orderBy } from 'natural-orderby'\nimport { createFile } from './createFile.ts'\nimport type { FabricEvents } from './Fabric.ts'\nimport { FileProcessor, type ProcessFilesProps } from './FileProcessor.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\nimport { Cache } from './utils/Cache.ts'\nimport { trimExtName } from './utils/trimExtName.ts'\n\nfunction mergeFile<TMeta extends object = object>(a: KubbFile.File<TMeta>, b: KubbFile.File<TMeta>): KubbFile.File<TMeta> {\n return {\n ...a,\n sources: [...(a.sources || []), ...(b.sources || [])],\n imports: [...(a.imports || []), ...(b.imports || [])],\n exports: [...(a.exports || []), ...(b.exports || [])],\n }\n}\n\ntype Options = {\n events?: AsyncEventEmitter<FabricEvents>\n}\n\nexport class FileManager {\n #cache = new Cache<KubbFile.ResolvedFile>()\n #filesCache: Array<KubbFile.ResolvedFile> | null = null\n events: AsyncEventEmitter<FabricEvents>\n processor: FileProcessor\n\n constructor({ events = new AsyncEventEmitter<FabricEvents>() }: Options = {}) {\n this.processor = new FileProcessor({ events })\n\n this.events = events\n return this\n }\n\n async add(...files: Array<KubbFile.File>) {\n const resolvedFiles: Array<KubbFile.ResolvedFile> = []\n\n const mergedFiles = new Map<string, KubbFile.File>()\n\n files.forEach((file) => {\n const existing = mergedFiles.get(file.path)\n if (existing) {\n mergedFiles.set(file.path, mergeFile(existing, file))\n } else {\n mergedFiles.set(file.path, file)\n }\n })\n\n for (const file of mergedFiles.values()) {\n const existing = this.#cache.get(file.path)\n\n const merged = existing ? mergeFile(existing, file) : file\n const resolvedFile = createFile(merged)\n\n this.#cache.set(resolvedFile.path, resolvedFile)\n this.flush()\n\n resolvedFiles.push(resolvedFile)\n }\n\n await this.events.emit('file:add', { files: resolvedFiles })\n\n return resolvedFiles\n }\n\n flush() {\n this.#filesCache = null\n this.#cache.flush()\n }\n\n getByPath(path: KubbFile.Path): KubbFile.ResolvedFile | null {\n return this.#cache.get(path)\n }\n\n deleteByPath(path: KubbFile.Path): void {\n this.#cache.delete(path)\n this.#filesCache = null\n }\n\n clear(): void {\n this.#cache.clear()\n this.#filesCache = null\n }\n\n get files(): Array<KubbFile.ResolvedFile> {\n if (this.#filesCache) {\n return [...this.#filesCache]\n }\n\n const cachedKeys = this.#cache.keys()\n\n // order by path length and if file is a barrel file\n const keys = orderBy(cachedKeys, [(v) => v.length, (v) => trimExtName(v).endsWith('index')])\n\n const files: Array<KubbFile.ResolvedFile> = []\n\n for (const key of keys) {\n const file = this.#cache.get(key)\n if (file) {\n files.push(file)\n }\n }\n\n this.#filesCache = files\n\n return [...files]\n }\n\n //TODO add test and check if write of FileManager contains the newly added file\n async write(options: ProcessFilesProps): Promise<KubbFile.ResolvedFile[]> {\n await this.events.emit('write:start', { files: this.files })\n\n const resolvedFiles = await this.processor.run(this.files, options)\n\n this.clear()\n\n await this.events.emit('write:end', { files: resolvedFiles })\n\n return resolvedFiles\n }\n}\n","import { isFunction } from 'remeda'\nimport type { Fabric, FabricConfig, FabricContext, FabricEvents, FabricOptions } from './Fabric.ts'\nimport { FileManager } from './FileManager.ts'\nimport type { Parser } from './parsers/types.ts'\nimport type { Plugin } from './plugins/types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\n\n/**\n * Function that initializes the root Fabric instance.\n *\n * Used for setting up plugins, parsers, or performing side effects\n * once the Fabric context is ready.\n */\ntype FabricInitializer<T extends FabricOptions> = (fabric: Fabric<T>) => void | Promise<void>\n\n/**\n * A function returned by {@link defineFabric} that creates a Fabric instance.\n */\nexport type CreateFabric<T extends FabricOptions> = (config?: FabricConfig<T>) => Fabric<T>\n\n/**\n * Defines a new Fabric factory function.\n *\n * @example\n * export const createFabric = defineFabric((fabric) => {\n * fabric.use(myPlugin())\n * })\n */\nexport function defineFabric<T extends FabricOptions>(init?: FabricInitializer<T>): CreateFabric<T> {\n function create(config?: FabricConfig<T>): Fabric<T> {\n const events = new AsyncEventEmitter<FabricEvents>()\n const installedPlugins = new Set<Plugin<any>>()\n const installedParsers = new Set<Parser<any>>()\n const fileManager = new FileManager({ events })\n\n const context: FabricContext<T> = {\n get files() {\n return fileManager.files\n },\n async addFile(...files) {\n await fileManager.add(...files)\n },\n config,\n fileManager,\n installedPlugins,\n installedParsers,\n on: events.on.bind(events),\n off: events.off.bind(events),\n onOnce: events.onOnce.bind(events),\n removeAll: events.removeAll.bind(events),\n emit: events.emit.bind(events),\n } as FabricContext<T>\n\n const fabric: Fabric<T> = {\n context,\n get files() {\n return fileManager.files\n },\n async addFile(...files) {\n await fileManager.add(...files)\n },\n async use(pluginOrParser, ...options) {\n if (pluginOrParser.type === 'plugin') {\n if (installedPlugins.has(pluginOrParser)) {\n console.warn(`Plugin \"${pluginOrParser.name}\" already applied.`)\n } else {\n installedPlugins.add(pluginOrParser)\n }\n\n if (isFunction(pluginOrParser.inject)) {\n const injecter = pluginOrParser.inject\n\n const injected = (injecter as any)(context, ...options)\n Object.assign(fabric, injected)\n }\n }\n\n if (pluginOrParser.type === 'parser') {\n if (installedParsers.has(pluginOrParser)) {\n console.warn(`Parser \"${pluginOrParser.name}\" already applied.`)\n } else {\n installedParsers.add(pluginOrParser)\n }\n }\n\n if (isFunction(pluginOrParser.install)) {\n const installer = pluginOrParser.install\n\n await (installer as any)(context, ...options)\n }\n\n return fabric\n },\n } as Fabric<T>\n\n if (init) {\n init(fabric)\n }\n\n return fabric\n }\n\n return create\n}\n","import { defineFabric } from './defineFabric.ts'\n\nexport const createFabric = defineFabric()\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["e","NodeEventEmitter","errors: Error[]","parser: Parser | undefined","resolvedFiles: Array<KubbFile.ResolvedFile>","files: Array<KubbFile.ResolvedFile>","context: FabricContext<T>","fabric: Fabric<T>","isFunction"],"sources":["../../../node_modules/.pnpm/remeda@2.32.0/node_modules/remeda/dist/isFunction-BJjFuZR7.js","../src/utils/AsyncEventEmitter.ts","../src/FileProcessor.ts","../src/utils/Cache.ts","../src/FileManager.ts","../src/defineFabric.ts","../src/createFabric.ts"],"sourcesContent":["const e=e=>typeof e==`function`;export{e as isFunction};\n//# sourceMappingURL=isFunction-BJjFuZR7.js.map","import { EventEmitter as NodeEventEmitter } from 'node:events'\nimport type { FabricMode } from '../Fabric.ts'\n\ntype Options = {\n mode?: FabricMode\n maxListener?: number\n}\n\nexport class AsyncEventEmitter<TEvents extends Record<string, any>> {\n constructor({ maxListener = 100, mode = 'sequential' }: Options = {}) {\n this.#emitter.setMaxListeners(maxListener)\n this.#mode = mode\n }\n\n #emitter = new NodeEventEmitter()\n #mode: FabricMode\n\n async emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void> {\n const listeners = this.#emitter.listeners(eventName) as Array<(...args: TEvents[TEventName]) => any>\n\n if (listeners.length === 0) {\n return\n }\n\n const errors: Error[] = []\n\n if (this.#mode === 'sequential') {\n // Run listeners one by one, in order\n for (const listener of listeners) {\n try {\n await listener(...eventArgs)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n errors.push(error)\n }\n }\n } else {\n // Run all listeners concurrently\n const promises = listeners.map(async (listener) => {\n try {\n await listener(...eventArgs)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n errors.push(error)\n }\n })\n await Promise.all(promises)\n }\n\n if (errors.length === 1) {\n throw errors[0]\n }\n\n if (errors.length > 1) {\n throw new AggregateError(errors, `Errors in async listeners for \"${eventName}\"`)\n }\n }\n\n on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {\n this.#emitter.on(eventName, handler as any)\n }\n\n onOnce<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArgs: TEvents[TEventName]) => void): void {\n const wrapper = (...args: TEvents[TEventName]) => {\n this.off(eventName, wrapper)\n handler(...args)\n }\n this.on(eventName, wrapper)\n }\n\n off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {\n this.#emitter.off(eventName, handler as any)\n }\n\n removeAll(): void {\n this.#emitter.removeAllListeners()\n }\n}\n","import pLimit from 'p-limit'\nimport type { FabricEvents, FabricMode } from './Fabric.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport { defaultParser } from './parsers/defaultParser.ts'\nimport type { Parser } from './parsers/types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\n\nexport type ProcessFilesProps = {\n parsers?: Set<Parser>\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n dryRun?: boolean\n /**\n * @default 'sequential'\n */\n mode?: FabricMode\n}\n\ntype GetParseOptions = {\n parsers?: Set<Parser>\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n}\n\ntype Options = {\n events?: AsyncEventEmitter<FabricEvents>\n}\n\nexport class FileProcessor {\n #limit = pLimit(100)\n events: AsyncEventEmitter<FabricEvents>\n\n constructor({ events = new AsyncEventEmitter<FabricEvents>() }: Options = {}) {\n this.events = events\n\n return this\n }\n\n async parse(file: KubbFile.ResolvedFile, { parsers, extension }: GetParseOptions = {}): Promise<string> {\n const parseExtName = extension?.[file.extname] || undefined\n\n if (!parsers) {\n console.warn('No parsers provided, using default parser. If you want to use a specific parser, please provide it in the options.')\n\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n if (!file.extname) {\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n let parser: Parser | undefined\n for (const item of parsers) {\n if (item.extNames?.includes(file.extname)) {\n parser = item\n break\n }\n }\n\n if (!parser) {\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n return parser.parse(file, { extname: parseExtName })\n }\n\n async run(\n files: Array<KubbFile.ResolvedFile>,\n { parsers, mode = 'sequential', dryRun, extension }: ProcessFilesProps = {},\n ): Promise<KubbFile.ResolvedFile[]> {\n await this.events.emit('process:start', { files })\n\n let processed = 0\n const total = files.length\n\n const processOne = async (resolvedFile: KubbFile.ResolvedFile, index: number) => {\n const percentage = (processed / total) * 100\n\n await this.events.emit('file:start', { file: resolvedFile, index, total })\n\n const source = dryRun ? undefined : await this.parse(resolvedFile, { extension, parsers })\n\n await this.events.emit('process:progress', {\n file: resolvedFile,\n source,\n processed,\n percentage,\n total,\n })\n\n processed++\n\n await this.events.emit('file:end', { file: resolvedFile, index, total })\n }\n\n if (mode === 'sequential') {\n async function* asyncFiles() {\n for (let index = 0; index < files.length; index++) {\n yield [files[index], index] as const\n }\n }\n\n for await (const [file, index] of asyncFiles()) {\n if (file) {\n await processOne(file, index)\n }\n }\n } else {\n const promises = files.map((resolvedFile, index) => this.#limit(() => processOne(resolvedFile, index)))\n await Promise.all(promises)\n }\n\n await this.events.emit('process:end', { files })\n\n return files\n }\n}\n","export class Cache<T> {\n #buffer = new Map<string, T>()\n\n get(key: string): T | null {\n return this.#buffer.get(key) ?? null\n }\n\n set(key: string, value: T): void {\n this.#buffer.set(key, value)\n }\n\n delete(key: string): void {\n this.#buffer.delete(key)\n }\n\n clear(): void {\n this.#buffer.clear()\n }\n\n keys(): string[] {\n return [...this.#buffer.keys()]\n }\n\n values(): Array<T> {\n return [...this.#buffer.values()]\n }\n\n flush(): void {\n // No-op for base cache\n }\n}\n","import { orderBy } from 'natural-orderby'\nimport { createFile } from './createFile.ts'\nimport type { FabricEvents } from './Fabric.ts'\nimport { FileProcessor, type ProcessFilesProps } from './FileProcessor.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\nimport { Cache } from './utils/Cache.ts'\nimport { trimExtName } from './utils/trimExtName.ts'\n\nfunction mergeFile<TMeta extends object = object>(a: KubbFile.File<TMeta>, b: KubbFile.File<TMeta>): KubbFile.File<TMeta> {\n return {\n ...a,\n sources: [...(a.sources || []), ...(b.sources || [])],\n imports: [...(a.imports || []), ...(b.imports || [])],\n exports: [...(a.exports || []), ...(b.exports || [])],\n }\n}\n\ntype Options = {\n events?: AsyncEventEmitter<FabricEvents>\n}\n\nexport class FileManager {\n #cache = new Cache<KubbFile.ResolvedFile>()\n #filesCache: Array<KubbFile.ResolvedFile> | null = null\n events: AsyncEventEmitter<FabricEvents>\n processor: FileProcessor\n\n constructor({ events = new AsyncEventEmitter<FabricEvents>() }: Options = {}) {\n this.processor = new FileProcessor({ events })\n\n this.events = events\n return this\n }\n\n async #resolvePath(file: KubbFile.File): Promise<KubbFile.File> {\n await this.events.emit('file:resolve:path', { file })\n\n return file\n }\n\n async #resolveName(file: KubbFile.File): Promise<KubbFile.File> {\n await this.events.emit('file:resolve:name', { file })\n\n return file\n }\n\n async add(...files: Array<KubbFile.File>) {\n const resolvedFiles: Array<KubbFile.ResolvedFile> = []\n\n const mergedFiles = new Map<string, KubbFile.File>()\n\n files.forEach((file) => {\n const existing = mergedFiles.get(file.path)\n if (existing) {\n mergedFiles.set(file.path, mergeFile(existing, file))\n } else {\n mergedFiles.set(file.path, file)\n }\n })\n\n for (let file of mergedFiles.values()) {\n const existing = this.#cache.get(file.path)\n\n file = await this.#resolveName(file)\n file = await this.#resolvePath(file)\n\n const merged = existing ? mergeFile(existing, file) : file\n const resolvedFile = createFile(merged)\n\n this.#cache.set(resolvedFile.path, resolvedFile)\n this.flush()\n\n resolvedFiles.push(resolvedFile)\n }\n\n await this.events.emit('file:add', { files: resolvedFiles })\n\n return resolvedFiles\n }\n\n flush() {\n this.#filesCache = null\n this.#cache.flush()\n }\n\n getByPath(path: KubbFile.Path): KubbFile.ResolvedFile | null {\n return this.#cache.get(path)\n }\n\n deleteByPath(path: KubbFile.Path): void {\n this.#cache.delete(path)\n this.#filesCache = null\n }\n\n clear(): void {\n this.#cache.clear()\n this.#filesCache = null\n }\n\n get files(): Array<KubbFile.ResolvedFile> {\n if (this.#filesCache) {\n return [...this.#filesCache]\n }\n\n const cachedKeys = this.#cache.keys()\n\n // order by path length and if file is a barrel file\n const keys = orderBy(cachedKeys, [(v) => v.length, (v) => trimExtName(v).endsWith('index')])\n\n const files: Array<KubbFile.ResolvedFile> = []\n\n for (const key of keys) {\n const file = this.#cache.get(key)\n if (file) {\n files.push(file)\n }\n }\n\n this.#filesCache = files\n\n return [...files]\n }\n\n //TODO add test and check if write of FileManager contains the newly added file\n async write(options: ProcessFilesProps): Promise<KubbFile.ResolvedFile[]> {\n await this.events.emit('write:start', { files: this.files })\n\n const resolvedFiles = await this.processor.run(this.files, options)\n\n this.clear()\n\n await this.events.emit('write:end', { files: resolvedFiles })\n\n return resolvedFiles\n }\n}\n","import { isFunction } from 'remeda'\nimport type { Fabric, FabricConfig, FabricContext, FabricEvents, FabricOptions } from './Fabric.ts'\nimport { FileManager } from './FileManager.ts'\nimport type { Parser } from './parsers/types.ts'\nimport type { Plugin } from './plugins/types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\n\n/**\n * Function that initializes the root Fabric instance.\n *\n * Used for setting up plugins, parsers, or performing side effects\n * once the Fabric context is ready.\n */\ntype FabricInitializer<T extends FabricOptions> = (fabric: Fabric<T>) => void | Promise<void>\n\n/**\n * A function returned by {@link defineFabric} that creates a Fabric instance.\n */\nexport type CreateFabric<T extends FabricOptions> = (config?: FabricConfig<T>) => Fabric<T>\n\n/**\n * Defines a new Fabric factory function.\n *\n * @example\n * export const createFabric = defineFabric((fabric) => {\n * fabric.use(myPlugin())\n * })\n */\nexport function defineFabric<T extends FabricOptions>(init?: FabricInitializer<T>): CreateFabric<T> {\n function create(config: FabricConfig<T> = { mode: 'sequential' } as FabricConfig<T>): Fabric<T> {\n const events = new AsyncEventEmitter<FabricEvents>()\n const installedPlugins = new Set<Plugin<any>>()\n const installedParsers = new Set<Parser<any>>()\n const fileManager = new FileManager({ events })\n\n const context: FabricContext<T> = {\n get files() {\n return fileManager.files\n },\n async addFile(...files) {\n await fileManager.add(...files)\n },\n config,\n fileManager,\n installedPlugins,\n installedParsers,\n on: events.on.bind(events),\n off: events.off.bind(events),\n onOnce: events.onOnce.bind(events),\n removeAll: events.removeAll.bind(events),\n emit: events.emit.bind(events),\n } as FabricContext<T>\n\n const fabric: Fabric<T> = {\n context,\n get files() {\n return fileManager.files\n },\n async addFile(...files) {\n await fileManager.add(...files)\n },\n async use(pluginOrParser, ...options) {\n if (pluginOrParser.type === 'plugin') {\n if (installedPlugins.has(pluginOrParser)) {\n console.warn(`Plugin \"${pluginOrParser.name}\" already applied.`)\n } else {\n installedPlugins.add(pluginOrParser)\n }\n\n if (isFunction(pluginOrParser.inject)) {\n const injecter = pluginOrParser.inject\n\n const injected = (injecter as any)(context, ...options)\n Object.assign(fabric, injected)\n }\n }\n\n if (pluginOrParser.type === 'parser') {\n if (installedParsers.has(pluginOrParser)) {\n console.warn(`Parser \"${pluginOrParser.name}\" already applied.`)\n } else {\n installedParsers.add(pluginOrParser)\n }\n }\n\n if (isFunction(pluginOrParser.install)) {\n const installer = pluginOrParser.install\n\n await (installer as any)(context, ...options)\n }\n\n return fabric\n },\n } as Fabric<T>\n\n if (init) {\n init(fabric)\n }\n\n return fabric\n }\n\n return create\n}\n","import { defineFabric } from './defineFabric.ts'\n\nexport const createFabric = defineFabric()\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "../Fabric-
|
|
2
|
-
import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-
|
|
1
|
+
import "../Fabric-BezqNTQ9.cjs";
|
|
2
|
+
import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-PfAO0SSm.cjs";
|
|
3
3
|
export { createExport, createImport, print, typescriptParser };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "../Fabric-
|
|
2
|
-
import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-
|
|
1
|
+
import "../Fabric-CVe8cc8b.js";
|
|
2
|
+
import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-B5SxjtvV.js";
|
|
3
3
|
export { createExport, createImport, print, typescriptParser };
|
package/dist/parsers.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as UserParser, u as Parser } from "./Fabric-
|
|
2
|
-
import { i as typescriptParser } from "./typescriptParser-
|
|
1
|
+
import { d as UserParser, u as Parser } from "./Fabric-BezqNTQ9.cjs";
|
|
2
|
+
import { i as typescriptParser } from "./typescriptParser-PfAO0SSm.cjs";
|
|
3
3
|
|
|
4
4
|
//#region src/parsers/createParser.d.ts
|
|
5
5
|
declare function createParser<TOptions = unknown, TMeta extends object = any>(parser: UserParser<TOptions, TMeta>): Parser<TOptions, TMeta>;
|
package/dist/parsers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as UserParser, u as Parser } from "./Fabric-
|
|
2
|
-
import { i as typescriptParser } from "./typescriptParser-
|
|
1
|
+
import { d as UserParser, u as Parser } from "./Fabric-CVe8cc8b.js";
|
|
2
|
+
import { i as typescriptParser } from "./typescriptParser-B5SxjtvV.js";
|
|
3
3
|
|
|
4
4
|
//#region src/parsers/createParser.d.ts
|
|
5
5
|
declare function createParser<TOptions = unknown, TMeta extends object = any>(parser: UserParser<TOptions, TMeta>): Parser<TOptions, TMeta>;
|
package/dist/plugins.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_trimExtName = require('./trimExtName-Bb4zGVF1.cjs');
|
|
2
|
-
const require_defineProperty = require('./defineProperty-
|
|
2
|
+
const require_defineProperty = require('./defineProperty-DZi5DvrW.cjs');
|
|
3
3
|
const require_getRelativePath = require('./getRelativePath-C6lvNCs7.cjs');
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
node_path = require_trimExtName.__toESM(node_path);
|
|
@@ -198,7 +198,6 @@ const barrelPlugin = createPlugin({
|
|
|
198
198
|
inject(ctx, options) {
|
|
199
199
|
if (!options) throw new Error("Barrel plugin requires options.root and options.mode");
|
|
200
200
|
return { async writeEntry({ root, mode }) {
|
|
201
|
-
var _ctx$config;
|
|
202
201
|
if (!mode || mode === "propagate") return;
|
|
203
202
|
const rootPath = node_path.default.resolve(root, "index.ts");
|
|
204
203
|
const entryFile = require_defineProperty.createFile({
|
|
@@ -222,7 +221,7 @@ const barrelPlugin = createPlugin({
|
|
|
222
221
|
});
|
|
223
222
|
await ctx.addFile(entryFile);
|
|
224
223
|
await ctx.fileManager.write({
|
|
225
|
-
mode:
|
|
224
|
+
mode: ctx.config.mode,
|
|
226
225
|
dryRun: options.dryRun,
|
|
227
226
|
parsers: ctx.installedParsers
|
|
228
227
|
});
|
|
@@ -267,9 +266,8 @@ const fsPlugin = createPlugin({
|
|
|
267
266
|
},
|
|
268
267
|
inject(ctx, { dryRun } = {}) {
|
|
269
268
|
return { async write(options = { extension: { ".ts": ".ts" } }) {
|
|
270
|
-
var _ctx$config;
|
|
271
269
|
await ctx.fileManager.write({
|
|
272
|
-
mode:
|
|
270
|
+
mode: ctx.config.mode,
|
|
273
271
|
extension: options.extension,
|
|
274
272
|
dryRun,
|
|
275
273
|
parsers: ctx.installedParsers
|
package/dist/plugins.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.cjs","names":["stack: Array<TreeNode<TData>>","result: Array<TreeNode<TData>>","nodes: Array<{ id: string; label: string }>","edges: Array<{ from: string; to: string }>","next: TreeNode<BarrelData> | undefined","path","createFile","getRelativePath","path","fs","path","http","createFile","path","SingleBar","Presets","process"],"sources":["../src/utils/TreeNode.ts","../src/plugins/createPlugin.ts","../src/plugins/barrelPlugin.ts","../src/plugins/fsPlugin.ts","../src/utils/open.ts","../src/plugins/graphPlugin.ts","../src/plugins/progressPlugin.ts"],"sourcesContent":["import type * as KubbFile from '../KubbFile.ts'\n\ntype BarrelData = {\n file?: KubbFile.File\n path: string\n name: string\n}\n\nexport type Graph = {\n nodes: Array<{ id: string; label: string }>\n edges: Array<{ from: string; to: string }>\n}\n\nexport class TreeNode<TData = unknown> {\n data: TData\n parent?: TreeNode<TData>\n children: Array<TreeNode<TData>> = []\n #cachedLeaves?: Array<TreeNode<TData>>\n\n constructor(data: TData, parent?: TreeNode<TData>) {\n this.data = data\n this.parent = parent\n }\n\n addChild(data: TData): TreeNode<TData> {\n const child = new TreeNode(data, this)\n this.children.push(child)\n this.#cachedLeaves = undefined // invalidate cached leaves\n return child\n }\n\n get leaves(): Array<TreeNode<TData>> {\n if (this.#cachedLeaves) return this.#cachedLeaves\n if (this.children.length === 0) return [this]\n\n const stack: Array<TreeNode<TData>> = [...this.children]\n const result: Array<TreeNode<TData>> = []\n\n for (const node of stack) {\n if (node.children.length) {\n for (const child of node.children) stack.push(child)\n } else {\n result.push(node)\n }\n }\n\n this.#cachedLeaves = result\n return result\n }\n\n forEach(callback: (node: TreeNode<TData>) => void): this {\n const stack: Array<TreeNode<TData>> = [this]\n\n for (const node of stack) {\n callback(node)\n if (node.children.length) {\n for (const child of node.children) stack.push(child)\n }\n }\n return this\n }\n\n findDeep(predicate: (node: TreeNode<TData>) => boolean): TreeNode<TData> | undefined {\n for (const leaf of this.leaves) {\n if (predicate(leaf)) return leaf\n }\n return undefined\n }\n\n static toGraph(root: TreeNode<BarrelData>): Graph {\n const nodes: Array<{ id: string; label: string }> = []\n const edges: Array<{ from: string; to: string }> = []\n\n root.forEach((node) => {\n nodes.push({\n id: node.data.path,\n label: node.data.name,\n })\n\n for (const child of node.children) {\n edges.push({\n from: node.data.path,\n to: child.data.path,\n })\n }\n })\n\n return { nodes, edges }\n }\n\n static fromFiles(files: Array<KubbFile.File>, rootFolder = ''): TreeNode<BarrelData> | null {\n const normalizePath = (p: string): string => p.replace(/\\\\/g, '/')\n const normalizedRoot = normalizePath(rootFolder)\n const rootPrefix = normalizedRoot.endsWith('/') ? normalizedRoot : `${normalizedRoot}/`\n\n const filteredFiles = files.filter((file) => {\n const filePath = normalizePath(file.path)\n\n return !filePath.endsWith('.json') && (!rootFolder || filePath.startsWith(rootPrefix))\n })\n\n if (filteredFiles.length === 0) {\n return null\n }\n\n const treeNode = new TreeNode<BarrelData>({\n name: rootFolder || '',\n path: rootFolder || '',\n file: undefined,\n })\n\n for (const file of filteredFiles) {\n const relPath = normalizePath(file.path).slice(rootPrefix.length)\n const parts = relPath.split('/')\n\n let current = treeNode\n let currentPath = rootFolder\n\n for (const [index, part] of parts.entries()) {\n const isLast = index === parts.length - 1\n currentPath += (currentPath.endsWith('/') ? '' : '/') + part\n\n let next: TreeNode<BarrelData> | undefined\n for (const child of current.children) {\n if ((child.data as BarrelData).name === part) {\n next = child\n break\n }\n }\n\n if (!next) {\n next = current.addChild({\n name: part,\n path: currentPath,\n file: isLast ? file : undefined,\n })\n }\n\n current = next\n }\n }\n\n return treeNode\n }\n}\n","import type { Plugin, UserPlugin } from './types.ts'\n\nexport function createPlugin<Options = unknown, TAppExtension extends Record<string, any> = {}>(\n plugin: UserPlugin<Options, TAppExtension>,\n): Plugin<Options, TAppExtension> {\n return {\n type: 'plugin',\n ...plugin,\n }\n}\n","/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: not needed */\n\nimport path from 'node:path'\nimport { createFile } from '../createFile.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { getRelativePath } from '../utils/getRelativePath.ts'\nimport { TreeNode } from '../utils/TreeNode.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype Mode = 'all' | 'named' | 'propagate' | false\n\ntype Options = {\n root: string\n mode: Mode\n dryRun?: boolean\n}\n\ntype WriteEntryOptions = {\n root: string\n mode: Mode\n}\n\ntype ExtendOptions = {\n writeEntry(options: WriteEntryOptions): Promise<void>\n}\n\ndeclare global {\n namespace Kubb {\n interface Fabric {\n writeEntry(options: WriteEntryOptions): Promise<void>\n }\n }\n}\n\ntype GetBarrelFilesOptions = {\n files: KubbFile.File[]\n root: string\n mode: Mode\n}\n\nexport function getBarrelFiles({ files, root, mode }: GetBarrelFilesOptions): Array<KubbFile.File> {\n // Do not generate when propagating or disabled\n if (mode === 'propagate' || mode === false) {\n return []\n }\n\n const cachedFiles = new Map<KubbFile.Path, KubbFile.File>()\n const dedupe = new Map<KubbFile.Path, Set<string>>()\n\n const treeNode = TreeNode.fromFiles(files, root)\n\n if (!treeNode) {\n return []\n }\n\n treeNode.forEach((node) => {\n // Only create a barrel for directory-like nodes that have a parent with a path\n if (!node?.children || !node.parent?.data.path) {\n return\n }\n\n const parentPath = node.parent.data.path as KubbFile.Path\n const barrelPath = path.join(parentPath, 'index.ts') as KubbFile.Path\n\n let barrelFile = cachedFiles.get(barrelPath)\n if (!barrelFile) {\n barrelFile = createFile({\n path: barrelPath,\n baseName: 'index.ts',\n exports: [],\n sources: [],\n })\n cachedFiles.set(barrelPath, barrelFile)\n dedupe.set(barrelPath, new Set<string>())\n }\n\n const seen = dedupe.get(barrelPath)!\n\n // Collect all leaves under the current directory node\n node.leaves.forEach((leaf) => {\n const file = leaf.data.file\n if (!file) {\n return\n }\n\n const sources = file.sources || []\n sources.forEach((source) => {\n if (!file.path || !source.isIndexable || !source.name) {\n return\n }\n\n const key = `${source.name}|${source.isTypeOnly ? '1' : '0'}`\n if (seen.has(key)) {\n return\n }\n seen.add(key)\n\n // Always compute relative path from the parent directory to the file path\n barrelFile!.exports!.push({\n name: [source.name],\n path: getRelativePath(parentPath, file.path),\n isTypeOnly: source.isTypeOnly,\n })\n\n barrelFile!.sources.push({\n name: source.name,\n isTypeOnly: source.isTypeOnly,\n value: '', // TODO use parser to generate import\n isExportable: mode === 'all' || mode === 'named',\n isIndexable: mode === 'all' || mode === 'named',\n })\n })\n })\n })\n\n const result = [...cachedFiles.values()]\n\n if (mode === 'all') {\n return result.map((file) => ({\n ...file,\n exports: file.exports?.map((e) => ({ ...e, name: undefined })),\n }))\n }\n\n return result\n}\n\nexport const barrelPlugin = createPlugin<Options, ExtendOptions>({\n name: 'barrel',\n install(ctx, options) {\n if (!options) {\n throw new Error('Barrel plugin requires options.root and options.mode')\n }\n\n if (!options.mode) {\n return undefined\n }\n\n ctx.on('write:start', async ({ files }) => {\n const root = options.root\n const barrelFiles = getBarrelFiles({ files, root, mode: options.mode })\n\n await ctx.fileManager.add(...barrelFiles)\n })\n },\n inject(ctx, options) {\n if (!options) {\n throw new Error('Barrel plugin requires options.root and options.mode')\n }\n\n return {\n async writeEntry({ root, mode }) {\n if (!mode || mode === 'propagate') {\n return undefined\n }\n\n const rootPath = path.resolve(root, 'index.ts')\n\n const barrelFiles = ctx.files.filter((file) => {\n return file.sources.some((source) => source.isIndexable)\n })\n\n const entryFile = createFile({\n path: rootPath,\n baseName: 'index.ts',\n exports: barrelFiles\n .flatMap((file) => {\n const containsOnlyTypes = file.sources.every((source) => source.isTypeOnly)\n\n return file.sources\n ?.map((source) => {\n if (!file.path || !source.isIndexable) {\n return undefined\n }\n\n return {\n name: mode === 'all' ? undefined : [source.name],\n path: getRelativePath(rootPath, file.path),\n isTypeOnly: mode === 'all' ? containsOnlyTypes : source.isTypeOnly,\n } as KubbFile.Export\n })\n .filter(Boolean)\n })\n .filter(Boolean),\n sources: [],\n })\n\n await ctx.addFile(entryFile)\n\n await ctx.fileManager.write({\n mode: ctx.config?.options?.mode,\n dryRun: options.dryRun,\n parsers: ctx.installedParsers,\n })\n },\n }\n },\n})\n","import { resolve } from 'node:path'\nimport fs from 'fs-extra'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype WriteOptions = {\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n}\n\ntype Options = {\n dryRun?: boolean\n /**\n * Optional callback that is invoked whenever a file is written by the plugin.\n * Useful for tests to observe write operations without spying on internal functions.\n */\n onBeforeWrite?: (path: string, data: string | undefined) => void | Promise<void>\n clean?: {\n path: string\n }\n}\n\ntype ExtendOptions = {\n write(options?: WriteOptions): Promise<void>\n}\n\nexport async function write(path: string, data: string | undefined, options: { sanity?: boolean } = {}): Promise<string | undefined> {\n if (typeof Bun !== 'undefined') {\n if (!data || data?.trim() === '') {\n return undefined\n }\n\n await Bun.write(resolve(path), data.trim())\n\n if (options?.sanity) {\n const file = Bun.file(resolve(path))\n const savedData = await file.text()\n\n if (savedData?.toString() !== data?.toString()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data\n }\n\n if (!data || data?.trim() === '') {\n return undefined\n }\n\n try {\n const oldContent = await fs.readFile(resolve(path), {\n encoding: 'utf-8',\n })\n if (oldContent?.toString() === data?.toString()) {\n return\n }\n } catch (_err) {\n /* empty */\n }\n\n await fs.outputFile(resolve(path), data.trim(), { encoding: 'utf-8' })\n\n if (options?.sanity) {\n const savedData = await fs.readFile(resolve(path), {\n encoding: 'utf-8',\n })\n\n if (savedData?.toString() !== data?.toString()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data\n}\n\ndeclare global {\n namespace Kubb {\n interface Fabric {\n write(options?: WriteOptions): Promise<void>\n }\n }\n}\n\nexport const fsPlugin = createPlugin<Options, ExtendOptions>({\n name: 'fs',\n install(ctx, options = {}) {\n if (options.clean) {\n fs.removeSync(options.clean.path)\n }\n\n ctx.on('process:progress', async ({ file, source }) => {\n if (options.onBeforeWrite) {\n await options.onBeforeWrite(file.path, source)\n }\n await write(file.path, source, { sanity: false })\n })\n },\n inject(ctx, { dryRun } = {}) {\n return {\n async write(\n options = {\n extension: { '.ts': '.ts' },\n },\n ) {\n await ctx.fileManager.write({\n mode: ctx.config?.options?.mode,\n extension: options.extension,\n dryRun,\n parsers: ctx.installedParsers,\n })\n },\n }\n },\n})\n","import { spawn } from 'node:child_process'\n\nconst spawnBin = (bin: string, args: string[]): Promise<boolean> => {\n return new Promise((resolve) => {\n const process = spawn(bin, args, {\n detached: true,\n shell: false,\n windowsHide: true,\n })\n\n process.on('close', (code) => {\n resolve(!code)\n })\n })\n}\n\ntype Options = {\n app?: string\n}\n\nexport async function open(path: string, options?: Options): Promise<boolean> {\n const app = options?.app\n\n if (process.platform === 'win32') {\n return spawnBin('cmd.exe', ['/c', 'start', app || '', path.replace(/[&^]/g, '^$&')])\n }\n\n if (process.platform === 'linux') {\n return spawnBin(app || 'xdg-open', [path])\n }\n if (process.platform === 'darwin') {\n return spawnBin('open', app ? ['-a', app, path] : [path])\n }\n\n throw new Error(`Unsupported platform, could not open \"${path}\"`)\n}\n","import http from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport path from 'node:path'\nimport handler from 'serve-handler'\nimport { createFile } from '../createFile.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { open } from '../utils/open.ts'\nimport { type Graph, TreeNode } from '../utils/TreeNode.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype Options = {\n root: string\n /**\n * @default false\n */\n open?: boolean\n}\n\ntype GetGraphOptions = {\n files: KubbFile.File[]\n root: string\n}\n\nexport function getGraph({ files, root }: GetGraphOptions): Graph | undefined {\n const treeNode = TreeNode.fromFiles(files, root)\n\n if (!treeNode) {\n return undefined\n }\n\n return TreeNode.toGraph(treeNode)\n}\nconst html = `\n <!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>File Graph</title>\n <script type=\"module\">\n import { Network } from 'https://cdn.jsdelivr.net/npm/vis-network/standalone/esm/vis-network.min.js'\n\n async function main() {\n const res = await fetch('./graph.json')\n const { nodes, edges } = await res.json()\n const container = document.getElementById('graph')\n\n const network = new Network(\n container,\n { nodes, edges },\n {\n layout: { hierarchical: { direction: 'UD', sortMethod: 'directed' } },\n nodes: { shape: 'box', font: { face: 'monospace' } },\n edges: { arrows: 'to' },\n physics: false,\n },\n )\n }\n\n main()\n </script>\n <style>\n html, body, #graph { height: 100%; margin: 0; }\n </style>\n </head>\n <body>\n <div id=\"graph\"></div>\n </body>\n</html>\n`\n\nasync function serve(root: string) {\n const server = http.createServer((req, res) => {\n return handler(req, res, {\n public: root,\n cleanUrls: true,\n })\n })\n\n server.listen(0, async () => {\n const { port } = server.address() as AddressInfo\n console.log(`Running on http://localhost:${port}/graph.html`)\n\n await open(`http://localhost:${port}/graph.html`)\n })\n}\n\nexport const graphPlugin = createPlugin<Options>({\n name: 'graph',\n install(ctx, options) {\n if (!options) {\n throw new Error('Graph plugin requires options.root and options.mode')\n }\n\n ctx.on('write:start', async ({ files }) => {\n const root = options.root\n\n const graph = getGraph({ files, root })\n\n if (!graph) {\n return undefined\n }\n\n const graphFile = createFile({\n baseName: 'graph.json',\n path: path.join(root, 'graph.json'),\n sources: [\n {\n name: 'graph',\n value: JSON.stringify(graph, null, 2),\n },\n ],\n })\n\n const graphHtmlFile = createFile({\n baseName: 'graph.html',\n path: path.join(root, 'graph.html'),\n sources: [\n {\n name: 'graph',\n value: html,\n },\n ],\n })\n\n await ctx.addFile(graphFile, graphHtmlFile)\n\n if (options.open) {\n await serve(root)\n }\n })\n },\n})\n","import { relative } from 'node:path'\nimport process from 'node:process'\nimport { Presets, SingleBar } from 'cli-progress'\nimport { createPlugin } from './createPlugin.ts'\n\nexport const progressPlugin = createPlugin({\n name: 'progress',\n install(ctx) {\n const progressBar = new SingleBar(\n {\n format: '{bar} {percentage}% | {value}/{total} | {message}',\n barCompleteChar: '█',\n barIncompleteChar: '░',\n hideCursor: true,\n clearOnComplete: true,\n },\n Presets.shades_grey,\n )\n\n ctx.on('process:start', async ({ files }) => {\n progressBar.start(files.length, 0, { message: 'Starting...' })\n })\n\n ctx.on('process:progress', async ({ file }) => {\n const message = `Writing ${relative(process.cwd(), file.path)}`\n progressBar.increment(1, { message })\n })\n\n ctx.on('process:end', async ({ files }) => {\n progressBar.update(files.length, { message: 'Done ✅' })\n progressBar.stop()\n })\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugins.cjs","names":["stack: Array<TreeNode<TData>>","result: Array<TreeNode<TData>>","nodes: Array<{ id: string; label: string }>","edges: Array<{ from: string; to: string }>","next: TreeNode<BarrelData> | undefined","path","createFile","getRelativePath","path","fs","path","http","createFile","path","SingleBar","Presets","process"],"sources":["../src/utils/TreeNode.ts","../src/plugins/createPlugin.ts","../src/plugins/barrelPlugin.ts","../src/plugins/fsPlugin.ts","../src/utils/open.ts","../src/plugins/graphPlugin.ts","../src/plugins/progressPlugin.ts"],"sourcesContent":["import type * as KubbFile from '../KubbFile.ts'\n\ntype BarrelData = {\n file?: KubbFile.File\n path: string\n name: string\n}\n\nexport type Graph = {\n nodes: Array<{ id: string; label: string }>\n edges: Array<{ from: string; to: string }>\n}\n\nexport class TreeNode<TData = unknown> {\n data: TData\n parent?: TreeNode<TData>\n children: Array<TreeNode<TData>> = []\n #cachedLeaves?: Array<TreeNode<TData>>\n\n constructor(data: TData, parent?: TreeNode<TData>) {\n this.data = data\n this.parent = parent\n }\n\n addChild(data: TData): TreeNode<TData> {\n const child = new TreeNode(data, this)\n this.children.push(child)\n this.#cachedLeaves = undefined // invalidate cached leaves\n return child\n }\n\n get leaves(): Array<TreeNode<TData>> {\n if (this.#cachedLeaves) return this.#cachedLeaves\n if (this.children.length === 0) return [this]\n\n const stack: Array<TreeNode<TData>> = [...this.children]\n const result: Array<TreeNode<TData>> = []\n\n for (const node of stack) {\n if (node.children.length) {\n for (const child of node.children) stack.push(child)\n } else {\n result.push(node)\n }\n }\n\n this.#cachedLeaves = result\n return result\n }\n\n forEach(callback: (node: TreeNode<TData>) => void): this {\n const stack: Array<TreeNode<TData>> = [this]\n\n for (const node of stack) {\n callback(node)\n if (node.children.length) {\n for (const child of node.children) stack.push(child)\n }\n }\n return this\n }\n\n findDeep(predicate: (node: TreeNode<TData>) => boolean): TreeNode<TData> | undefined {\n for (const leaf of this.leaves) {\n if (predicate(leaf)) return leaf\n }\n return undefined\n }\n\n static toGraph(root: TreeNode<BarrelData>): Graph {\n const nodes: Array<{ id: string; label: string }> = []\n const edges: Array<{ from: string; to: string }> = []\n\n root.forEach((node) => {\n nodes.push({\n id: node.data.path,\n label: node.data.name,\n })\n\n for (const child of node.children) {\n edges.push({\n from: node.data.path,\n to: child.data.path,\n })\n }\n })\n\n return { nodes, edges }\n }\n\n static fromFiles(files: Array<KubbFile.File>, rootFolder = ''): TreeNode<BarrelData> | null {\n const normalizePath = (p: string): string => p.replace(/\\\\/g, '/')\n const normalizedRoot = normalizePath(rootFolder)\n const rootPrefix = normalizedRoot.endsWith('/') ? normalizedRoot : `${normalizedRoot}/`\n\n const filteredFiles = files.filter((file) => {\n const filePath = normalizePath(file.path)\n\n return !filePath.endsWith('.json') && (!rootFolder || filePath.startsWith(rootPrefix))\n })\n\n if (filteredFiles.length === 0) {\n return null\n }\n\n const treeNode = new TreeNode<BarrelData>({\n name: rootFolder || '',\n path: rootFolder || '',\n file: undefined,\n })\n\n for (const file of filteredFiles) {\n const relPath = normalizePath(file.path).slice(rootPrefix.length)\n const parts = relPath.split('/')\n\n let current = treeNode\n let currentPath = rootFolder\n\n for (const [index, part] of parts.entries()) {\n const isLast = index === parts.length - 1\n currentPath += (currentPath.endsWith('/') ? '' : '/') + part\n\n let next: TreeNode<BarrelData> | undefined\n for (const child of current.children) {\n if ((child.data as BarrelData).name === part) {\n next = child\n break\n }\n }\n\n if (!next) {\n next = current.addChild({\n name: part,\n path: currentPath,\n file: isLast ? file : undefined,\n })\n }\n\n current = next\n }\n }\n\n return treeNode\n }\n}\n","import type { Plugin, UserPlugin } from './types.ts'\n\nexport function createPlugin<Options = unknown, TAppExtension extends Record<string, any> = {}>(\n plugin: UserPlugin<Options, TAppExtension>,\n): Plugin<Options, TAppExtension> {\n return {\n type: 'plugin',\n ...plugin,\n }\n}\n","/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: not needed */\n\nimport path from 'node:path'\nimport { createFile } from '../createFile.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { getRelativePath } from '../utils/getRelativePath.ts'\nimport { TreeNode } from '../utils/TreeNode.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype Mode = 'all' | 'named' | 'propagate' | false\n\ntype Options = {\n root: string\n mode: Mode\n dryRun?: boolean\n}\n\ntype WriteEntryOptions = {\n root: string\n mode: Mode\n}\n\ntype ExtendOptions = {\n /**\n * `fabric.writeEntry` should be called before `fabric.write`\n */\n writeEntry(options: WriteEntryOptions): Promise<void>\n}\n\ndeclare global {\n namespace Kubb {\n interface Fabric {\n /**\n * `fabric.writeEntry` should be called before `fabric.write`\n */\n writeEntry(options: WriteEntryOptions): Promise<void>\n }\n }\n}\n\ntype GetBarrelFilesOptions = {\n files: KubbFile.File[]\n root: string\n mode: Mode\n}\n\nexport function getBarrelFiles({ files, root, mode }: GetBarrelFilesOptions): Array<KubbFile.File> {\n // Do not generate when propagating or disabled\n if (mode === 'propagate' || mode === false) {\n return []\n }\n\n const cachedFiles = new Map<KubbFile.Path, KubbFile.File>()\n const dedupe = new Map<KubbFile.Path, Set<string>>()\n\n const treeNode = TreeNode.fromFiles(files, root)\n\n if (!treeNode) {\n return []\n }\n\n treeNode.forEach((node) => {\n // Only create a barrel for directory-like nodes that have a parent with a path\n if (!node?.children || !node.parent?.data.path) {\n return\n }\n\n const parentPath = node.parent.data.path as KubbFile.Path\n const barrelPath = path.join(parentPath, 'index.ts') as KubbFile.Path\n\n let barrelFile = cachedFiles.get(barrelPath)\n if (!barrelFile) {\n barrelFile = createFile({\n path: barrelPath,\n baseName: 'index.ts',\n exports: [],\n sources: [],\n })\n cachedFiles.set(barrelPath, barrelFile)\n dedupe.set(barrelPath, new Set<string>())\n }\n\n const seen = dedupe.get(barrelPath)!\n\n // Collect all leaves under the current directory node\n node.leaves.forEach((leaf) => {\n const file = leaf.data.file\n if (!file) {\n return\n }\n\n const sources = file.sources || []\n sources.forEach((source) => {\n if (!file.path || !source.isIndexable || !source.name) {\n return\n }\n\n const key = `${source.name}|${source.isTypeOnly ? '1' : '0'}`\n if (seen.has(key)) {\n return\n }\n seen.add(key)\n\n // Always compute relative path from the parent directory to the file path\n barrelFile!.exports!.push({\n name: [source.name],\n path: getRelativePath(parentPath, file.path),\n isTypeOnly: source.isTypeOnly,\n })\n\n barrelFile!.sources.push({\n name: source.name,\n isTypeOnly: source.isTypeOnly,\n value: '', // TODO use parser to generate import\n isExportable: mode === 'all' || mode === 'named',\n isIndexable: mode === 'all' || mode === 'named',\n })\n })\n })\n })\n\n const result = [...cachedFiles.values()]\n\n if (mode === 'all') {\n return result.map((file) => ({\n ...file,\n exports: file.exports?.map((e) => ({ ...e, name: undefined })),\n }))\n }\n\n return result\n}\n\nexport const barrelPlugin = createPlugin<Options, ExtendOptions>({\n name: 'barrel',\n install(ctx, options) {\n if (!options) {\n throw new Error('Barrel plugin requires options.root and options.mode')\n }\n\n if (!options.mode) {\n return undefined\n }\n\n ctx.on('write:start', async ({ files }) => {\n const root = options.root\n const barrelFiles = getBarrelFiles({ files, root, mode: options.mode })\n\n await ctx.fileManager.add(...barrelFiles)\n })\n },\n inject(ctx, options) {\n if (!options) {\n throw new Error('Barrel plugin requires options.root and options.mode')\n }\n\n return {\n async writeEntry({ root, mode }) {\n if (!mode || mode === 'propagate') {\n return undefined\n }\n\n const rootPath = path.resolve(root, 'index.ts')\n\n const barrelFiles = ctx.files.filter((file) => {\n return file.sources.some((source) => source.isIndexable)\n })\n\n const entryFile = createFile({\n path: rootPath,\n baseName: 'index.ts',\n exports: barrelFiles\n .flatMap((file) => {\n const containsOnlyTypes = file.sources.every((source) => source.isTypeOnly)\n\n return file.sources\n ?.map((source) => {\n if (!file.path || !source.isIndexable) {\n return undefined\n }\n\n return {\n name: mode === 'all' ? undefined : [source.name],\n path: getRelativePath(rootPath, file.path),\n isTypeOnly: mode === 'all' ? containsOnlyTypes : source.isTypeOnly,\n } as KubbFile.Export\n })\n .filter(Boolean)\n })\n .filter(Boolean),\n sources: [],\n })\n\n await ctx.addFile(entryFile)\n\n await ctx.fileManager.write({\n mode: ctx.config.mode,\n dryRun: options.dryRun,\n parsers: ctx.installedParsers,\n })\n },\n }\n },\n})\n","import { resolve } from 'node:path'\nimport fs from 'fs-extra'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype WriteOptions = {\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n}\n\ntype Options = {\n dryRun?: boolean\n /**\n * Optional callback that is invoked whenever a file is written by the plugin.\n * Useful for tests to observe write operations without spying on internal functions.\n */\n onBeforeWrite?: (path: string, data: string | undefined) => void | Promise<void>\n clean?: {\n path: string\n }\n}\n\ntype ExtendOptions = {\n write(options?: WriteOptions): Promise<void>\n}\n\nexport async function write(path: string, data: string | undefined, options: { sanity?: boolean } = {}): Promise<string | undefined> {\n if (typeof Bun !== 'undefined') {\n if (!data || data?.trim() === '') {\n return undefined\n }\n\n await Bun.write(resolve(path), data.trim())\n\n if (options?.sanity) {\n const file = Bun.file(resolve(path))\n const savedData = await file.text()\n\n if (savedData?.toString() !== data?.toString()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data\n }\n\n if (!data || data?.trim() === '') {\n return undefined\n }\n\n try {\n const oldContent = await fs.readFile(resolve(path), {\n encoding: 'utf-8',\n })\n if (oldContent?.toString() === data?.toString()) {\n return\n }\n } catch (_err) {\n /* empty */\n }\n\n await fs.outputFile(resolve(path), data.trim(), { encoding: 'utf-8' })\n\n if (options?.sanity) {\n const savedData = await fs.readFile(resolve(path), {\n encoding: 'utf-8',\n })\n\n if (savedData?.toString() !== data?.toString()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data\n}\n\ndeclare global {\n namespace Kubb {\n interface Fabric {\n write(options?: WriteOptions): Promise<void>\n }\n }\n}\n\nexport const fsPlugin = createPlugin<Options, ExtendOptions>({\n name: 'fs',\n install(ctx, options = {}) {\n if (options.clean) {\n fs.removeSync(options.clean.path)\n }\n\n ctx.on('process:progress', async ({ file, source }) => {\n if (options.onBeforeWrite) {\n await options.onBeforeWrite(file.path, source)\n }\n await write(file.path, source, { sanity: false })\n })\n },\n inject(ctx, { dryRun } = {}) {\n return {\n async write(\n options = {\n extension: { '.ts': '.ts' },\n },\n ) {\n await ctx.fileManager.write({\n mode: ctx.config.mode,\n extension: options.extension,\n dryRun,\n parsers: ctx.installedParsers,\n })\n },\n }\n },\n})\n","import { spawn } from 'node:child_process'\n\nconst spawnBin = (bin: string, args: string[]): Promise<boolean> => {\n return new Promise((resolve) => {\n const process = spawn(bin, args, {\n detached: true,\n shell: false,\n windowsHide: true,\n })\n\n process.on('close', (code) => {\n resolve(!code)\n })\n })\n}\n\ntype Options = {\n app?: string\n}\n\nexport async function open(path: string, options?: Options): Promise<boolean> {\n const app = options?.app\n\n if (process.platform === 'win32') {\n return spawnBin('cmd.exe', ['/c', 'start', app || '', path.replace(/[&^]/g, '^$&')])\n }\n\n if (process.platform === 'linux') {\n return spawnBin(app || 'xdg-open', [path])\n }\n if (process.platform === 'darwin') {\n return spawnBin('open', app ? ['-a', app, path] : [path])\n }\n\n throw new Error(`Unsupported platform, could not open \"${path}\"`)\n}\n","import http from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport path from 'node:path'\nimport handler from 'serve-handler'\nimport { createFile } from '../createFile.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { open } from '../utils/open.ts'\nimport { type Graph, TreeNode } from '../utils/TreeNode.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype Options = {\n root: string\n /**\n * @default false\n */\n open?: boolean\n}\n\ntype GetGraphOptions = {\n files: KubbFile.File[]\n root: string\n}\n\nexport function getGraph({ files, root }: GetGraphOptions): Graph | undefined {\n const treeNode = TreeNode.fromFiles(files, root)\n\n if (!treeNode) {\n return undefined\n }\n\n return TreeNode.toGraph(treeNode)\n}\nconst html = `\n <!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>File Graph</title>\n <script type=\"module\">\n import { Network } from 'https://cdn.jsdelivr.net/npm/vis-network/standalone/esm/vis-network.min.js'\n\n async function main() {\n const res = await fetch('./graph.json')\n const { nodes, edges } = await res.json()\n const container = document.getElementById('graph')\n\n const network = new Network(\n container,\n { nodes, edges },\n {\n layout: { hierarchical: { direction: 'UD', sortMethod: 'directed' } },\n nodes: { shape: 'box', font: { face: 'monospace' } },\n edges: { arrows: 'to' },\n physics: false,\n },\n )\n }\n\n main()\n </script>\n <style>\n html, body, #graph { height: 100%; margin: 0; }\n </style>\n </head>\n <body>\n <div id=\"graph\"></div>\n </body>\n</html>\n`\n\nasync function serve(root: string) {\n const server = http.createServer((req, res) => {\n return handler(req, res, {\n public: root,\n cleanUrls: true,\n })\n })\n\n server.listen(0, async () => {\n const { port } = server.address() as AddressInfo\n console.log(`Running on http://localhost:${port}/graph.html`)\n\n await open(`http://localhost:${port}/graph.html`)\n })\n}\n\nexport const graphPlugin = createPlugin<Options>({\n name: 'graph',\n install(ctx, options) {\n if (!options) {\n throw new Error('Graph plugin requires options.root and options.mode')\n }\n\n ctx.on('write:start', async ({ files }) => {\n const root = options.root\n\n const graph = getGraph({ files, root })\n\n if (!graph) {\n return undefined\n }\n\n const graphFile = createFile({\n baseName: 'graph.json',\n path: path.join(root, 'graph.json'),\n sources: [\n {\n name: 'graph',\n value: JSON.stringify(graph, null, 2),\n },\n ],\n })\n\n const graphHtmlFile = createFile({\n baseName: 'graph.html',\n path: path.join(root, 'graph.html'),\n sources: [\n {\n name: 'graph',\n value: html,\n },\n ],\n })\n\n await ctx.addFile(graphFile, graphHtmlFile)\n\n if (options.open) {\n await serve(root)\n }\n })\n },\n})\n","import { relative } from 'node:path'\nimport process from 'node:process'\nimport { Presets, SingleBar } from 'cli-progress'\nimport { createPlugin } from './createPlugin.ts'\n\nexport const progressPlugin = createPlugin({\n name: 'progress',\n install(ctx) {\n const progressBar = new SingleBar(\n {\n format: '{bar} {percentage}% | {value}/{total} | {message}',\n barCompleteChar: '█',\n barIncompleteChar: '░',\n hideCursor: true,\n clearOnComplete: true,\n },\n Presets.shades_grey,\n )\n\n ctx.on('process:start', async ({ files }) => {\n progressBar.start(files.length, 0, { message: 'Starting...' })\n })\n\n ctx.on('process:progress', async ({ file }) => {\n const message = `Writing ${relative(process.cwd(), file.path)}`\n progressBar.increment(1, { message })\n })\n\n ctx.on('process:end', async ({ files }) => {\n progressBar.update(files.length, { message: 'Done ✅' })\n progressBar.stop()\n })\n },\n})\n"],"mappings":"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"}
|
package/dist/plugins.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as Extname, o as Plugin, s as UserPlugin } from "./Fabric-
|
|
1
|
+
import { f as Extname, o as Plugin, s as UserPlugin } from "./Fabric-BezqNTQ9.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/plugins/barrelPlugin.d.ts
|
|
4
4
|
type Mode = 'all' | 'named' | 'propagate' | false;
|
|
@@ -12,11 +12,17 @@ type WriteEntryOptions = {
|
|
|
12
12
|
mode: Mode;
|
|
13
13
|
};
|
|
14
14
|
type ExtendOptions$1 = {
|
|
15
|
+
/**
|
|
16
|
+
* `fabric.writeEntry` should be called before `fabric.write`
|
|
17
|
+
*/
|
|
15
18
|
writeEntry(options: WriteEntryOptions): Promise<void>;
|
|
16
19
|
};
|
|
17
20
|
declare global {
|
|
18
21
|
namespace Kubb {
|
|
19
22
|
interface Fabric {
|
|
23
|
+
/**
|
|
24
|
+
* `fabric.writeEntry` should be called before `fabric.write`
|
|
25
|
+
*/
|
|
20
26
|
writeEntry(options: WriteEntryOptions): Promise<void>;
|
|
21
27
|
}
|
|
22
28
|
}
|
package/dist/plugins.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as Extname, o as Plugin, s as UserPlugin } from "./Fabric-
|
|
1
|
+
import { f as Extname, o as Plugin, s as UserPlugin } from "./Fabric-CVe8cc8b.js";
|
|
2
2
|
|
|
3
3
|
//#region src/plugins/barrelPlugin.d.ts
|
|
4
4
|
type Mode = 'all' | 'named' | 'propagate' | false;
|
|
@@ -12,11 +12,17 @@ type WriteEntryOptions = {
|
|
|
12
12
|
mode: Mode;
|
|
13
13
|
};
|
|
14
14
|
type ExtendOptions$1 = {
|
|
15
|
+
/**
|
|
16
|
+
* `fabric.writeEntry` should be called before `fabric.write`
|
|
17
|
+
*/
|
|
15
18
|
writeEntry(options: WriteEntryOptions): Promise<void>;
|
|
16
19
|
};
|
|
17
20
|
declare global {
|
|
18
21
|
namespace Kubb {
|
|
19
22
|
interface Fabric {
|
|
23
|
+
/**
|
|
24
|
+
* `fabric.writeEntry` should be called before `fabric.write`
|
|
25
|
+
*/
|
|
20
26
|
writeEntry(options: WriteEntryOptions): Promise<void>;
|
|
21
27
|
}
|
|
22
28
|
}
|
package/dist/plugins.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _classPrivateFieldGet2, s as createFile, t as _defineProperty } from "./defineProperty-DcP1vZ2K.js";
|
|
2
2
|
import "./trimExtName-CeOVQVbu.js";
|
|
3
3
|
import { t as getRelativePath } from "./getRelativePath-CERJmYkp.js";
|
|
4
4
|
import path, { relative, resolve } from "node:path";
|
|
@@ -191,7 +191,6 @@ const barrelPlugin = createPlugin({
|
|
|
191
191
|
inject(ctx, options) {
|
|
192
192
|
if (!options) throw new Error("Barrel plugin requires options.root and options.mode");
|
|
193
193
|
return { async writeEntry({ root, mode }) {
|
|
194
|
-
var _ctx$config;
|
|
195
194
|
if (!mode || mode === "propagate") return;
|
|
196
195
|
const rootPath = path.resolve(root, "index.ts");
|
|
197
196
|
const entryFile = createFile({
|
|
@@ -215,7 +214,7 @@ const barrelPlugin = createPlugin({
|
|
|
215
214
|
});
|
|
216
215
|
await ctx.addFile(entryFile);
|
|
217
216
|
await ctx.fileManager.write({
|
|
218
|
-
mode:
|
|
217
|
+
mode: ctx.config.mode,
|
|
219
218
|
dryRun: options.dryRun,
|
|
220
219
|
parsers: ctx.installedParsers
|
|
221
220
|
});
|
|
@@ -260,9 +259,8 @@ const fsPlugin = createPlugin({
|
|
|
260
259
|
},
|
|
261
260
|
inject(ctx, { dryRun } = {}) {
|
|
262
261
|
return { async write(options = { extension: { ".ts": ".ts" } }) {
|
|
263
|
-
var _ctx$config;
|
|
264
262
|
await ctx.fileManager.write({
|
|
265
|
-
mode:
|
|
263
|
+
mode: ctx.config.mode,
|
|
266
264
|
extension: options.extension,
|
|
267
265
|
dryRun,
|
|
268
266
|
parsers: ctx.installedParsers
|
package/dist/plugins.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.js","names":["stack: Array<TreeNode<TData>>","result: Array<TreeNode<TData>>","nodes: Array<{ id: string; label: string }>","edges: Array<{ from: string; to: string }>","next: TreeNode<BarrelData> | undefined","path","path","process"],"sources":["../src/utils/TreeNode.ts","../src/plugins/createPlugin.ts","../src/plugins/barrelPlugin.ts","../src/plugins/fsPlugin.ts","../src/utils/open.ts","../src/plugins/graphPlugin.ts","../src/plugins/progressPlugin.ts"],"sourcesContent":["import type * as KubbFile from '../KubbFile.ts'\n\ntype BarrelData = {\n file?: KubbFile.File\n path: string\n name: string\n}\n\nexport type Graph = {\n nodes: Array<{ id: string; label: string }>\n edges: Array<{ from: string; to: string }>\n}\n\nexport class TreeNode<TData = unknown> {\n data: TData\n parent?: TreeNode<TData>\n children: Array<TreeNode<TData>> = []\n #cachedLeaves?: Array<TreeNode<TData>>\n\n constructor(data: TData, parent?: TreeNode<TData>) {\n this.data = data\n this.parent = parent\n }\n\n addChild(data: TData): TreeNode<TData> {\n const child = new TreeNode(data, this)\n this.children.push(child)\n this.#cachedLeaves = undefined // invalidate cached leaves\n return child\n }\n\n get leaves(): Array<TreeNode<TData>> {\n if (this.#cachedLeaves) return this.#cachedLeaves\n if (this.children.length === 0) return [this]\n\n const stack: Array<TreeNode<TData>> = [...this.children]\n const result: Array<TreeNode<TData>> = []\n\n for (const node of stack) {\n if (node.children.length) {\n for (const child of node.children) stack.push(child)\n } else {\n result.push(node)\n }\n }\n\n this.#cachedLeaves = result\n return result\n }\n\n forEach(callback: (node: TreeNode<TData>) => void): this {\n const stack: Array<TreeNode<TData>> = [this]\n\n for (const node of stack) {\n callback(node)\n if (node.children.length) {\n for (const child of node.children) stack.push(child)\n }\n }\n return this\n }\n\n findDeep(predicate: (node: TreeNode<TData>) => boolean): TreeNode<TData> | undefined {\n for (const leaf of this.leaves) {\n if (predicate(leaf)) return leaf\n }\n return undefined\n }\n\n static toGraph(root: TreeNode<BarrelData>): Graph {\n const nodes: Array<{ id: string; label: string }> = []\n const edges: Array<{ from: string; to: string }> = []\n\n root.forEach((node) => {\n nodes.push({\n id: node.data.path,\n label: node.data.name,\n })\n\n for (const child of node.children) {\n edges.push({\n from: node.data.path,\n to: child.data.path,\n })\n }\n })\n\n return { nodes, edges }\n }\n\n static fromFiles(files: Array<KubbFile.File>, rootFolder = ''): TreeNode<BarrelData> | null {\n const normalizePath = (p: string): string => p.replace(/\\\\/g, '/')\n const normalizedRoot = normalizePath(rootFolder)\n const rootPrefix = normalizedRoot.endsWith('/') ? normalizedRoot : `${normalizedRoot}/`\n\n const filteredFiles = files.filter((file) => {\n const filePath = normalizePath(file.path)\n\n return !filePath.endsWith('.json') && (!rootFolder || filePath.startsWith(rootPrefix))\n })\n\n if (filteredFiles.length === 0) {\n return null\n }\n\n const treeNode = new TreeNode<BarrelData>({\n name: rootFolder || '',\n path: rootFolder || '',\n file: undefined,\n })\n\n for (const file of filteredFiles) {\n const relPath = normalizePath(file.path).slice(rootPrefix.length)\n const parts = relPath.split('/')\n\n let current = treeNode\n let currentPath = rootFolder\n\n for (const [index, part] of parts.entries()) {\n const isLast = index === parts.length - 1\n currentPath += (currentPath.endsWith('/') ? '' : '/') + part\n\n let next: TreeNode<BarrelData> | undefined\n for (const child of current.children) {\n if ((child.data as BarrelData).name === part) {\n next = child\n break\n }\n }\n\n if (!next) {\n next = current.addChild({\n name: part,\n path: currentPath,\n file: isLast ? file : undefined,\n })\n }\n\n current = next\n }\n }\n\n return treeNode\n }\n}\n","import type { Plugin, UserPlugin } from './types.ts'\n\nexport function createPlugin<Options = unknown, TAppExtension extends Record<string, any> = {}>(\n plugin: UserPlugin<Options, TAppExtension>,\n): Plugin<Options, TAppExtension> {\n return {\n type: 'plugin',\n ...plugin,\n }\n}\n","/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: not needed */\n\nimport path from 'node:path'\nimport { createFile } from '../createFile.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { getRelativePath } from '../utils/getRelativePath.ts'\nimport { TreeNode } from '../utils/TreeNode.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype Mode = 'all' | 'named' | 'propagate' | false\n\ntype Options = {\n root: string\n mode: Mode\n dryRun?: boolean\n}\n\ntype WriteEntryOptions = {\n root: string\n mode: Mode\n}\n\ntype ExtendOptions = {\n writeEntry(options: WriteEntryOptions): Promise<void>\n}\n\ndeclare global {\n namespace Kubb {\n interface Fabric {\n writeEntry(options: WriteEntryOptions): Promise<void>\n }\n }\n}\n\ntype GetBarrelFilesOptions = {\n files: KubbFile.File[]\n root: string\n mode: Mode\n}\n\nexport function getBarrelFiles({ files, root, mode }: GetBarrelFilesOptions): Array<KubbFile.File> {\n // Do not generate when propagating or disabled\n if (mode === 'propagate' || mode === false) {\n return []\n }\n\n const cachedFiles = new Map<KubbFile.Path, KubbFile.File>()\n const dedupe = new Map<KubbFile.Path, Set<string>>()\n\n const treeNode = TreeNode.fromFiles(files, root)\n\n if (!treeNode) {\n return []\n }\n\n treeNode.forEach((node) => {\n // Only create a barrel for directory-like nodes that have a parent with a path\n if (!node?.children || !node.parent?.data.path) {\n return\n }\n\n const parentPath = node.parent.data.path as KubbFile.Path\n const barrelPath = path.join(parentPath, 'index.ts') as KubbFile.Path\n\n let barrelFile = cachedFiles.get(barrelPath)\n if (!barrelFile) {\n barrelFile = createFile({\n path: barrelPath,\n baseName: 'index.ts',\n exports: [],\n sources: [],\n })\n cachedFiles.set(barrelPath, barrelFile)\n dedupe.set(barrelPath, new Set<string>())\n }\n\n const seen = dedupe.get(barrelPath)!\n\n // Collect all leaves under the current directory node\n node.leaves.forEach((leaf) => {\n const file = leaf.data.file\n if (!file) {\n return\n }\n\n const sources = file.sources || []\n sources.forEach((source) => {\n if (!file.path || !source.isIndexable || !source.name) {\n return\n }\n\n const key = `${source.name}|${source.isTypeOnly ? '1' : '0'}`\n if (seen.has(key)) {\n return\n }\n seen.add(key)\n\n // Always compute relative path from the parent directory to the file path\n barrelFile!.exports!.push({\n name: [source.name],\n path: getRelativePath(parentPath, file.path),\n isTypeOnly: source.isTypeOnly,\n })\n\n barrelFile!.sources.push({\n name: source.name,\n isTypeOnly: source.isTypeOnly,\n value: '', // TODO use parser to generate import\n isExportable: mode === 'all' || mode === 'named',\n isIndexable: mode === 'all' || mode === 'named',\n })\n })\n })\n })\n\n const result = [...cachedFiles.values()]\n\n if (mode === 'all') {\n return result.map((file) => ({\n ...file,\n exports: file.exports?.map((e) => ({ ...e, name: undefined })),\n }))\n }\n\n return result\n}\n\nexport const barrelPlugin = createPlugin<Options, ExtendOptions>({\n name: 'barrel',\n install(ctx, options) {\n if (!options) {\n throw new Error('Barrel plugin requires options.root and options.mode')\n }\n\n if (!options.mode) {\n return undefined\n }\n\n ctx.on('write:start', async ({ files }) => {\n const root = options.root\n const barrelFiles = getBarrelFiles({ files, root, mode: options.mode })\n\n await ctx.fileManager.add(...barrelFiles)\n })\n },\n inject(ctx, options) {\n if (!options) {\n throw new Error('Barrel plugin requires options.root and options.mode')\n }\n\n return {\n async writeEntry({ root, mode }) {\n if (!mode || mode === 'propagate') {\n return undefined\n }\n\n const rootPath = path.resolve(root, 'index.ts')\n\n const barrelFiles = ctx.files.filter((file) => {\n return file.sources.some((source) => source.isIndexable)\n })\n\n const entryFile = createFile({\n path: rootPath,\n baseName: 'index.ts',\n exports: barrelFiles\n .flatMap((file) => {\n const containsOnlyTypes = file.sources.every((source) => source.isTypeOnly)\n\n return file.sources\n ?.map((source) => {\n if (!file.path || !source.isIndexable) {\n return undefined\n }\n\n return {\n name: mode === 'all' ? undefined : [source.name],\n path: getRelativePath(rootPath, file.path),\n isTypeOnly: mode === 'all' ? containsOnlyTypes : source.isTypeOnly,\n } as KubbFile.Export\n })\n .filter(Boolean)\n })\n .filter(Boolean),\n sources: [],\n })\n\n await ctx.addFile(entryFile)\n\n await ctx.fileManager.write({\n mode: ctx.config?.options?.mode,\n dryRun: options.dryRun,\n parsers: ctx.installedParsers,\n })\n },\n }\n },\n})\n","import { resolve } from 'node:path'\nimport fs from 'fs-extra'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype WriteOptions = {\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n}\n\ntype Options = {\n dryRun?: boolean\n /**\n * Optional callback that is invoked whenever a file is written by the plugin.\n * Useful for tests to observe write operations without spying on internal functions.\n */\n onBeforeWrite?: (path: string, data: string | undefined) => void | Promise<void>\n clean?: {\n path: string\n }\n}\n\ntype ExtendOptions = {\n write(options?: WriteOptions): Promise<void>\n}\n\nexport async function write(path: string, data: string | undefined, options: { sanity?: boolean } = {}): Promise<string | undefined> {\n if (typeof Bun !== 'undefined') {\n if (!data || data?.trim() === '') {\n return undefined\n }\n\n await Bun.write(resolve(path), data.trim())\n\n if (options?.sanity) {\n const file = Bun.file(resolve(path))\n const savedData = await file.text()\n\n if (savedData?.toString() !== data?.toString()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data\n }\n\n if (!data || data?.trim() === '') {\n return undefined\n }\n\n try {\n const oldContent = await fs.readFile(resolve(path), {\n encoding: 'utf-8',\n })\n if (oldContent?.toString() === data?.toString()) {\n return\n }\n } catch (_err) {\n /* empty */\n }\n\n await fs.outputFile(resolve(path), data.trim(), { encoding: 'utf-8' })\n\n if (options?.sanity) {\n const savedData = await fs.readFile(resolve(path), {\n encoding: 'utf-8',\n })\n\n if (savedData?.toString() !== data?.toString()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data\n}\n\ndeclare global {\n namespace Kubb {\n interface Fabric {\n write(options?: WriteOptions): Promise<void>\n }\n }\n}\n\nexport const fsPlugin = createPlugin<Options, ExtendOptions>({\n name: 'fs',\n install(ctx, options = {}) {\n if (options.clean) {\n fs.removeSync(options.clean.path)\n }\n\n ctx.on('process:progress', async ({ file, source }) => {\n if (options.onBeforeWrite) {\n await options.onBeforeWrite(file.path, source)\n }\n await write(file.path, source, { sanity: false })\n })\n },\n inject(ctx, { dryRun } = {}) {\n return {\n async write(\n options = {\n extension: { '.ts': '.ts' },\n },\n ) {\n await ctx.fileManager.write({\n mode: ctx.config?.options?.mode,\n extension: options.extension,\n dryRun,\n parsers: ctx.installedParsers,\n })\n },\n }\n },\n})\n","import { spawn } from 'node:child_process'\n\nconst spawnBin = (bin: string, args: string[]): Promise<boolean> => {\n return new Promise((resolve) => {\n const process = spawn(bin, args, {\n detached: true,\n shell: false,\n windowsHide: true,\n })\n\n process.on('close', (code) => {\n resolve(!code)\n })\n })\n}\n\ntype Options = {\n app?: string\n}\n\nexport async function open(path: string, options?: Options): Promise<boolean> {\n const app = options?.app\n\n if (process.platform === 'win32') {\n return spawnBin('cmd.exe', ['/c', 'start', app || '', path.replace(/[&^]/g, '^$&')])\n }\n\n if (process.platform === 'linux') {\n return spawnBin(app || 'xdg-open', [path])\n }\n if (process.platform === 'darwin') {\n return spawnBin('open', app ? ['-a', app, path] : [path])\n }\n\n throw new Error(`Unsupported platform, could not open \"${path}\"`)\n}\n","import http from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport path from 'node:path'\nimport handler from 'serve-handler'\nimport { createFile } from '../createFile.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { open } from '../utils/open.ts'\nimport { type Graph, TreeNode } from '../utils/TreeNode.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype Options = {\n root: string\n /**\n * @default false\n */\n open?: boolean\n}\n\ntype GetGraphOptions = {\n files: KubbFile.File[]\n root: string\n}\n\nexport function getGraph({ files, root }: GetGraphOptions): Graph | undefined {\n const treeNode = TreeNode.fromFiles(files, root)\n\n if (!treeNode) {\n return undefined\n }\n\n return TreeNode.toGraph(treeNode)\n}\nconst html = `\n <!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>File Graph</title>\n <script type=\"module\">\n import { Network } from 'https://cdn.jsdelivr.net/npm/vis-network/standalone/esm/vis-network.min.js'\n\n async function main() {\n const res = await fetch('./graph.json')\n const { nodes, edges } = await res.json()\n const container = document.getElementById('graph')\n\n const network = new Network(\n container,\n { nodes, edges },\n {\n layout: { hierarchical: { direction: 'UD', sortMethod: 'directed' } },\n nodes: { shape: 'box', font: { face: 'monospace' } },\n edges: { arrows: 'to' },\n physics: false,\n },\n )\n }\n\n main()\n </script>\n <style>\n html, body, #graph { height: 100%; margin: 0; }\n </style>\n </head>\n <body>\n <div id=\"graph\"></div>\n </body>\n</html>\n`\n\nasync function serve(root: string) {\n const server = http.createServer((req, res) => {\n return handler(req, res, {\n public: root,\n cleanUrls: true,\n })\n })\n\n server.listen(0, async () => {\n const { port } = server.address() as AddressInfo\n console.log(`Running on http://localhost:${port}/graph.html`)\n\n await open(`http://localhost:${port}/graph.html`)\n })\n}\n\nexport const graphPlugin = createPlugin<Options>({\n name: 'graph',\n install(ctx, options) {\n if (!options) {\n throw new Error('Graph plugin requires options.root and options.mode')\n }\n\n ctx.on('write:start', async ({ files }) => {\n const root = options.root\n\n const graph = getGraph({ files, root })\n\n if (!graph) {\n return undefined\n }\n\n const graphFile = createFile({\n baseName: 'graph.json',\n path: path.join(root, 'graph.json'),\n sources: [\n {\n name: 'graph',\n value: JSON.stringify(graph, null, 2),\n },\n ],\n })\n\n const graphHtmlFile = createFile({\n baseName: 'graph.html',\n path: path.join(root, 'graph.html'),\n sources: [\n {\n name: 'graph',\n value: html,\n },\n ],\n })\n\n await ctx.addFile(graphFile, graphHtmlFile)\n\n if (options.open) {\n await serve(root)\n }\n })\n },\n})\n","import { relative } from 'node:path'\nimport process from 'node:process'\nimport { Presets, SingleBar } from 'cli-progress'\nimport { createPlugin } from './createPlugin.ts'\n\nexport const progressPlugin = createPlugin({\n name: 'progress',\n install(ctx) {\n const progressBar = new SingleBar(\n {\n format: '{bar} {percentage}% | {value}/{total} | {message}',\n barCompleteChar: '█',\n barIncompleteChar: '░',\n hideCursor: true,\n clearOnComplete: true,\n },\n Presets.shades_grey,\n )\n\n ctx.on('process:start', async ({ files }) => {\n progressBar.start(files.length, 0, { message: 'Starting...' })\n })\n\n ctx.on('process:progress', async ({ file }) => {\n const message = `Writing ${relative(process.cwd(), file.path)}`\n progressBar.increment(1, { message })\n })\n\n ctx.on('process:end', async ({ files }) => {\n progressBar.update(files.length, { message: 'Done ✅' })\n progressBar.stop()\n })\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugins.js","names":["stack: Array<TreeNode<TData>>","result: Array<TreeNode<TData>>","nodes: Array<{ id: string; label: string }>","edges: Array<{ from: string; to: string }>","next: TreeNode<BarrelData> | undefined","path","path","process"],"sources":["../src/utils/TreeNode.ts","../src/plugins/createPlugin.ts","../src/plugins/barrelPlugin.ts","../src/plugins/fsPlugin.ts","../src/utils/open.ts","../src/plugins/graphPlugin.ts","../src/plugins/progressPlugin.ts"],"sourcesContent":["import type * as KubbFile from '../KubbFile.ts'\n\ntype BarrelData = {\n file?: KubbFile.File\n path: string\n name: string\n}\n\nexport type Graph = {\n nodes: Array<{ id: string; label: string }>\n edges: Array<{ from: string; to: string }>\n}\n\nexport class TreeNode<TData = unknown> {\n data: TData\n parent?: TreeNode<TData>\n children: Array<TreeNode<TData>> = []\n #cachedLeaves?: Array<TreeNode<TData>>\n\n constructor(data: TData, parent?: TreeNode<TData>) {\n this.data = data\n this.parent = parent\n }\n\n addChild(data: TData): TreeNode<TData> {\n const child = new TreeNode(data, this)\n this.children.push(child)\n this.#cachedLeaves = undefined // invalidate cached leaves\n return child\n }\n\n get leaves(): Array<TreeNode<TData>> {\n if (this.#cachedLeaves) return this.#cachedLeaves\n if (this.children.length === 0) return [this]\n\n const stack: Array<TreeNode<TData>> = [...this.children]\n const result: Array<TreeNode<TData>> = []\n\n for (const node of stack) {\n if (node.children.length) {\n for (const child of node.children) stack.push(child)\n } else {\n result.push(node)\n }\n }\n\n this.#cachedLeaves = result\n return result\n }\n\n forEach(callback: (node: TreeNode<TData>) => void): this {\n const stack: Array<TreeNode<TData>> = [this]\n\n for (const node of stack) {\n callback(node)\n if (node.children.length) {\n for (const child of node.children) stack.push(child)\n }\n }\n return this\n }\n\n findDeep(predicate: (node: TreeNode<TData>) => boolean): TreeNode<TData> | undefined {\n for (const leaf of this.leaves) {\n if (predicate(leaf)) return leaf\n }\n return undefined\n }\n\n static toGraph(root: TreeNode<BarrelData>): Graph {\n const nodes: Array<{ id: string; label: string }> = []\n const edges: Array<{ from: string; to: string }> = []\n\n root.forEach((node) => {\n nodes.push({\n id: node.data.path,\n label: node.data.name,\n })\n\n for (const child of node.children) {\n edges.push({\n from: node.data.path,\n to: child.data.path,\n })\n }\n })\n\n return { nodes, edges }\n }\n\n static fromFiles(files: Array<KubbFile.File>, rootFolder = ''): TreeNode<BarrelData> | null {\n const normalizePath = (p: string): string => p.replace(/\\\\/g, '/')\n const normalizedRoot = normalizePath(rootFolder)\n const rootPrefix = normalizedRoot.endsWith('/') ? normalizedRoot : `${normalizedRoot}/`\n\n const filteredFiles = files.filter((file) => {\n const filePath = normalizePath(file.path)\n\n return !filePath.endsWith('.json') && (!rootFolder || filePath.startsWith(rootPrefix))\n })\n\n if (filteredFiles.length === 0) {\n return null\n }\n\n const treeNode = new TreeNode<BarrelData>({\n name: rootFolder || '',\n path: rootFolder || '',\n file: undefined,\n })\n\n for (const file of filteredFiles) {\n const relPath = normalizePath(file.path).slice(rootPrefix.length)\n const parts = relPath.split('/')\n\n let current = treeNode\n let currentPath = rootFolder\n\n for (const [index, part] of parts.entries()) {\n const isLast = index === parts.length - 1\n currentPath += (currentPath.endsWith('/') ? '' : '/') + part\n\n let next: TreeNode<BarrelData> | undefined\n for (const child of current.children) {\n if ((child.data as BarrelData).name === part) {\n next = child\n break\n }\n }\n\n if (!next) {\n next = current.addChild({\n name: part,\n path: currentPath,\n file: isLast ? file : undefined,\n })\n }\n\n current = next\n }\n }\n\n return treeNode\n }\n}\n","import type { Plugin, UserPlugin } from './types.ts'\n\nexport function createPlugin<Options = unknown, TAppExtension extends Record<string, any> = {}>(\n plugin: UserPlugin<Options, TAppExtension>,\n): Plugin<Options, TAppExtension> {\n return {\n type: 'plugin',\n ...plugin,\n }\n}\n","/** biome-ignore-all lint/suspicious/useIterableCallbackReturn: not needed */\n\nimport path from 'node:path'\nimport { createFile } from '../createFile.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { getRelativePath } from '../utils/getRelativePath.ts'\nimport { TreeNode } from '../utils/TreeNode.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype Mode = 'all' | 'named' | 'propagate' | false\n\ntype Options = {\n root: string\n mode: Mode\n dryRun?: boolean\n}\n\ntype WriteEntryOptions = {\n root: string\n mode: Mode\n}\n\ntype ExtendOptions = {\n /**\n * `fabric.writeEntry` should be called before `fabric.write`\n */\n writeEntry(options: WriteEntryOptions): Promise<void>\n}\n\ndeclare global {\n namespace Kubb {\n interface Fabric {\n /**\n * `fabric.writeEntry` should be called before `fabric.write`\n */\n writeEntry(options: WriteEntryOptions): Promise<void>\n }\n }\n}\n\ntype GetBarrelFilesOptions = {\n files: KubbFile.File[]\n root: string\n mode: Mode\n}\n\nexport function getBarrelFiles({ files, root, mode }: GetBarrelFilesOptions): Array<KubbFile.File> {\n // Do not generate when propagating or disabled\n if (mode === 'propagate' || mode === false) {\n return []\n }\n\n const cachedFiles = new Map<KubbFile.Path, KubbFile.File>()\n const dedupe = new Map<KubbFile.Path, Set<string>>()\n\n const treeNode = TreeNode.fromFiles(files, root)\n\n if (!treeNode) {\n return []\n }\n\n treeNode.forEach((node) => {\n // Only create a barrel for directory-like nodes that have a parent with a path\n if (!node?.children || !node.parent?.data.path) {\n return\n }\n\n const parentPath = node.parent.data.path as KubbFile.Path\n const barrelPath = path.join(parentPath, 'index.ts') as KubbFile.Path\n\n let barrelFile = cachedFiles.get(barrelPath)\n if (!barrelFile) {\n barrelFile = createFile({\n path: barrelPath,\n baseName: 'index.ts',\n exports: [],\n sources: [],\n })\n cachedFiles.set(barrelPath, barrelFile)\n dedupe.set(barrelPath, new Set<string>())\n }\n\n const seen = dedupe.get(barrelPath)!\n\n // Collect all leaves under the current directory node\n node.leaves.forEach((leaf) => {\n const file = leaf.data.file\n if (!file) {\n return\n }\n\n const sources = file.sources || []\n sources.forEach((source) => {\n if (!file.path || !source.isIndexable || !source.name) {\n return\n }\n\n const key = `${source.name}|${source.isTypeOnly ? '1' : '0'}`\n if (seen.has(key)) {\n return\n }\n seen.add(key)\n\n // Always compute relative path from the parent directory to the file path\n barrelFile!.exports!.push({\n name: [source.name],\n path: getRelativePath(parentPath, file.path),\n isTypeOnly: source.isTypeOnly,\n })\n\n barrelFile!.sources.push({\n name: source.name,\n isTypeOnly: source.isTypeOnly,\n value: '', // TODO use parser to generate import\n isExportable: mode === 'all' || mode === 'named',\n isIndexable: mode === 'all' || mode === 'named',\n })\n })\n })\n })\n\n const result = [...cachedFiles.values()]\n\n if (mode === 'all') {\n return result.map((file) => ({\n ...file,\n exports: file.exports?.map((e) => ({ ...e, name: undefined })),\n }))\n }\n\n return result\n}\n\nexport const barrelPlugin = createPlugin<Options, ExtendOptions>({\n name: 'barrel',\n install(ctx, options) {\n if (!options) {\n throw new Error('Barrel plugin requires options.root and options.mode')\n }\n\n if (!options.mode) {\n return undefined\n }\n\n ctx.on('write:start', async ({ files }) => {\n const root = options.root\n const barrelFiles = getBarrelFiles({ files, root, mode: options.mode })\n\n await ctx.fileManager.add(...barrelFiles)\n })\n },\n inject(ctx, options) {\n if (!options) {\n throw new Error('Barrel plugin requires options.root and options.mode')\n }\n\n return {\n async writeEntry({ root, mode }) {\n if (!mode || mode === 'propagate') {\n return undefined\n }\n\n const rootPath = path.resolve(root, 'index.ts')\n\n const barrelFiles = ctx.files.filter((file) => {\n return file.sources.some((source) => source.isIndexable)\n })\n\n const entryFile = createFile({\n path: rootPath,\n baseName: 'index.ts',\n exports: barrelFiles\n .flatMap((file) => {\n const containsOnlyTypes = file.sources.every((source) => source.isTypeOnly)\n\n return file.sources\n ?.map((source) => {\n if (!file.path || !source.isIndexable) {\n return undefined\n }\n\n return {\n name: mode === 'all' ? undefined : [source.name],\n path: getRelativePath(rootPath, file.path),\n isTypeOnly: mode === 'all' ? containsOnlyTypes : source.isTypeOnly,\n } as KubbFile.Export\n })\n .filter(Boolean)\n })\n .filter(Boolean),\n sources: [],\n })\n\n await ctx.addFile(entryFile)\n\n await ctx.fileManager.write({\n mode: ctx.config.mode,\n dryRun: options.dryRun,\n parsers: ctx.installedParsers,\n })\n },\n }\n },\n})\n","import { resolve } from 'node:path'\nimport fs from 'fs-extra'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype WriteOptions = {\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n}\n\ntype Options = {\n dryRun?: boolean\n /**\n * Optional callback that is invoked whenever a file is written by the plugin.\n * Useful for tests to observe write operations without spying on internal functions.\n */\n onBeforeWrite?: (path: string, data: string | undefined) => void | Promise<void>\n clean?: {\n path: string\n }\n}\n\ntype ExtendOptions = {\n write(options?: WriteOptions): Promise<void>\n}\n\nexport async function write(path: string, data: string | undefined, options: { sanity?: boolean } = {}): Promise<string | undefined> {\n if (typeof Bun !== 'undefined') {\n if (!data || data?.trim() === '') {\n return undefined\n }\n\n await Bun.write(resolve(path), data.trim())\n\n if (options?.sanity) {\n const file = Bun.file(resolve(path))\n const savedData = await file.text()\n\n if (savedData?.toString() !== data?.toString()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data\n }\n\n if (!data || data?.trim() === '') {\n return undefined\n }\n\n try {\n const oldContent = await fs.readFile(resolve(path), {\n encoding: 'utf-8',\n })\n if (oldContent?.toString() === data?.toString()) {\n return\n }\n } catch (_err) {\n /* empty */\n }\n\n await fs.outputFile(resolve(path), data.trim(), { encoding: 'utf-8' })\n\n if (options?.sanity) {\n const savedData = await fs.readFile(resolve(path), {\n encoding: 'utf-8',\n })\n\n if (savedData?.toString() !== data?.toString()) {\n throw new Error(`Sanity check failed for ${path}\\n\\nData[${data.length}]:\\n${data}\\n\\nSaved[${savedData.length}]:\\n${savedData}\\n`)\n }\n\n return savedData\n }\n\n return data\n}\n\ndeclare global {\n namespace Kubb {\n interface Fabric {\n write(options?: WriteOptions): Promise<void>\n }\n }\n}\n\nexport const fsPlugin = createPlugin<Options, ExtendOptions>({\n name: 'fs',\n install(ctx, options = {}) {\n if (options.clean) {\n fs.removeSync(options.clean.path)\n }\n\n ctx.on('process:progress', async ({ file, source }) => {\n if (options.onBeforeWrite) {\n await options.onBeforeWrite(file.path, source)\n }\n await write(file.path, source, { sanity: false })\n })\n },\n inject(ctx, { dryRun } = {}) {\n return {\n async write(\n options = {\n extension: { '.ts': '.ts' },\n },\n ) {\n await ctx.fileManager.write({\n mode: ctx.config.mode,\n extension: options.extension,\n dryRun,\n parsers: ctx.installedParsers,\n })\n },\n }\n },\n})\n","import { spawn } from 'node:child_process'\n\nconst spawnBin = (bin: string, args: string[]): Promise<boolean> => {\n return new Promise((resolve) => {\n const process = spawn(bin, args, {\n detached: true,\n shell: false,\n windowsHide: true,\n })\n\n process.on('close', (code) => {\n resolve(!code)\n })\n })\n}\n\ntype Options = {\n app?: string\n}\n\nexport async function open(path: string, options?: Options): Promise<boolean> {\n const app = options?.app\n\n if (process.platform === 'win32') {\n return spawnBin('cmd.exe', ['/c', 'start', app || '', path.replace(/[&^]/g, '^$&')])\n }\n\n if (process.platform === 'linux') {\n return spawnBin(app || 'xdg-open', [path])\n }\n if (process.platform === 'darwin') {\n return spawnBin('open', app ? ['-a', app, path] : [path])\n }\n\n throw new Error(`Unsupported platform, could not open \"${path}\"`)\n}\n","import http from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport path from 'node:path'\nimport handler from 'serve-handler'\nimport { createFile } from '../createFile.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { open } from '../utils/open.ts'\nimport { type Graph, TreeNode } from '../utils/TreeNode.ts'\nimport { createPlugin } from './createPlugin.ts'\n\ntype Options = {\n root: string\n /**\n * @default false\n */\n open?: boolean\n}\n\ntype GetGraphOptions = {\n files: KubbFile.File[]\n root: string\n}\n\nexport function getGraph({ files, root }: GetGraphOptions): Graph | undefined {\n const treeNode = TreeNode.fromFiles(files, root)\n\n if (!treeNode) {\n return undefined\n }\n\n return TreeNode.toGraph(treeNode)\n}\nconst html = `\n <!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>File Graph</title>\n <script type=\"module\">\n import { Network } from 'https://cdn.jsdelivr.net/npm/vis-network/standalone/esm/vis-network.min.js'\n\n async function main() {\n const res = await fetch('./graph.json')\n const { nodes, edges } = await res.json()\n const container = document.getElementById('graph')\n\n const network = new Network(\n container,\n { nodes, edges },\n {\n layout: { hierarchical: { direction: 'UD', sortMethod: 'directed' } },\n nodes: { shape: 'box', font: { face: 'monospace' } },\n edges: { arrows: 'to' },\n physics: false,\n },\n )\n }\n\n main()\n </script>\n <style>\n html, body, #graph { height: 100%; margin: 0; }\n </style>\n </head>\n <body>\n <div id=\"graph\"></div>\n </body>\n</html>\n`\n\nasync function serve(root: string) {\n const server = http.createServer((req, res) => {\n return handler(req, res, {\n public: root,\n cleanUrls: true,\n })\n })\n\n server.listen(0, async () => {\n const { port } = server.address() as AddressInfo\n console.log(`Running on http://localhost:${port}/graph.html`)\n\n await open(`http://localhost:${port}/graph.html`)\n })\n}\n\nexport const graphPlugin = createPlugin<Options>({\n name: 'graph',\n install(ctx, options) {\n if (!options) {\n throw new Error('Graph plugin requires options.root and options.mode')\n }\n\n ctx.on('write:start', async ({ files }) => {\n const root = options.root\n\n const graph = getGraph({ files, root })\n\n if (!graph) {\n return undefined\n }\n\n const graphFile = createFile({\n baseName: 'graph.json',\n path: path.join(root, 'graph.json'),\n sources: [\n {\n name: 'graph',\n value: JSON.stringify(graph, null, 2),\n },\n ],\n })\n\n const graphHtmlFile = createFile({\n baseName: 'graph.html',\n path: path.join(root, 'graph.html'),\n sources: [\n {\n name: 'graph',\n value: html,\n },\n ],\n })\n\n await ctx.addFile(graphFile, graphHtmlFile)\n\n if (options.open) {\n await serve(root)\n }\n })\n },\n})\n","import { relative } from 'node:path'\nimport process from 'node:process'\nimport { Presets, SingleBar } from 'cli-progress'\nimport { createPlugin } from './createPlugin.ts'\n\nexport const progressPlugin = createPlugin({\n name: 'progress',\n install(ctx) {\n const progressBar = new SingleBar(\n {\n format: '{bar} {percentage}% | {value}/{total} | {message}',\n barCompleteChar: '█',\n barIncompleteChar: '░',\n hideCursor: true,\n clearOnComplete: true,\n },\n Presets.shades_grey,\n )\n\n ctx.on('process:start', async ({ files }) => {\n progressBar.start(files.length, 0, { message: 'Starting...' })\n })\n\n ctx.on('process:progress', async ({ file }) => {\n const message = `Writing ${relative(process.cwd(), file.path)}`\n progressBar.increment(1, { message })\n })\n\n ctx.on('process:end', async ({ files }) => {\n progressBar.update(files.length, { message: 'Done ✅' })\n progressBar.stop()\n })\n },\n})\n"],"mappings":"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"}
|
package/dist/types.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as FabricOptions, i as FabricMode, m as KubbFile_d_exports, n as FabricConfig, r as FabricContext } from "./Fabric-
|
|
1
|
+
import { a as FabricOptions, i as FabricMode, m as KubbFile_d_exports, n as FabricConfig, r as FabricContext } from "./Fabric-BezqNTQ9.cjs";
|
|
2
2
|
export { type FabricConfig, type FabricContext, type FabricMode, type FabricOptions, KubbFile_d_exports as KubbFile };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as FabricOptions, i as FabricMode, m as KubbFile_d_exports, n as FabricConfig, r as FabricContext } from "./Fabric-
|
|
1
|
+
import { a as FabricOptions, i as FabricMode, m as KubbFile_d_exports, n as FabricConfig, r as FabricContext } from "./Fabric-CVe8cc8b.js";
|
|
2
2
|
export { type FabricConfig, type FabricContext, type FabricMode, type FabricOptions, KubbFile_d_exports as KubbFile };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as Parser } from "./Fabric-
|
|
1
|
+
import { u as Parser } from "./Fabric-CVe8cc8b.js";
|
|
2
2
|
import ts from "typescript";
|
|
3
3
|
|
|
4
4
|
//#region src/parsers/typescriptParser.d.ts
|
|
@@ -47,4 +47,4 @@ declare function createExport({
|
|
|
47
47
|
declare const typescriptParser: Parser<[], any>;
|
|
48
48
|
//#endregion
|
|
49
49
|
export { typescriptParser as i, createImport as n, print as r, createExport as t };
|
|
50
|
-
//# sourceMappingURL=typescriptParser-
|
|
50
|
+
//# sourceMappingURL=typescriptParser-B5SxjtvV.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as Parser } from "./Fabric-
|
|
1
|
+
import { u as Parser } from "./Fabric-BezqNTQ9.cjs";
|
|
2
2
|
import ts from "typescript";
|
|
3
3
|
|
|
4
4
|
//#region src/parsers/typescriptParser.d.ts
|
|
@@ -47,4 +47,4 @@ declare function createExport({
|
|
|
47
47
|
declare const typescriptParser: Parser<[], any>;
|
|
48
48
|
//#endregion
|
|
49
49
|
export { typescriptParser as i, createImport as n, print as r, createExport as t };
|
|
50
|
-
//# sourceMappingURL=typescriptParser-
|
|
50
|
+
//# sourceMappingURL=typescriptParser-PfAO0SSm.d.cts.map
|
package/package.json
CHANGED
package/src/Fabric.ts
CHANGED
|
@@ -50,10 +50,12 @@ export interface FabricEvents {
|
|
|
50
50
|
|
|
51
51
|
/** Called once before any files are processed. */
|
|
52
52
|
'process:start': [{ files: KubbFile.ResolvedFile[] }]
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Called when FileManager is adding files to its cache
|
|
55
|
+
*/
|
|
55
56
|
'file:add': [{ files: KubbFile.ResolvedFile[] }]
|
|
56
|
-
|
|
57
|
+
'file:resolve:path': [{ file: KubbFile.File }]
|
|
58
|
+
'file:resolve:name': [{ file: KubbFile.File }]
|
|
57
59
|
'write:start': [{ files: KubbFile.ResolvedFile[] }]
|
|
58
60
|
'write:end': [{ files: KubbFile.ResolvedFile[] }]
|
|
59
61
|
|
|
@@ -86,7 +88,7 @@ export interface FabricEvents {
|
|
|
86
88
|
*/
|
|
87
89
|
export interface FabricContext<T extends FabricOptions = FabricOptions> extends AsyncEventEmitter<FabricEvents> {
|
|
88
90
|
/** The active Fabric configuration. */
|
|
89
|
-
config
|
|
91
|
+
config: FabricConfig<T>
|
|
90
92
|
|
|
91
93
|
/** The internal file manager handling file creation, merging, and writing. */
|
|
92
94
|
fileManager: FileManager
|
|
@@ -105,10 +107,7 @@ export interface FabricContext<T extends FabricOptions = FabricOptions> extends
|
|
|
105
107
|
/**
|
|
106
108
|
* Base configuration object for Fabric.
|
|
107
109
|
*/
|
|
108
|
-
export
|
|
109
|
-
/** The runtime options used to configure Fabric. */
|
|
110
|
-
options: T
|
|
111
|
-
}
|
|
110
|
+
export type FabricConfig<T extends FabricOptions = FabricOptions> = T
|
|
112
111
|
|
|
113
112
|
/**
|
|
114
113
|
* Utility type that checks whether all properties of `T` are optional.
|