@kubb/fabric-core 0.7.4 → 0.8.0

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/plugins.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  const require_trimExtName = require('./trimExtName-DaBSwMN-.cjs');
2
- const require_defineProperty = require('./defineProperty-B59n8a_H.cjs');
2
+ const require_defineProperty = require('./defineProperty-Db0mqPmh.cjs');
3
3
  const require_getRelativePath = require('./getRelativePath-CLj7Ou6d.cjs');
4
4
  let node_path = require("node:path");
5
5
  node_path = require_trimExtName.__toESM(node_path);
@@ -10,8 +10,10 @@ node_http = require_trimExtName.__toESM(node_http);
10
10
  let serve_handler = require("serve-handler");
11
11
  serve_handler = require_trimExtName.__toESM(serve_handler);
12
12
  let node_child_process = require("node:child_process");
13
- let cli_progress = require("cli-progress");
14
- let consola = require("consola");
13
+ let _clack_prompts = require("@clack/prompts");
14
+ _clack_prompts = require_trimExtName.__toESM(_clack_prompts);
15
+ let picocolors = require("picocolors");
16
+ picocolors = require_trimExtName.__toESM(picocolors);
15
17
  let ws = require("ws");
16
18
 
17
19
  //#region src/utils/TreeNode.ts
@@ -305,6 +307,7 @@ const fsPlugin = definePlugin({
305
307
  dryRun,
306
308
  parsers: ctx.installedParsers
307
309
  });
310
+ await ctx.emit("lifecycle:end");
308
311
  } };
309
312
  }
310
313
  });
@@ -448,20 +451,19 @@ function serializeFile(file) {
448
451
  function pluralize(word, count) {
449
452
  return `${count} ${word}${count === 1 ? "" : "s"}`;
450
453
  }
451
- const defaultTag = "Fabric";
452
- const createProgressBar = () => new cli_progress.SingleBar({
453
- format: "{bar} {percentage}% | {value}/{total} | {message}",
454
- barCompleteChar: "█",
455
- barIncompleteChar: "░",
456
- hideCursor: true,
457
- clearOnComplete: true
458
- }, cli_progress.Presets.shades_grey);
454
+ const DEFAULT_PROGRESS_BAR_SIZE = 30;
459
455
  const loggerPlugin = definePlugin({
460
456
  name: "logger",
461
457
  install(ctx, options = {}) {
462
- const { level, websocket = true, progress = true } = options;
463
- const logger = (0, consola.createConsola)(level !== void 0 ? { level } : {}).withTag(defaultTag);
464
- const progressBar = progress ? createProgressBar() : void 0;
458
+ const { websocket = true, progress = true } = options;
459
+ const state = {
460
+ spinner: _clack_prompts.spinner(),
461
+ isSpinning: false,
462
+ progressBar: void 0
463
+ };
464
+ function formatPath(path$2) {
465
+ return (0, node_path.relative)(process.cwd(), path$2);
466
+ }
465
467
  let server;
466
468
  let wss;
467
469
  const broadcast = (event, payload) => {
@@ -481,12 +483,12 @@ const loggerPlugin = definePlugin({
481
483
  if (addressInfo && typeof addressInfo === "object") {
482
484
  const { host: resolvedHost, port: resolvedPort } = normalizeAddress(addressInfo);
483
485
  const url = `ws://${resolvedHost}:${resolvedPort}`;
484
- logger.info(`Logger websocket listening on ${url}`);
486
+ _clack_prompts.log.info(`${picocolors.default.blue("ℹ")} Logger websocket listening on ${url}`);
485
487
  broadcast("websocket:ready", { url });
486
488
  }
487
489
  });
488
490
  wss.on("connection", (socket) => {
489
- logger.info("Logger websocket client connected");
491
+ _clack_prompts.log.info(`${picocolors.default.blue("ℹ")} Logger websocket client connected`);
490
492
  socket.send(JSON.stringify({
491
493
  event: "welcome",
492
494
  payload: {
@@ -496,44 +498,47 @@ const loggerPlugin = definePlugin({
496
498
  }));
497
499
  });
498
500
  wss.on("error", (error) => {
499
- logger.error("Logger websocket error", error);
501
+ _clack_prompts.log.error(`${picocolors.default.red("✗")} Logger websocket error: ${error.message}`);
500
502
  });
501
503
  }
502
- const formatPath = (path$2) => (0, node_path.relative)(process.cwd(), path$2);
503
504
  ctx.on("lifecycle:start", async () => {
504
- logger.start("Starting Fabric run");
505
+ _clack_prompts.intro(`${picocolors.default.blue("Fabric")} ${picocolors.default.dim("Starting run")}`);
505
506
  broadcast("lifecycle:start", { timestamp: Date.now() });
506
507
  });
507
508
  ctx.on("lifecycle:render", async () => {
508
- logger.info("Rendering application graph");
509
+ _clack_prompts.log.info(`${picocolors.default.blue("ℹ")} Rendering application graph`);
509
510
  broadcast("lifecycle:render", { timestamp: Date.now() });
510
511
  });
511
512
  ctx.on("files:added", async (files) => {
512
513
  if (!files.length) return;
513
- logger.info(`Queued ${pluralize("file", files.length)}`);
514
+ _clack_prompts.log.info(`${picocolors.default.blue("ℹ")} Queued ${pluralize("file", files.length)}`);
514
515
  broadcast("files:added", { files: files.map(serializeFile) });
515
516
  });
516
517
  ctx.on("file:resolve:path", async (file) => {
517
- logger.info(`Resolving path for ${formatPath(file.path)}`);
518
+ _clack_prompts.log.step(`Resolving path for ${picocolors.default.dim(formatPath(file.path))}`);
518
519
  broadcast("file:resolve:path", { file: serializeFile(file) });
519
520
  });
520
521
  ctx.on("file:resolve:name", async (file) => {
521
- logger.info(`Resolving name for ${formatPath(file.path)}`);
522
+ _clack_prompts.log.step(`Resolving name for ${picocolors.default.dim(formatPath(file.path))}`);
522
523
  broadcast("file:resolve:name", { file: serializeFile(file) });
523
524
  });
524
525
  ctx.on("files:processing:start", async (files) => {
525
- logger.start(`Processing ${pluralize("file", files.length)}`);
526
+ _clack_prompts.log.step(`Processing ${picocolors.default.green(pluralize("file", files.length))}`);
526
527
  broadcast("files:processing:start", {
527
528
  total: files.length,
528
529
  timestamp: Date.now()
529
530
  });
530
- if (progressBar) {
531
- logger.pauseLogs();
532
- progressBar.start(files.length, 0, { message: "Starting..." });
531
+ if (progress) {
532
+ state.progressBar = _clack_prompts.progress({
533
+ style: "block",
534
+ max: files.length,
535
+ size: DEFAULT_PROGRESS_BAR_SIZE
536
+ });
537
+ state.progressBar.start(`Processing ${files.length} files`);
533
538
  }
534
539
  });
535
540
  ctx.on("file:processing:start", async (file, index, total) => {
536
- logger.info(`Processing [${index + 1}/${total}] ${formatPath(file.path)}`);
541
+ if (!state.progressBar) _clack_prompts.log.step(`Processing ${picocolors.default.dim(`[${index + 1}/${total}]`)} ${formatPath(file.path)}`);
537
542
  broadcast("file:processing:start", {
538
543
  index,
539
544
  total,
@@ -541,18 +546,21 @@ const loggerPlugin = definePlugin({
541
546
  });
542
547
  });
543
548
  ctx.on("file:processing:update", async ({ processed, total, percentage, file }) => {
544
- const formattedPercentage = Number.isFinite(percentage) ? percentage.toFixed(1) : "0.0";
545
- logger.info(`Progress ${formattedPercentage}% (${processed}/${total}) → ${formatPath(file.path)}`);
546
549
  broadcast("file:processing:update", {
547
550
  processed,
548
551
  total,
549
552
  percentage,
550
553
  file: serializeFile(file)
551
554
  });
552
- if (progressBar) progressBar.increment(1, { message: `Writing ${formatPath(file.path)}` });
555
+ if (state.progressBar) state.progressBar.advance(void 0, `Writing ${formatPath(file.path)}`);
556
+ else {
557
+ const formattedPercentage = Number.isFinite(percentage) ? percentage.toFixed(1) : "0.0";
558
+ _clack_prompts.log.step(`Progress ${picocolors.default.green(`${formattedPercentage}%`)} ${picocolors.default.dim(`(${processed}/${total})`)} → ${formatPath(file.path)}`);
559
+ }
553
560
  });
554
561
  ctx.on("file:processing:end", async (file, index, total) => {
555
- logger.success(`Finished [${index + 1}/${total}] ${formatPath(file.path)}`);
562
+ if (state.progressBar) state.progressBar.message(`${picocolors.default.green("✓")} Finished ${picocolors.default.dim(`[${index + 1}/${total}]`)} ${formatPath(file.path)}`);
563
+ else _clack_prompts.log.success(`${picocolors.default.green("✓")} Finished ${picocolors.default.dim(`[${index + 1}/${total}]`)} ${formatPath(file.path)}`);
556
564
  broadcast("file:processing:end", {
557
565
  index,
558
566
  total,
@@ -560,32 +568,28 @@ const loggerPlugin = definePlugin({
560
568
  });
561
569
  });
562
570
  ctx.on("files:writing:start", async (files) => {
563
- logger.start(`Writing ${pluralize("file", files.length)} to disk`);
564
571
  broadcast("files:writing:start", { files: files.map(serializeFile) });
565
572
  });
566
573
  ctx.on("files:writing:end", async (files) => {
567
- logger.success(`Written ${pluralize("file", files.length)} to disk`);
568
574
  broadcast("files:writing:end", { files: files.map(serializeFile) });
569
575
  });
570
576
  ctx.on("files:processing:end", async (files) => {
571
- logger.success(`Processed ${pluralize("file", files.length)}`);
577
+ if (state.progressBar) {
578
+ state.progressBar.stop(`${picocolors.default.green("✓")} Processed ${pluralize("file", files.length)}`);
579
+ state.progressBar = void 0;
580
+ } else _clack_prompts.log.success(`${picocolors.default.green("✓")} Processed ${pluralize("file", files.length)}`);
572
581
  broadcast("files:processing:end", {
573
582
  total: files.length,
574
583
  timestamp: Date.now()
575
584
  });
576
- if (progressBar) {
577
- progressBar.update(files.length, { message: "Done ✅" });
578
- progressBar.stop();
579
- logger.resumeLogs();
580
- }
581
585
  });
582
586
  ctx.on("lifecycle:end", async () => {
583
- logger.success("Fabric run completed");
584
- broadcast("lifecycle:end", { timestamp: Date.now() });
585
- if (progressBar) {
586
- progressBar.stop();
587
- logger.resumeLogs();
587
+ if (state.progressBar) {
588
+ state.progressBar.stop();
589
+ state.progressBar = void 0;
588
590
  }
591
+ _clack_prompts.outro(`${picocolors.default.blue("Fabric")} ${picocolors.default.dim("completed")}`);
592
+ broadcast("lifecycle:end", { timestamp: Date.now() });
589
593
  const closures = [];
590
594
  if (wss) {
591
595
  const wsServer = wss;
@@ -602,7 +606,7 @@ const loggerPlugin = definePlugin({
602
606
  }
603
607
  if (closures.length) {
604
608
  await Promise.allSettled(closures);
605
- logger.info("Logger websocket closed");
609
+ _clack_prompts.log.info(`${picocolors.default.blue("ℹ")} Logger websocket closed`);
606
610
  }
607
611
  });
608
612
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.cjs","names":["result: Array<TreeNode<TData>>","stack: Array<TreeNode<TData>>","nodes: Array<{ id: string; label: string }>","edges: Array<{ from: string; to: string }>","stack: Array<TreeNode<BarrelData>>","filteredFiles: Array<KubbFile.File>","indexableSources: Array<KubbFile.Source>","path","createFile","getRelativePath","barrelFiles: Array<KubbFile.ResolvedFile>","exports: Array<KubbFile.Export>","path","fs","path","http","createFile","path","SingleBar","Presets","server: http.Server | undefined","wss: WebSocketServer | undefined","broadcast: Broadcast","WebSocket","http","WebSocketServer","path","closures: Array<Promise<void>>","resolve"],"sources":["../src/utils/TreeNode.ts","../src/plugins/definePlugin.ts","../src/plugins/barrelPlugin.ts","../src/plugins/fsPlugin.ts","../src/utils/open.ts","../src/plugins/graphPlugin.ts","../src/plugins/loggerPlugin.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 #childrenMap = new Map<string, 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 // Update Map if data has a name property (for BarrelData)\n if (typeof data === 'object' && data !== null && 'name' in data) {\n this.#childrenMap.set((data as { name: string }).name, child)\n }\n this.#cachedLeaves = undefined // invalidate cached leaves\n return child\n }\n\n getChildByName(name: string): TreeNode<TData> | undefined {\n return this.#childrenMap.get(name)\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 result: Array<TreeNode<TData>> = []\n const stack: Array<TreeNode<TData>> = [...this.children]\n const visited = new Set<TreeNode<TData>>()\n\n while (stack.length > 0) {\n const node = stack.pop()!\n if (visited.has(node)) {\n continue\n }\n visited.add(node)\n\n if (node.children.length > 0) {\n stack.push(...node.children)\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 (let i = 0; i < stack.length; i++) {\n const node = stack[i]!\n callback(node)\n\n if (node.children.length > 0) {\n stack.push(...node.children)\n }\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 const stack: Array<TreeNode<BarrelData>> = [root]\n\n for (let i = 0; i < stack.length; i++) {\n const node = stack[i]!\n\n nodes.push({\n id: node.data.path,\n label: node.data.name,\n })\n\n const children = node.children\n if (children.length > 0) {\n for (let j = 0, len = children.length; j < len; j++) {\n const child = children[j]!\n edges.push({\n from: node.data.path,\n to: child.data.path,\n })\n stack.push(child)\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 normalizedPaths = new Map<KubbFile.File, string>()\n const filteredFiles: Array<KubbFile.File> = []\n for (const file of files) {\n const filePath = normalizedPaths.get(file) ?? normalizePath(file.path)\n normalizedPaths.set(file, filePath)\n if (!filePath.endsWith('.json') && (!rootFolder || filePath.startsWith(rootPrefix))) {\n filteredFiles.push(file)\n }\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 filePath = normalizedPaths.get(file)!\n const relPath = filePath.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 = current.getChildByName(part)\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 definePlugin<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 { definePlugin } from './definePlugin.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 indexableSourcesMap = new Map<KubbFile.File, Array<KubbFile.Source>>()\n\n for (const file of files) {\n const indexableSources: Array<KubbFile.Source> = []\n for (const source of file.sources || []) {\n if (source.isIndexable && source.name) {\n indexableSources.push(source)\n }\n }\n if (indexableSources.length > 0) {\n indexableSourcesMap.set(file, indexableSources)\n }\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 for (const leaf of node.leaves) {\n const file = leaf.data.file\n if (!file || !file.path) {\n continue\n }\n\n const indexableSources = indexableSourcesMap.get(file)\n if (!indexableSources) {\n continue\n }\n\n for (const source of indexableSources) {\n const key = `${source.name}|${source.isTypeOnly ? '1' : '0'}`\n if (seen.has(key)) {\n continue\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 = definePlugin<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('files:writing: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: Array<KubbFile.ResolvedFile> = []\n for (const file of ctx.files) {\n for (const source of file.sources) {\n if (source.isIndexable) {\n barrelFiles.push(file)\n\n break\n }\n }\n }\n\n const fileTypeCache = new Map<KubbFile.ResolvedFile, boolean>()\n for (const file of barrelFiles) {\n fileTypeCache.set(\n file,\n file.sources.every((source) => source.isTypeOnly),\n )\n }\n\n const exports: Array<KubbFile.Export> = []\n for (const file of barrelFiles) {\n const containsOnlyTypes = fileTypeCache.get(file) ?? false\n\n for (const source of file.sources) {\n if (!file.path || !source.isIndexable) {\n continue\n }\n\n exports.push({\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 }\n\n const entryFile = createFile({\n path: rootPath,\n baseName: 'index.ts',\n exports,\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 { definePlugin } from './definePlugin.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 = definePlugin<Options, ExtendOptions>({\n name: 'fs',\n install(ctx, options = {}) {\n if (options.clean) {\n fs.removeSync(options.clean.path)\n }\n\n ctx.on('file:processing:update', 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 { definePlugin } from './definePlugin.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 = definePlugin<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('files:writing: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 http from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport { relative } from 'node:path'\nimport { Presets, SingleBar } from 'cli-progress'\nimport { createConsola, type LogLevel } from 'consola'\nimport { WebSocket, WebSocketServer } from 'ws'\nimport type { FabricEvents } from '../Fabric.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { definePlugin } from './definePlugin.ts'\n\ntype Broadcast = <T = unknown>(event: keyof FabricEvents | string, payload: T) => void\ntype WebSocketOptions = {\n /**\n * Hostname to bind the websocket server to.\n * @default '127.0.0.1'\n */\n host?: string\n /**\n * Port to bind the websocket server to.\n * @default 0 (random available port)\n */\n port?: number\n}\n\ntype Options = {\n /**\n * Explicit consola log level.\n */\n level?: LogLevel\n /**\n * Toggle progress bar output.\n * @default true\n */\n progress?: boolean\n /**\n * Toggle or configure the websocket broadcast server.\n * When `true`, a websocket server is started on an ephemeral port.\n * When `false`, websocket support is disabled.\n * When providing an object, the server uses the supplied host and port.\n * @default true\n */\n websocket?: boolean | WebSocketOptions\n}\n\nfunction normalizeAddress(address: AddressInfo): {\n host: string\n port: number\n} {\n const host = address.address === '::' ? '127.0.0.1' : address.address\n\n return { host, port: address.port }\n}\n\nfunction serializeFile(file: KubbFile.File | KubbFile.ResolvedFile) {\n return {\n path: file.path,\n baseName: file.baseName,\n name: 'name' in file ? file.name : undefined,\n extname: 'extname' in file ? file.extname : undefined,\n }\n}\n\nfunction pluralize(word: string, count: number) {\n return `${count} ${word}${count === 1 ? '' : 's'}`\n}\n\nconst defaultTag = 'Fabric'\n\nconst createProgressBar = () =>\n 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\nexport const loggerPlugin = definePlugin<Options>({\n name: 'logger',\n install(ctx, options = {}) {\n const { level, websocket = true, progress = true } = options\n\n const logger = createConsola(level !== undefined ? { level } : {}).withTag(defaultTag)\n\n const progressBar = progress ? createProgressBar() : undefined\n\n let server: http.Server | undefined\n let wss: WebSocketServer | undefined\n\n const broadcast: Broadcast = (event, payload) => {\n if (!wss) {\n return\n }\n\n const message = JSON.stringify({ event, payload })\n\n for (const client of wss.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(message)\n }\n }\n }\n\n if (websocket) {\n const { host = '127.0.0.1', port = 0 } = typeof websocket === 'boolean' ? {} : websocket\n\n server = http.createServer()\n wss = new WebSocketServer({ server })\n\n server.listen(port, host, () => {\n const addressInfo = server?.address()\n\n if (addressInfo && typeof addressInfo === 'object') {\n const { host: resolvedHost, port: resolvedPort } = normalizeAddress(addressInfo)\n const url = `ws://${resolvedHost}:${resolvedPort}`\n\n logger.info(`Logger websocket listening on ${url}`)\n broadcast('websocket:ready', { url })\n }\n })\n\n wss.on('connection', (socket) => {\n logger.info('Logger websocket client connected')\n socket.send(\n JSON.stringify({\n event: 'welcome',\n payload: {\n message: 'Connected to Fabric log stream',\n timestamp: Date.now(),\n },\n }),\n )\n })\n\n wss.on('error', (error) => {\n logger.error('Logger websocket error', error)\n })\n }\n\n const formatPath = (path: string) => relative(process.cwd(), path)\n\n ctx.on('lifecycle:start', async () => {\n logger.start('Starting Fabric run')\n broadcast('lifecycle:start', { timestamp: Date.now() })\n })\n\n ctx.on('lifecycle:render', async () => {\n logger.info('Rendering application graph')\n broadcast('lifecycle:render', { timestamp: Date.now() })\n })\n\n ctx.on('files:added', async (files) => {\n if (!files.length) {\n return\n }\n\n logger.info(`Queued ${pluralize('file', files.length)}`)\n broadcast('files:added', {\n files: files.map(serializeFile),\n })\n })\n\n ctx.on('file:resolve:path', async (file) => {\n logger.info(`Resolving path for ${formatPath(file.path)}`)\n broadcast('file:resolve:path', { file: serializeFile(file) })\n })\n\n ctx.on('file:resolve:name', async (file) => {\n logger.info(`Resolving name for ${formatPath(file.path)}`)\n broadcast('file:resolve:name', { file: serializeFile(file) })\n })\n\n ctx.on('files:processing:start', async (files) => {\n logger.start(`Processing ${pluralize('file', files.length)}`)\n broadcast('files:processing:start', {\n total: files.length,\n timestamp: Date.now(),\n })\n\n if (progressBar) {\n logger.pauseLogs()\n progressBar.start(files.length, 0, { message: 'Starting...' })\n }\n })\n\n ctx.on('file:processing:start', async (file, index, total) => {\n logger.info(`Processing [${index + 1}/${total}] ${formatPath(file.path)}`)\n broadcast('file:processing:start', {\n index,\n total,\n file: serializeFile(file),\n })\n })\n\n ctx.on('file:processing:update', async ({ processed, total, percentage, file }) => {\n const formattedPercentage = Number.isFinite(percentage) ? percentage.toFixed(1) : '0.0'\n\n logger.info(`Progress ${formattedPercentage}% (${processed}/${total}) → ${formatPath(file.path)}`)\n broadcast('file:processing:update', {\n processed,\n total,\n percentage,\n file: serializeFile(file),\n })\n\n if (progressBar) {\n progressBar.increment(1, {\n message: `Writing ${formatPath(file.path)}`,\n })\n }\n })\n\n ctx.on('file:processing:end', async (file, index, total) => {\n logger.success(`Finished [${index + 1}/${total}] ${formatPath(file.path)}`)\n broadcast('file:processing:end', {\n index,\n total,\n file: serializeFile(file),\n })\n })\n\n ctx.on('files:writing:start', async (files) => {\n logger.start(`Writing ${pluralize('file', files.length)} to disk`)\n broadcast('files:writing:start', {\n files: files.map(serializeFile),\n })\n })\n\n ctx.on('files:writing:end', async (files) => {\n logger.success(`Written ${pluralize('file', files.length)} to disk`)\n broadcast('files:writing:end', {\n files: files.map(serializeFile),\n })\n })\n\n ctx.on('files:processing:end', async (files) => {\n logger.success(`Processed ${pluralize('file', files.length)}`)\n broadcast('files:processing:end', {\n total: files.length,\n timestamp: Date.now(),\n })\n\n if (progressBar) {\n progressBar.update(files.length, { message: 'Done ✅' })\n progressBar.stop()\n\n logger.resumeLogs()\n }\n })\n\n ctx.on('lifecycle:end', async () => {\n logger.success('Fabric run completed')\n broadcast('lifecycle:end', { timestamp: Date.now() })\n\n if (progressBar) {\n progressBar.stop()\n logger.resumeLogs()\n }\n\n const closures: Array<Promise<void>> = []\n\n if (wss) {\n const wsServer = wss\n\n closures.push(\n new Promise((resolve) => {\n for (const client of wsServer.clients) {\n client.close()\n }\n wsServer.close(() => resolve())\n }),\n )\n }\n\n if (server) {\n const httpServer = server\n\n closures.push(\n new Promise((resolve) => {\n httpServer.close(() => resolve())\n }),\n )\n }\n\n if (closures.length) {\n await Promise.allSettled(closures)\n logger.info('Logger websocket closed')\n }\n })\n },\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugins.cjs","names":["result: Array<TreeNode<TData>>","stack: Array<TreeNode<TData>>","nodes: Array<{ id: string; label: string }>","edges: Array<{ from: string; to: string }>","stack: Array<TreeNode<BarrelData>>","filteredFiles: Array<KubbFile.File>","indexableSources: Array<KubbFile.Source>","path","createFile","getRelativePath","barrelFiles: Array<KubbFile.ResolvedFile>","exports: Array<KubbFile.Export>","path","fs","path","http","createFile","path","clack","path","server: http.Server | undefined","wss: WebSocketServer | undefined","broadcast: Broadcast","WebSocket","http","WebSocketServer","pc","closures: Array<Promise<void>>","resolve"],"sources":["../src/utils/TreeNode.ts","../src/plugins/definePlugin.ts","../src/plugins/barrelPlugin.ts","../src/plugins/fsPlugin.ts","../src/utils/open.ts","../src/plugins/graphPlugin.ts","../src/plugins/loggerPlugin.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 #childrenMap = new Map<string, 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 // Update Map if data has a name property (for BarrelData)\n if (typeof data === 'object' && data !== null && 'name' in data) {\n this.#childrenMap.set((data as { name: string }).name, child)\n }\n this.#cachedLeaves = undefined // invalidate cached leaves\n return child\n }\n\n getChildByName(name: string): TreeNode<TData> | undefined {\n return this.#childrenMap.get(name)\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 result: Array<TreeNode<TData>> = []\n const stack: Array<TreeNode<TData>> = [...this.children]\n const visited = new Set<TreeNode<TData>>()\n\n while (stack.length > 0) {\n const node = stack.pop()!\n if (visited.has(node)) {\n continue\n }\n visited.add(node)\n\n if (node.children.length > 0) {\n stack.push(...node.children)\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 (let i = 0; i < stack.length; i++) {\n const node = stack[i]!\n callback(node)\n\n if (node.children.length > 0) {\n stack.push(...node.children)\n }\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 const stack: Array<TreeNode<BarrelData>> = [root]\n\n for (let i = 0; i < stack.length; i++) {\n const node = stack[i]!\n\n nodes.push({\n id: node.data.path,\n label: node.data.name,\n })\n\n const children = node.children\n if (children.length > 0) {\n for (let j = 0, len = children.length; j < len; j++) {\n const child = children[j]!\n edges.push({\n from: node.data.path,\n to: child.data.path,\n })\n stack.push(child)\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 normalizedPaths = new Map<KubbFile.File, string>()\n const filteredFiles: Array<KubbFile.File> = []\n for (const file of files) {\n const filePath = normalizedPaths.get(file) ?? normalizePath(file.path)\n normalizedPaths.set(file, filePath)\n if (!filePath.endsWith('.json') && (!rootFolder || filePath.startsWith(rootPrefix))) {\n filteredFiles.push(file)\n }\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 filePath = normalizedPaths.get(file)!\n const relPath = filePath.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 = current.getChildByName(part)\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 definePlugin<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 { definePlugin } from './definePlugin.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 indexableSourcesMap = new Map<KubbFile.File, Array<KubbFile.Source>>()\n\n for (const file of files) {\n const indexableSources: Array<KubbFile.Source> = []\n for (const source of file.sources || []) {\n if (source.isIndexable && source.name) {\n indexableSources.push(source)\n }\n }\n if (indexableSources.length > 0) {\n indexableSourcesMap.set(file, indexableSources)\n }\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 for (const leaf of node.leaves) {\n const file = leaf.data.file\n if (!file || !file.path) {\n continue\n }\n\n const indexableSources = indexableSourcesMap.get(file)\n if (!indexableSources) {\n continue\n }\n\n for (const source of indexableSources) {\n const key = `${source.name}|${source.isTypeOnly ? '1' : '0'}`\n if (seen.has(key)) {\n continue\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 = definePlugin<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('files:writing: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: Array<KubbFile.ResolvedFile> = []\n for (const file of ctx.files) {\n for (const source of file.sources) {\n if (source.isIndexable) {\n barrelFiles.push(file)\n\n break\n }\n }\n }\n\n const fileTypeCache = new Map<KubbFile.ResolvedFile, boolean>()\n for (const file of barrelFiles) {\n fileTypeCache.set(\n file,\n file.sources.every((source) => source.isTypeOnly),\n )\n }\n\n const exports: Array<KubbFile.Export> = []\n for (const file of barrelFiles) {\n const containsOnlyTypes = fileTypeCache.get(file) ?? false\n\n for (const source of file.sources) {\n if (!file.path || !source.isIndexable) {\n continue\n }\n\n exports.push({\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 }\n\n const entryFile = createFile({\n path: rootPath,\n baseName: 'index.ts',\n exports,\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 { definePlugin } from './definePlugin.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 = definePlugin<Options, ExtendOptions>({\n name: 'fs',\n install(ctx, options = {}) {\n if (options.clean) {\n fs.removeSync(options.clean.path)\n }\n\n ctx.on('file:processing:update', 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 await ctx.emit('lifecycle:end')\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 { definePlugin } from './definePlugin.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 = definePlugin<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('files:writing: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 http from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport { relative } from 'node:path'\nimport * as clack from '@clack/prompts'\nimport pc from 'picocolors'\nimport { WebSocket, WebSocketServer } from 'ws'\nimport type { FabricEvents } from '../Fabric.ts'\nimport type * as KubbFile from '../KubbFile.ts'\nimport { definePlugin } from './definePlugin.ts'\n\ntype Broadcast = <T = unknown>(event: keyof FabricEvents | string, payload: T) => void\ntype WebSocketOptions = {\n /**\n * Hostname to bind the websocket server to.\n * @default '127.0.0.1'\n */\n host?: string\n /**\n * Port to bind the websocket server to.\n * @default 0 (random available port)\n */\n port?: number\n}\n\ntype Options = {\n /**\n * Toggle progress bar output.\n * @default true\n */\n progress?: boolean\n /**\n * Toggle or configure the websocket broadcast server.\n * When `true`, a websocket server is started on an ephemeral port.\n * When `false`, websocket support is disabled.\n * When providing an object, the server uses the supplied host and port.\n * @default true\n */\n websocket?: boolean | WebSocketOptions\n}\n\nfunction normalizeAddress(address: AddressInfo): {\n host: string\n port: number\n} {\n const host = address.address === '::' ? '127.0.0.1' : address.address\n\n return { host, port: address.port }\n}\n\nfunction serializeFile(file: KubbFile.File | KubbFile.ResolvedFile) {\n return {\n path: file.path,\n baseName: file.baseName,\n name: 'name' in file ? file.name : undefined,\n extname: 'extname' in file ? file.extname : undefined,\n }\n}\n\nfunction pluralize(word: string, count: number) {\n return `${count} ${word}${count === 1 ? '' : 's'}`\n}\n\nconst DEFAULT_PROGRESS_BAR_SIZE = 30\n\nexport const loggerPlugin = definePlugin<Options>({\n name: 'logger',\n install(ctx, options = {}) {\n const { websocket = true, progress = true } = options\n\n const state = {\n spinner: clack.spinner(),\n isSpinning: false,\n progressBar: undefined as ReturnType<typeof clack.progress> | undefined,\n }\n\n function formatPath(path: string) {\n return relative(process.cwd(), path)\n }\n\n let server: http.Server | undefined\n let wss: WebSocketServer | undefined\n\n const broadcast: Broadcast = (event, payload) => {\n if (!wss) {\n return\n }\n\n const message = JSON.stringify({ event, payload })\n\n for (const client of wss.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(message)\n }\n }\n }\n\n if (websocket) {\n const { host = '127.0.0.1', port = 0 } = typeof websocket === 'boolean' ? {} : websocket\n\n server = http.createServer()\n wss = new WebSocketServer({ server })\n\n server.listen(port, host, () => {\n const addressInfo = server?.address()\n\n if (addressInfo && typeof addressInfo === 'object') {\n const { host: resolvedHost, port: resolvedPort } = normalizeAddress(addressInfo)\n const url = `ws://${resolvedHost}:${resolvedPort}`\n\n clack.log.info(`${pc.blue('ℹ')} Logger websocket listening on ${url}`)\n broadcast('websocket:ready', { url })\n }\n })\n\n wss.on('connection', (socket) => {\n clack.log.info(`${pc.blue('ℹ')} Logger websocket client connected`)\n socket.send(\n JSON.stringify({\n event: 'welcome',\n payload: {\n message: 'Connected to Fabric log stream',\n timestamp: Date.now(),\n },\n }),\n )\n })\n\n wss.on('error', (error) => {\n clack.log.error(`${pc.red('✗')} Logger websocket error: ${error.message}`)\n })\n }\n\n ctx.on('lifecycle:start', async () => {\n clack.intro(`${pc.blue('Fabric')} ${pc.dim('Starting run')}`)\n broadcast('lifecycle:start', { timestamp: Date.now() })\n })\n\n ctx.on('lifecycle:render', async () => {\n clack.log.info(`${pc.blue('ℹ')} Rendering application graph`)\n broadcast('lifecycle:render', { timestamp: Date.now() })\n })\n\n ctx.on('files:added', async (files) => {\n if (!files.length) {\n return\n }\n\n clack.log.info(`${pc.blue('ℹ')} Queued ${pluralize('file', files.length)}`)\n broadcast('files:added', {\n files: files.map(serializeFile),\n })\n })\n\n ctx.on('file:resolve:path', async (file) => {\n clack.log.step(`Resolving path for ${pc.dim(formatPath(file.path))}`)\n broadcast('file:resolve:path', { file: serializeFile(file) })\n })\n\n ctx.on('file:resolve:name', async (file) => {\n clack.log.step(`Resolving name for ${pc.dim(formatPath(file.path))}`)\n broadcast('file:resolve:name', { file: serializeFile(file) })\n })\n\n ctx.on('files:processing:start', async (files) => {\n clack.log.step(`Processing ${pc.green(pluralize('file', files.length))}`)\n broadcast('files:processing:start', {\n total: files.length,\n timestamp: Date.now(),\n })\n\n if (progress) {\n state.progressBar = clack.progress({\n style: 'block',\n max: files.length,\n size: DEFAULT_PROGRESS_BAR_SIZE,\n })\n state.progressBar.start(`Processing ${files.length} files`)\n }\n })\n\n ctx.on('file:processing:start', async (file, index, total) => {\n if (!state.progressBar) {\n clack.log.step(`Processing ${pc.dim(`[${index + 1}/${total}]`)} ${formatPath(file.path)}`)\n }\n\n broadcast('file:processing:start', {\n index,\n total,\n file: serializeFile(file),\n })\n })\n\n ctx.on('file:processing:update', async ({ processed, total, percentage, file }) => {\n broadcast('file:processing:update', {\n processed,\n total,\n percentage,\n file: serializeFile(file),\n })\n\n if (state.progressBar) {\n // undefined = auto-increment by 1\n state.progressBar.advance(undefined, `Writing ${formatPath(file.path)}`)\n } else {\n const formattedPercentage = Number.isFinite(percentage) ? percentage.toFixed(1) : '0.0'\n clack.log.step(`Progress ${pc.green(`${formattedPercentage}%`)} ${pc.dim(`(${processed}/${total})`)} → ${formatPath(file.path)}`)\n }\n })\n\n ctx.on('file:processing:end', async (file, index, total) => {\n if (state.progressBar) {\n state.progressBar.message(`${pc.green('✓')} Finished ${pc.dim(`[${index + 1}/${total}]`)} ${formatPath(file.path)}`)\n } else {\n clack.log.success(`${pc.green('✓')} Finished ${pc.dim(`[${index + 1}/${total}]`)} ${formatPath(file.path)}`)\n }\n\n broadcast('file:processing:end', {\n index,\n total,\n file: serializeFile(file),\n })\n })\n\n ctx.on('files:writing:start', async (files) => {\n broadcast('files:writing:start', {\n files: files.map(serializeFile),\n })\n })\n\n ctx.on('files:writing:end', async (files) => {\n broadcast('files:writing:end', {\n files: files.map(serializeFile),\n })\n })\n\n ctx.on('files:processing:end', async (files) => {\n if (state.progressBar) {\n state.progressBar.stop(`${pc.green('✓')} Processed ${pluralize('file', files.length)}`)\n state.progressBar = undefined\n } else {\n clack.log.success(`${pc.green('✓')} Processed ${pluralize('file', files.length)}`)\n }\n\n broadcast('files:processing:end', {\n total: files.length,\n timestamp: Date.now(),\n })\n })\n\n ctx.on('lifecycle:end', async () => {\n if (state.progressBar) {\n state.progressBar.stop()\n state.progressBar = undefined\n }\n\n clack.outro(`${pc.blue('Fabric')} ${pc.dim('completed')}`)\n\n broadcast('lifecycle:end', { timestamp: Date.now() })\n\n const closures: Array<Promise<void>> = []\n\n if (wss) {\n const wsServer = wss\n\n closures.push(\n new Promise((resolve) => {\n for (const client of wsServer.clients) {\n client.close()\n }\n wsServer.close(() => resolve())\n }),\n )\n }\n\n if (server) {\n const httpServer = server\n\n closures.push(\n new Promise((resolve) => {\n httpServer.close(() => resolve())\n }),\n )\n }\n\n if (closures.length) {\n await Promise.allSettled(closures)\n clack.log.info(`${pc.blue('ℹ')} Logger websocket closed`)\n }\n })\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAaA,IAAa,WAAb,MAAa,SAA0B;CAOrC,YAAY,MAAa,QAA0B;+CANnD;+CACA;+CACA,YAAmC,EAAE;wFACtB,IAAI,KAA8B;;AAI/C,OAAK,OAAO;AACZ,OAAK,SAAS;;CAGhB,SAAS,MAA8B;EACrC,MAAM,QAAQ,IAAI,SAAS,MAAM,KAAK;AACtC,OAAK,SAAS,KAAK,MAAM;AAEzB,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,UAAU,KACzD,kEAAiB,CAAC,IAAK,KAA0B,MAAM,MAAM;AAE/D,qEAAqB,OAAS;AAC9B,SAAO;;CAGT,eAAe,MAA2C;AACxD,qEAAO,KAAiB,CAAC,IAAI,KAAK;;CAGpC,IAAI,SAAiC;AACnC,mEAAI,KAAkB,CAAE,qEAAO,KAAkB;AACjD,MAAI,KAAK,SAAS,WAAW,EAAG,QAAO,CAAC,KAAK;EAE7C,MAAMA,SAAiC,EAAE;EACzC,MAAMC,QAAgC,CAAC,GAAG,KAAK,SAAS;EACxD,MAAM,0BAAU,IAAI,KAAsB;AAE1C,SAAO,MAAM,SAAS,GAAG;GACvB,MAAM,OAAO,MAAM,KAAK;AACxB,OAAI,QAAQ,IAAI,KAAK,CACnB;AAEF,WAAQ,IAAI,KAAK;AAEjB,OAAI,KAAK,SAAS,SAAS,EACzB,OAAM,KAAK,GAAG,KAAK,SAAS;OAE5B,QAAO,KAAK,KAAK;;AAIrB,qEAAqB,OAAM;AAC3B,SAAO;;CAGT,QAAQ,UAAiD;EACvD,MAAMA,QAAgC,CAAC,KAAK;AAE5C,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,OAAO,MAAM;AACnB,YAAS,KAAK;AAEd,OAAI,KAAK,SAAS,SAAS,EACzB,OAAM,KAAK,GAAG,KAAK,SAAS;;AAIhC,SAAO;;CAGT,SAAS,WAA4E;AACnF,OAAK,MAAM,QAAQ,KAAK,OACtB,KAAI,UAAU,KAAK,CAAE,QAAO;;CAKhC,OAAO,QAAQ,MAAmC;EAChD,MAAMC,QAA8C,EAAE;EACtD,MAAMC,QAA6C,EAAE;EAErD,MAAMC,QAAqC,CAAC,KAAK;AAEjD,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,OAAO,MAAM;AAEnB,SAAM,KAAK;IACT,IAAI,KAAK,KAAK;IACd,OAAO,KAAK,KAAK;IAClB,CAAC;GAEF,MAAM,WAAW,KAAK;AACtB,OAAI,SAAS,SAAS,EACpB,MAAK,IAAI,IAAI,GAAG,MAAM,SAAS,QAAQ,IAAI,KAAK,KAAK;IACnD,MAAM,QAAQ,SAAS;AACvB,UAAM,KAAK;KACT,MAAM,KAAK,KAAK;KAChB,IAAI,MAAM,KAAK;KAChB,CAAC;AACF,UAAM,KAAK,MAAM;;;AAKvB,SAAO;GAAE;GAAO;GAAO;;CAGzB,OAAO,UAAU,OAA6B,aAAa,IAAiC;EAC1F,MAAM,iBAAiB,MAAsB,EAAE,QAAQ,OAAO,IAAI;EAClE,MAAM,iBAAiB,cAAc,WAAW;EAChD,MAAM,aAAa,eAAe,SAAS,IAAI,GAAG,iBAAiB,GAAG,eAAe;EAErF,MAAM,kCAAkB,IAAI,KAA4B;EACxD,MAAMC,gBAAsC,EAAE;AAC9C,OAAK,MAAM,QAAQ,OAAO;;GACxB,MAAM,mCAAW,gBAAgB,IAAI,KAAK,uEAAI,cAAc,KAAK,KAAK;AACtE,mBAAgB,IAAI,MAAM,SAAS;AACnC,OAAI,CAAC,SAAS,SAAS,QAAQ,KAAK,CAAC,cAAc,SAAS,WAAW,WAAW,EAChF,eAAc,KAAK,KAAK;;AAI5B,MAAI,cAAc,WAAW,EAC3B,QAAO;EAGT,MAAM,WAAW,IAAI,SAAqB;GACxC,MAAM,cAAc;GACpB,MAAM,cAAc;GACpB,MAAM;GACP,CAAC;AAEF,OAAK,MAAM,QAAQ,eAAe;GAGhC,MAAM,QAFW,gBAAgB,IAAI,KAAK,CACjB,MAAM,WAAW,OAAO,CAC3B,MAAM,IAAI;GAEhC,IAAI,UAAU;GACd,IAAI,cAAc;AAElB,QAAK,MAAM,CAAC,OAAO,SAAS,MAAM,SAAS,EAAE;IAC3C,MAAM,SAAS,UAAU,MAAM,SAAS;AACxC,oBAAgB,YAAY,SAAS,IAAI,GAAG,KAAK,OAAO;IAExD,IAAI,OAAO,QAAQ,eAAe,KAAK;AAEvC,QAAI,CAAC,KACH,QAAO,QAAQ,SAAS;KACtB,MAAM;KACN,MAAM;KACN,MAAM,SAAS,OAAO;KACvB,CAAC;AAGJ,cAAU;;;AAId,SAAO;;;;;;ACvKX,SAAgB,aACd,QACgC;AAChC,QAAO;EACL,MAAM;EACN,GAAG;EACJ;;;;;;ACsCH,SAAgB,eAAe,EAAE,OAAO,MAAM,QAAqD;AAEjG,KAAI,SAAS,eAAe,SAAS,MACnC,QAAO,EAAE;CAGX,MAAM,sCAAsB,IAAI,KAA4C;AAE5E,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAMC,mBAA2C,EAAE;AACnD,OAAK,MAAM,UAAU,KAAK,WAAW,EAAE,CACrC,KAAI,OAAO,eAAe,OAAO,KAC/B,kBAAiB,KAAK,OAAO;AAGjC,MAAI,iBAAiB,SAAS,EAC5B,qBAAoB,IAAI,MAAM,iBAAiB;;CAInD,MAAM,8BAAc,IAAI,KAAmC;CAC3D,MAAM,yBAAS,IAAI,KAAiC;CAEpD,MAAM,WAAW,SAAS,UAAU,OAAO,KAAK;AAEhD,KAAI,CAAC,SACH,QAAO,EAAE;AAGX,UAAS,SAAS,SAAS;;AAEzB,MAAI,8CAAC,KAAM,aAAY,kBAAC,KAAK,oEAAQ,KAAK,MACxC;EAGF,MAAM,aAAa,KAAK,OAAO,KAAK;EACpC,MAAM,aAAaC,kBAAK,KAAK,YAAY,WAAW;EAEpD,IAAI,aAAa,YAAY,IAAI,WAAW;AAC5C,MAAI,CAAC,YAAY;AACf,gBAAaC,kCAAW;IACtB,MAAM;IACN,UAAU;IACV,SAAS,EAAE;IACX,SAAS,EAAE;IACZ,CAAC;AACF,eAAY,IAAI,YAAY,WAAW;AACvC,UAAO,IAAI,4BAAY,IAAI,KAAa,CAAC;;EAG3C,MAAM,OAAO,OAAO,IAAI,WAAW;AAEnC,OAAK,MAAM,QAAQ,KAAK,QAAQ;GAC9B,MAAM,OAAO,KAAK,KAAK;AACvB,OAAI,CAAC,QAAQ,CAAC,KAAK,KACjB;GAGF,MAAM,mBAAmB,oBAAoB,IAAI,KAAK;AACtD,OAAI,CAAC,iBACH;AAGF,QAAK,MAAM,UAAU,kBAAkB;IACrC,MAAM,MAAM,GAAG,OAAO,KAAK,GAAG,OAAO,aAAa,MAAM;AACxD,QAAI,KAAK,IAAI,IAAI,CACf;AAEF,SAAK,IAAI,IAAI;AAGb,eAAW,QAAS,KAAK;KACvB,MAAM,CAAC,OAAO,KAAM;KACpB,MAAMC,wCAAgB,YAAY,KAAK,KAAK;KAC5C,YAAY,OAAO;KACpB,CAAC;AAEF,eAAY,QAAQ,KAAK;KACvB,MAAM,OAAO;KACb,YAAY,OAAO;KACnB,OAAO;KACP,cAAc,SAAS,SAAS,SAAS;KACzC,aAAa,SAAS,SAAS,SAAS;KACzC,CAAC;;;GAGN;CAEF,MAAM,SAAS,CAAC,GAAG,YAAY,QAAQ,CAAC;AAExC,KAAI,SAAS,MACX,QAAO,OAAO,KAAK,SAAS;;SAAC;GAC3B,GAAG;GACH,0BAAS,KAAK,uEAAS,KAAK,OAAO;IAAE,GAAG;IAAG,MAAM;IAAW,EAAE;GAC/D;GAAE;AAGL,QAAO;;AAGT,MAAa,eAAe,aAAqC;CAC/D,MAAM;CACN,QAAQ,KAAK,SAAS;AACpB,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,uDAAuD;AAGzE,MAAI,CAAC,QAAQ,KACX;AAGF,MAAI,GAAG,uBAAuB,OAAO,UAAU;GAC7C,MAAM,OAAO,QAAQ;GACrB,MAAM,cAAc,eAAe;IAAE;IAAO;IAAM,MAAM,QAAQ;IAAM,CAAC;AAEvE,SAAM,IAAI,YAAY,IAAI,GAAG,YAAY;IACzC;;CAEJ,OAAO,KAAK,SAAS;AACnB,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,uDAAuD;AAGzE,SAAO,EACL,MAAM,WAAW,EAAE,MAAM,QAAQ;AAC/B,OAAI,CAAC,QAAQ,SAAS,YACpB;GAGF,MAAM,WAAWF,kBAAK,QAAQ,MAAM,WAAW;GAE/C,MAAMG,cAA4C,EAAE;AACpD,QAAK,MAAM,QAAQ,IAAI,MACrB,MAAK,MAAM,UAAU,KAAK,QACxB,KAAI,OAAO,aAAa;AACtB,gBAAY,KAAK,KAAK;AAEtB;;GAKN,MAAM,gCAAgB,IAAI,KAAqC;AAC/D,QAAK,MAAM,QAAQ,YACjB,eAAc,IACZ,MACA,KAAK,QAAQ,OAAO,WAAW,OAAO,WAAW,CAClD;GAGH,MAAMC,YAAkC,EAAE;AAC1C,QAAK,MAAM,QAAQ,aAAa;;IAC9B,MAAM,0CAAoB,cAAc,IAAI,KAAK,mEAAI;AAErD,SAAK,MAAM,UAAU,KAAK,SAAS;AACjC,SAAI,CAAC,KAAK,QAAQ,CAAC,OAAO,YACxB;AAGF,eAAQ,KAAK;MACX,MAAM,SAAS,QAAQ,SAAY,CAAC,OAAO,KAAK;MAChD,MAAMF,wCAAgB,UAAU,KAAK,KAAK;MAC1C,YAAY,SAAS,QAAQ,oBAAoB,OAAO;MACzD,CAAoB;;;GAIzB,MAAM,YAAYD,kCAAW;IAC3B,MAAM;IACN,UAAU;IACV;IACA,SAAS,EAAE;IACZ,CAAC;AAEF,SAAM,IAAI,QAAQ,UAAU;AAE5B,SAAM,IAAI,YAAY,MAAM;IAC1B,MAAM,IAAI,OAAO;IACjB,QAAQ,QAAQ;IAChB,SAAS,IAAI;IACd,CAAC;KAEL;;CAEJ,CAAC;;;;AC7MF,eAAsB,MAAM,QAAc,MAA0B,UAAgC,EAAE,EAA+B;AACnI,KAAI,OAAO,QAAQ,aAAa;AAC9B,MAAI,CAAC,qDAAQ,KAAM,MAAM,MAAK,GAC5B;AAGF,QAAM,IAAI,6BAAcI,OAAK,EAAE,KAAK,MAAM,CAAC;AAE3C,wDAAI,QAAS,QAAQ;GAEnB,MAAM,YAAY,MADL,IAAI,4BAAaA,OAAK,CAAC,CACP,MAAM;AAEnC,8DAAI,UAAW,UAAU,mDAAK,KAAM,UAAU,EAC5C,OAAM,IAAI,MAAM,2BAA2BA,OAAK,WAAW,KAAK,OAAO,MAAM,KAAK,YAAY,UAAU,OAAO,MAAM,UAAU,IAAI;AAGrI,UAAO;;AAGT,SAAO;;AAGT,KAAI,CAAC,qDAAQ,KAAM,MAAM,MAAK,GAC5B;AAGF,KAAI;EACF,MAAM,aAAa,MAAMC,iBAAG,gCAAiBD,OAAK,EAAE,EAClD,UAAU,SACX,CAAC;AACF,+DAAI,WAAY,UAAU,mDAAK,KAAM,UAAU,EAC7C;UAEK,MAAM;AAIf,OAAMC,iBAAG,kCAAmBD,OAAK,EAAE,KAAK,MAAM,EAAE,EAAE,UAAU,SAAS,CAAC;AAEtE,uDAAI,QAAS,QAAQ;EACnB,MAAM,YAAY,MAAMC,iBAAG,gCAAiBD,OAAK,EAAE,EACjD,UAAU,SACX,CAAC;AAEF,6DAAI,UAAW,UAAU,mDAAK,KAAM,UAAU,EAC5C,OAAM,IAAI,MAAM,2BAA2BA,OAAK,WAAW,KAAK,OAAO,MAAM,KAAK,YAAY,UAAU,OAAO,MAAM,UAAU,IAAI;AAGrI,SAAO;;AAGT,QAAO;;AAWT,MAAa,WAAW,aAAqC;CAC3D,MAAM;CACN,QAAQ,KAAK,UAAU,EAAE,EAAE;AACzB,MAAI,QAAQ,MACV,kBAAG,WAAW,QAAQ,MAAM,KAAK;AAGnC,MAAI,GAAG,0BAA0B,OAAO,EAAE,MAAM,aAAa;AAC3D,OAAI,QAAQ,cACV,OAAM,QAAQ,cAAc,KAAK,MAAM,OAAO;AAEhD,SAAM,MAAM,KAAK,MAAM,QAAQ,EAAE,QAAQ,OAAO,CAAC;IACjD;;CAEJ,OAAO,KAAK,EAAE,WAAW,EAAE,EAAE;AAC3B,SAAO,EACL,MAAM,MACJ,UAAU,EACR,WAAW,EAAE,OAAO,OAAO,EAC5B,EACD;AACA,SAAM,IAAI,YAAY,MAAM;IAC1B,MAAM,IAAI,OAAO;IACjB,WAAW,QAAQ;IACnB;IACA,SAAS,IAAI;IACd,CAAC;AAEF,SAAM,IAAI,KAAK,gBAAgB;KAElC;;CAEJ,CAAC;;;;ACrHF,MAAM,YAAY,KAAa,SAAqC;AAClE,QAAO,IAAI,SAAS,cAAY;AAO9B,gCANsB,KAAK,MAAM;GAC/B,UAAU;GACV,OAAO;GACP,aAAa;GACd,CAAC,CAEM,GAAG,UAAU,SAAS;AAC5B,aAAQ,CAAC,KAAK;IACd;GACF;;AAOJ,eAAsB,KAAK,QAAc,SAAqC;CAC5E,MAAM,wDAAM,QAAS;AAErB,KAAI,QAAQ,aAAa,QACvB,QAAO,SAAS,WAAW;EAAC;EAAM;EAAS,OAAO;EAAIE,OAAK,QAAQ,SAAS,MAAM;EAAC,CAAC;AAGtF,KAAI,QAAQ,aAAa,QACvB,QAAO,SAAS,OAAO,YAAY,CAACA,OAAK,CAAC;AAE5C,KAAI,QAAQ,aAAa,SACvB,QAAO,SAAS,QAAQ,MAAM;EAAC;EAAM;EAAKA;EAAK,GAAG,CAACA,OAAK,CAAC;AAG3D,OAAM,IAAI,MAAM,yCAAyCA,OAAK,GAAG;;;;;ACXnE,SAAgB,SAAS,EAAE,OAAO,QAA4C;CAC5E,MAAM,WAAW,SAAS,UAAU,OAAO,KAAK;AAEhD,KAAI,CAAC,SACH;AAGF,QAAO,SAAS,QAAQ,SAAS;;AAEnC,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCb,eAAe,MAAM,MAAc;CACjC,MAAM,SAASC,kBAAK,cAAc,KAAK,QAAQ;AAC7C,oCAAe,KAAK,KAAK;GACvB,QAAQ;GACR,WAAW;GACZ,CAAC;GACF;AAEF,QAAO,OAAO,GAAG,YAAY;EAC3B,MAAM,EAAE,SAAS,OAAO,SAAS;AACjC,UAAQ,IAAI,+BAA+B,KAAK,aAAa;AAE7D,QAAM,KAAK,oBAAoB,KAAK,aAAa;GACjD;;AAGJ,MAAa,cAAc,aAAsB;CAC/C,MAAM;CACN,QAAQ,KAAK,SAAS;AACpB,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,sDAAsD;AAGxE,MAAI,GAAG,uBAAuB,OAAO,UAAU;GAC7C,MAAM,OAAO,QAAQ;GAErB,MAAM,QAAQ,SAAS;IAAE;IAAO;IAAM,CAAC;AAEvC,OAAI,CAAC,MACH;GAGF,MAAM,YAAYC,kCAAW;IAC3B,UAAU;IACV,MAAMC,kBAAK,KAAK,MAAM,aAAa;IACnC,SAAS,CACP;KACE,MAAM;KACN,OAAO,KAAK,UAAU,OAAO,MAAM,EAAE;KACtC,CACF;IACF,CAAC;GAEF,MAAM,gBAAgBD,kCAAW;IAC/B,UAAU;IACV,MAAMC,kBAAK,KAAK,MAAM,aAAa;IACnC,SAAS,CACP;KACE,MAAM;KACN,OAAO;KACR,CACF;IACF,CAAC;AAEF,SAAM,IAAI,QAAQ,WAAW,cAAc;AAE3C,OAAI,QAAQ,KACV,OAAM,MAAM,KAAK;IAEnB;;CAEL,CAAC;;;;AC3FF,SAAS,iBAAiB,SAGxB;AAGA,QAAO;EAAE,MAFI,QAAQ,YAAY,OAAO,cAAc,QAAQ;EAE/C,MAAM,QAAQ;EAAM;;AAGrC,SAAS,cAAc,MAA6C;AAClE,QAAO;EACL,MAAM,KAAK;EACX,UAAU,KAAK;EACf,MAAM,UAAU,OAAO,KAAK,OAAO;EACnC,SAAS,aAAa,OAAO,KAAK,UAAU;EAC7C;;AAGH,SAAS,UAAU,MAAc,OAAe;AAC9C,QAAO,GAAG,MAAM,GAAG,OAAO,UAAU,IAAI,KAAK;;AAG/C,MAAM,4BAA4B;AAElC,MAAa,eAAe,aAAsB;CAChD,MAAM;CACN,QAAQ,KAAK,UAAU,EAAE,EAAE;EACzB,MAAM,EAAE,YAAY,MAAM,WAAW,SAAS;EAE9C,MAAM,QAAQ;GACZ,SAASC,eAAM,SAAS;GACxB,YAAY;GACZ,aAAa;GACd;EAED,SAAS,WAAW,QAAc;AAChC,kCAAgB,QAAQ,KAAK,EAAEC,OAAK;;EAGtC,IAAIC;EACJ,IAAIC;EAEJ,MAAMC,aAAwB,OAAO,YAAY;AAC/C,OAAI,CAAC,IACH;GAGF,MAAM,UAAU,KAAK,UAAU;IAAE;IAAO;IAAS,CAAC;AAElD,QAAK,MAAM,UAAU,IAAI,QACvB,KAAI,OAAO,eAAeC,aAAU,KAClC,QAAO,KAAK,QAAQ;;AAK1B,MAAI,WAAW;GACb,MAAM,EAAE,OAAO,aAAa,OAAO,MAAM,OAAO,cAAc,YAAY,EAAE,GAAG;AAE/E,YAASC,kBAAK,cAAc;AAC5B,SAAM,IAAIC,mBAAgB,EAAE,QAAQ,CAAC;AAErC,UAAO,OAAO,MAAM,YAAY;IAC9B,MAAM,8DAAc,OAAQ,SAAS;AAErC,QAAI,eAAe,OAAO,gBAAgB,UAAU;KAClD,MAAM,EAAE,MAAM,cAAc,MAAM,iBAAiB,iBAAiB,YAAY;KAChF,MAAM,MAAM,QAAQ,aAAa,GAAG;AAEpC,oBAAM,IAAI,KAAK,GAAGC,mBAAG,KAAK,IAAI,CAAC,iCAAiC,MAAM;AACtE,eAAU,mBAAmB,EAAE,KAAK,CAAC;;KAEvC;AAEF,OAAI,GAAG,eAAe,WAAW;AAC/B,mBAAM,IAAI,KAAK,GAAGA,mBAAG,KAAK,IAAI,CAAC,oCAAoC;AACnE,WAAO,KACL,KAAK,UAAU;KACb,OAAO;KACP,SAAS;MACP,SAAS;MACT,WAAW,KAAK,KAAK;MACtB;KACF,CAAC,CACH;KACD;AAEF,OAAI,GAAG,UAAU,UAAU;AACzB,mBAAM,IAAI,MAAM,GAAGA,mBAAG,IAAI,IAAI,CAAC,2BAA2B,MAAM,UAAU;KAC1E;;AAGJ,MAAI,GAAG,mBAAmB,YAAY;AACpC,kBAAM,MAAM,GAAGA,mBAAG,KAAK,SAAS,CAAC,GAAGA,mBAAG,IAAI,eAAe,GAAG;AAC7D,aAAU,mBAAmB,EAAE,WAAW,KAAK,KAAK,EAAE,CAAC;IACvD;AAEF,MAAI,GAAG,oBAAoB,YAAY;AACrC,kBAAM,IAAI,KAAK,GAAGA,mBAAG,KAAK,IAAI,CAAC,8BAA8B;AAC7D,aAAU,oBAAoB,EAAE,WAAW,KAAK,KAAK,EAAE,CAAC;IACxD;AAEF,MAAI,GAAG,eAAe,OAAO,UAAU;AACrC,OAAI,CAAC,MAAM,OACT;AAGF,kBAAM,IAAI,KAAK,GAAGA,mBAAG,KAAK,IAAI,CAAC,UAAU,UAAU,QAAQ,MAAM,OAAO,GAAG;AAC3E,aAAU,eAAe,EACvB,OAAO,MAAM,IAAI,cAAc,EAChC,CAAC;IACF;AAEF,MAAI,GAAG,qBAAqB,OAAO,SAAS;AAC1C,kBAAM,IAAI,KAAK,sBAAsBA,mBAAG,IAAI,WAAW,KAAK,KAAK,CAAC,GAAG;AACrE,aAAU,qBAAqB,EAAE,MAAM,cAAc,KAAK,EAAE,CAAC;IAC7D;AAEF,MAAI,GAAG,qBAAqB,OAAO,SAAS;AAC1C,kBAAM,IAAI,KAAK,sBAAsBA,mBAAG,IAAI,WAAW,KAAK,KAAK,CAAC,GAAG;AACrE,aAAU,qBAAqB,EAAE,MAAM,cAAc,KAAK,EAAE,CAAC;IAC7D;AAEF,MAAI,GAAG,0BAA0B,OAAO,UAAU;AAChD,kBAAM,IAAI,KAAK,cAAcA,mBAAG,MAAM,UAAU,QAAQ,MAAM,OAAO,CAAC,GAAG;AACzE,aAAU,0BAA0B;IAClC,OAAO,MAAM;IACb,WAAW,KAAK,KAAK;IACtB,CAAC;AAEF,OAAI,UAAU;AACZ,UAAM,cAAcR,eAAM,SAAS;KACjC,OAAO;KACP,KAAK,MAAM;KACX,MAAM;KACP,CAAC;AACF,UAAM,YAAY,MAAM,cAAc,MAAM,OAAO,QAAQ;;IAE7D;AAEF,MAAI,GAAG,yBAAyB,OAAO,MAAM,OAAO,UAAU;AAC5D,OAAI,CAAC,MAAM,YACT,gBAAM,IAAI,KAAK,cAAcQ,mBAAG,IAAI,IAAI,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,WAAW,KAAK,KAAK,GAAG;AAG5F,aAAU,yBAAyB;IACjC;IACA;IACA,MAAM,cAAc,KAAK;IAC1B,CAAC;IACF;AAEF,MAAI,GAAG,0BAA0B,OAAO,EAAE,WAAW,OAAO,YAAY,WAAW;AACjF,aAAU,0BAA0B;IAClC;IACA;IACA;IACA,MAAM,cAAc,KAAK;IAC1B,CAAC;AAEF,OAAI,MAAM,YAER,OAAM,YAAY,QAAQ,QAAW,WAAW,WAAW,KAAK,KAAK,GAAG;QACnE;IACL,MAAM,sBAAsB,OAAO,SAAS,WAAW,GAAG,WAAW,QAAQ,EAAE,GAAG;AAClF,mBAAM,IAAI,KAAK,YAAYA,mBAAG,MAAM,GAAG,oBAAoB,GAAG,CAAC,GAAGA,mBAAG,IAAI,IAAI,UAAU,GAAG,MAAM,GAAG,CAAC,KAAK,WAAW,KAAK,KAAK,GAAG;;IAEnI;AAEF,MAAI,GAAG,uBAAuB,OAAO,MAAM,OAAO,UAAU;AAC1D,OAAI,MAAM,YACR,OAAM,YAAY,QAAQ,GAAGA,mBAAG,MAAM,IAAI,CAAC,YAAYA,mBAAG,IAAI,IAAI,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,WAAW,KAAK,KAAK,GAAG;OAEpH,gBAAM,IAAI,QAAQ,GAAGA,mBAAG,MAAM,IAAI,CAAC,YAAYA,mBAAG,IAAI,IAAI,QAAQ,EAAE,GAAG,MAAM,GAAG,CAAC,GAAG,WAAW,KAAK,KAAK,GAAG;AAG9G,aAAU,uBAAuB;IAC/B;IACA;IACA,MAAM,cAAc,KAAK;IAC1B,CAAC;IACF;AAEF,MAAI,GAAG,uBAAuB,OAAO,UAAU;AAC7C,aAAU,uBAAuB,EAC/B,OAAO,MAAM,IAAI,cAAc,EAChC,CAAC;IACF;AAEF,MAAI,GAAG,qBAAqB,OAAO,UAAU;AAC3C,aAAU,qBAAqB,EAC7B,OAAO,MAAM,IAAI,cAAc,EAChC,CAAC;IACF;AAEF,MAAI,GAAG,wBAAwB,OAAO,UAAU;AAC9C,OAAI,MAAM,aAAa;AACrB,UAAM,YAAY,KAAK,GAAGA,mBAAG,MAAM,IAAI,CAAC,aAAa,UAAU,QAAQ,MAAM,OAAO,GAAG;AACvF,UAAM,cAAc;SAEpB,gBAAM,IAAI,QAAQ,GAAGA,mBAAG,MAAM,IAAI,CAAC,aAAa,UAAU,QAAQ,MAAM,OAAO,GAAG;AAGpF,aAAU,wBAAwB;IAChC,OAAO,MAAM;IACb,WAAW,KAAK,KAAK;IACtB,CAAC;IACF;AAEF,MAAI,GAAG,iBAAiB,YAAY;AAClC,OAAI,MAAM,aAAa;AACrB,UAAM,YAAY,MAAM;AACxB,UAAM,cAAc;;AAGtB,kBAAM,MAAM,GAAGA,mBAAG,KAAK,SAAS,CAAC,GAAGA,mBAAG,IAAI,YAAY,GAAG;AAE1D,aAAU,iBAAiB,EAAE,WAAW,KAAK,KAAK,EAAE,CAAC;GAErD,MAAMC,WAAiC,EAAE;AAEzC,OAAI,KAAK;IACP,MAAM,WAAW;AAEjB,aAAS,KACP,IAAI,SAAS,cAAY;AACvB,UAAK,MAAM,UAAU,SAAS,QAC5B,QAAO,OAAO;AAEhB,cAAS,YAAYC,WAAS,CAAC;MAC/B,CACH;;AAGH,OAAI,QAAQ;IACV,MAAM,aAAa;AAEnB,aAAS,KACP,IAAI,SAAS,cAAY;AACvB,gBAAW,YAAYA,WAAS,CAAC;MACjC,CACH;;AAGH,OAAI,SAAS,QAAQ;AACnB,UAAM,QAAQ,WAAW,SAAS;AAClC,mBAAM,IAAI,KAAK,GAAGF,mBAAG,KAAK,IAAI,CAAC,0BAA0B;;IAE3D;;CAEL,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import { f as Extname, o as Plugin, s as UserPlugin } from "./Fabric-BXYWK9V4.cjs";
2
- import { LogLevel } from "consola";
3
2
 
4
3
  //#region src/plugins/barrelPlugin.d.ts
5
4
  type Mode = 'all' | 'named' | 'propagate' | false;
@@ -84,10 +83,6 @@ type WebSocketOptions = {
84
83
  port?: number;
85
84
  };
86
85
  type Options = {
87
- /**
88
- * Explicit consola log level.
89
- */
90
- level?: LogLevel;
91
86
  /**
92
87
  * Toggle progress bar output.
93
88
  * @default true
package/dist/plugins.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { f as Extname, o as Plugin, s as UserPlugin } from "./Fabric-CDFwTDyP.js";
2
- import { LogLevel } from "consola";
3
2
 
4
3
  //#region src/plugins/barrelPlugin.d.ts
5
4
  type Mode = 'all' | 'named' | 'propagate' | false;
@@ -84,10 +83,6 @@ type WebSocketOptions = {
84
83
  port?: number;
85
84
  };
86
85
  type Options = {
87
- /**
88
- * Explicit consola log level.
89
- */
90
- level?: LogLevel;
91
86
  /**
92
87
  * Toggle progress bar output.
93
88
  * @default true