@xylabs/readme-gen 5.0.84 → 5.0.87

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/README.md CHANGED
@@ -15,6 +15,8 @@
15
15
 
16
16
  Base functionality used throughout XY Labs TypeScript/JavaScript libraries
17
17
 
18
+
19
+
18
20
  ## Reference
19
21
 
20
22
  **@xylabs/readme-gen**
@@ -23,7 +25,9 @@ Base functionality used throughout XY Labs TypeScript/JavaScript libraries
23
25
 
24
26
  ## Functions
25
27
 
26
- - [generateReadmeFiles](#functions/generateReadmeFiles)
28
+ | Function | Description |
29
+ | ------ | ------ |
30
+ | [generateReadmeFiles](#functions/generateReadmeFiles) | Generates README.md files for all workspace packages using a shared template. Fills each README with package metadata, an optional body, and auto-generated TypeDoc reference. |
27
31
 
28
32
  ### functions
29
33
 
@@ -34,12 +38,18 @@ Base functionality used throughout XY Labs TypeScript/JavaScript libraries
34
38
  ***
35
39
 
36
40
  ```ts
37
- function generateReadmeFiles(): Promise<void>;
41
+ function generateReadmeFiles(customTemplatePath?: string): Promise<void>;
38
42
  ```
39
43
 
40
44
  Generates README.md files for all workspace packages using a shared template.
41
45
  Fills each README with package metadata, an optional body, and auto-generated TypeDoc reference.
42
46
 
47
+ ## Parameters
48
+
49
+ | Parameter | Type |
50
+ | ------ | ------ |
51
+ | `customTemplatePath?` | `string` |
52
+
43
53
  ## Returns
44
54
 
45
55
  `Promise`\<`void`\>
@@ -3,5 +3,5 @@
3
3
  * Generates README.md files for all workspace packages using a shared template.
4
4
  * Fills each README with package metadata, an optional body, and auto-generated TypeDoc reference.
5
5
  */
6
- export declare function generateReadmeFiles(): Promise<void>;
6
+ export declare function generateReadmeFiles(customTemplatePath?: string): Promise<void>;
7
7
  //# sourceMappingURL=generateReadmeFiles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateReadmeFiles.d.ts","sourceRoot":"","sources":["../../src/generateReadmeFiles.ts"],"names":[],"mappings":";AAoDA;;;GAGG;AACH,wBAAsB,mBAAmB,kBAuBxC"}
1
+ {"version":3,"file":"generateReadmeFiles.d.ts","sourceRoot":"","sources":["../../src/generateReadmeFiles.ts"],"names":[],"mappings":";AAoDA;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,MAAM,iBAuBpE"}
@@ -1 +1 @@
1
- {"version":3,"file":"generateTypeDoc.d.ts","sourceRoot":"","sources":["../../src/generateTypeDoc.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,mBAoEnF"}
1
+ {"version":3,"file":"generateTypeDoc.d.ts","sourceRoot":"","sources":["../../src/generateTypeDoc.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,mBAkFnF"}
@@ -43,7 +43,21 @@ async function generateTypeDoc(packageLocation, entryPoints) {
43
43
  excludeExternals: true,
44
44
  excludeInternal: true,
45
45
  excludePrivate: true,
46
- sort: ["source-order"]
46
+ sort: ["source-order"],
47
+ expandObjects: true,
48
+ expandParameters: true,
49
+ parametersFormat: "table",
50
+ propertiesFormat: "table",
51
+ enumMembersFormat: "table",
52
+ typeDeclarationFormat: "table",
53
+ indexFormat: "table",
54
+ tableColumnSettings: {
55
+ hideDefaults: false,
56
+ hideInherited: false,
57
+ hideModifiers: false,
58
+ hideOverrides: false,
59
+ hideSources: true
60
+ }
47
61
  };
48
62
  const typedocJsonPath = path.join(tempDir, "typedoc.json");
49
63
  await writeFile(typedocJsonPath, JSON.stringify(typedocConfig, null, 2));
@@ -140,8 +154,8 @@ async function tryLoadReadmeReference(location) {
140
154
  return;
141
155
  }
142
156
  }
143
- async function generateReadmeFiles() {
144
- const template = await readFile(templatePath(), "utf8");
157
+ async function generateReadmeFiles(customTemplatePath) {
158
+ const template = await readFile(customTemplatePath ?? templatePath(), "utf8");
145
159
  const pkgs = yarnWorkspaces();
146
160
  for (const { location } of pkgs) {
147
161
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/generateReadmeFiles.ts","../../src/generateTypeDoc.ts"],"sourcesContent":["#!/usr/bin/env node\n/* eslint-disable no-console */\n\n// generate-readmes.mjs\nimport { readFile, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { yarnWorkspaces } from '@xylabs/ts-scripts-yarn3'\n\nimport { generateTypeDoc } from './generateTypeDoc.ts'\n\nconst dirName = () => path.dirname(fileURLToPath(import.meta.url))\nconst templatePath = () => path.join(dirName(), 'README.template.md')\n\n/**\n * Replaces `{{key}}` placeholders in a template string with values from the data object.\n * @param template - The template string containing `{{key}}` placeholders\n * @param data - A key-value map of replacement values\n * @returns The template with all placeholders replaced\n */\nfunction fillTemplate(template: string, data: { [key: string]: string }) {\n const additionalData: { [key: string]: string } = { ...data, safeName: data.name.replaceAll('/', '__').replaceAll('@', '') }\n return template.replaceAll(/{{(.*?)}}/g, (_, key) => additionalData[(key as string).trim()] ?? '')\n}\n\n/**\n * Attempts to load a `README.body.md` file from the given package location.\n * @param location - The package directory path\n * @returns The file contents, or undefined if the file does not exist\n */\nasync function tryLoadReadmeBody(location: string) {\n try {\n return await readFile(path.join(location, 'README.body.md'), 'utf8')\n } catch {\n return\n }\n}\n\n/**\n * Attempts to load a `README.reference.md` file from the given package location.\n * @param location - The package directory path\n * @returns The file contents, or undefined if the file does not exist\n */\nasync function tryLoadReadmeReference(location: string) {\n try {\n return await readFile(path.join(location, 'README.reference.md'), 'utf8')\n } catch {\n return\n }\n}\n\n/**\n * Generates README.md files for all workspace packages using a shared template.\n * Fills each README with package metadata, an optional body, and auto-generated TypeDoc reference.\n */\nexport async function generateReadmeFiles() {\n const template = await readFile(templatePath(), 'utf8')\n const pkgs = yarnWorkspaces()\n\n for (const { location } of pkgs) {\n try {\n if (location.includes('wallet-chrome')) {\n continue\n }\n const pkgJsonPath = path.join(location, 'package.json')\n const pkg = JSON.parse(await readFile(pkgJsonPath, 'utf8'))\n const body = await tryLoadReadmeBody(location) ?? ''\n const reference = await tryLoadReadmeReference(location) ?? await generateTypeDoc(location, ['src/index*.ts'])\n const readmeContent = fillTemplate(template, {\n ...pkg, body, reference,\n })\n await writeFile(path.join(location, 'README.md'), readmeContent)\n console.log(`✅ Created README.md for ${pkg.name}`)\n } catch (ex) {\n const error = ex as Error\n console.warn(`⚠️ Skipped ${location}:`, error.message)\n }\n }\n}\n","/* eslint-disable no-console */\nimport { execSync } from 'node:child_process'\nimport {\n existsSync, mkdirSync, readdirSync,\n readFileSync,\n} from 'node:fs'\nimport { rm, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n/**\n * Generates inline TypeDoc markdown documentation\n * @param {string} packageLocation - The package location path\n * @param {string} sourceGlob - The glob pattern for source files\n * @returns {Promise<string>} A markdown string containing Reference\n */\nexport async function generateTypeDoc(packageLocation: string, entryPoints: string[]) {\n const __dirname = path.dirname(fileURLToPath(import.meta.url))\n const tempDir = path.join(__dirname, '.temp-typedoc')\n\n console.log(`Generating TypeDoc for package at: ${packageLocation}`)\n for (const ep of entryPoints) {\n console.log(` - Entry point: ${path.resolve(packageLocation, ep)}`)\n }\n\n try {\n // Create temp directory if it doesn't exist\n if (!existsSync(tempDir)) {\n mkdirSync(tempDir, { recursive: true })\n }\n\n // Create a minimal TypeDoc config for markdown generation\n const typedocConfig = {\n entryPoints: entryPoints.map(ep => path.resolve(packageLocation, ep)),\n entryPointStrategy: 'expand',\n out: tempDir,\n plugin: ['typedoc-plugin-markdown'],\n readme: 'none',\n theme: 'markdown',\n useCodeBlocks: true,\n hidePageTitle: true,\n githubPages: false,\n hideGenerator: true,\n hideBreadcrumbs: true,\n disableSources: true,\n skipErrorChecking: true,\n excludeExternals: true,\n excludeInternal: true,\n excludePrivate: true,\n sort: ['source-order'],\n }\n\n // Create temporary typedoc.json file\n const typedocJsonPath = path.join(tempDir, 'typedoc.json')\n await writeFile(typedocJsonPath, JSON.stringify(typedocConfig, null, 2))\n\n // Run TypeDoc with the config\n try {\n console.log(`Generating docs for: ${packageLocation}`)\n execSync(`npx typedoc --options ${typedocJsonPath}`, {\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n } catch (ex) {\n const error = ex as Error\n console.error(`TypeDoc error: ${error.message}`)\n return '## Reference\\n\\nReference generation failed.'\n }\n\n // Combine all markdown files into a single document\n return consolidateMarkdown(tempDir)\n } catch (ex) {\n const error = ex as Error\n console.warn(`⚠️ Error generating TypeDoc for ${packageLocation}:`, error.message)\n return '## Reference\\n\\nReference generation failed.'\n } finally {\n // Clean up the temp directory\n try {\n await rm(tempDir, { recursive: true, force: true })\n } catch (ex) {\n const error = ex as Error\n console.warn('⚠️ Failed to clean up temp directory:', error.message)\n }\n }\n}\n\n/**\n * Consolidates all markdown files in the TypeDoc output directory into a single markdown string\n * @param {string} tempDir - The temporary directory containing TypeDoc output\n * @returns {string} - Consolidated markdown content\n */\nfunction consolidateMarkdown(tempDir: string) {\n // Start with the main README content\n let consolidated = '## Reference\\n\\n'\n\n // Read main README.md first (if it exists)\n const mainReadmePath = path.join(tempDir, 'README.md')\n if (existsSync(mainReadmePath)) {\n const mainContent = readFileSync(mainReadmePath, 'utf8')\n .replace(/^---(.|\\n)*?---\\n/, '') // Remove front matter\n .replace(/^# .+\\n/, '') // Remove top-level header\n .replaceAll(/\\]\\((.+?)\\.md\\)/g, '](#$1)') // Fix internal links to use anchors\n\n consolidated += mainContent + '\\n\\n'\n }\n\n // Function to process a directory recursively\n function processDirectory(dir: string, level = 0): string {\n const indent = ' '.repeat(level)\n let content = ''\n\n try {\n const items = readdirSync(dir, { withFileTypes: true })\n\n // Process files first\n for (const item of items) {\n const itemPath = path.join(dir, item.name)\n\n // Skip directories for now (process them later)\n if (item.isDirectory()) continue\n\n // Skip README.md (already processed) and files that aren't markdown\n if (item.name === 'README.md' || !item.name.endsWith('.md')) continue\n\n // Read file content\n const fileContent = readFileSync(itemPath, 'utf8')\n .replace(/^---(.|\\n)*?---\\n/, '') // Remove front matter\n\n // Get the module name from filename (without extension)\n const moduleName = item.name.replace('.md', '')\n\n // Create a header with anchor\n content += `\\n\\n${indent}### <a id=\"${moduleName}\"></a>${moduleName}\\n\\n`\n\n // Add file content with fixed links\n content += fileContent\n .replace(/^# .+\\n/, '') // Remove top-level header\n .replaceAll(/\\]\\((.+?)\\.md\\)/g, '](#$1)') // Fix internal links to use anchors\n }\n\n // Process subdirectories\n for (const item of items) {\n if (item.isDirectory()) {\n const subDirPath = path.join(dir, item.name)\n // Skip spec directories\n if (item.name === 'spec' || item.name.includes('.spec')) continue\n\n // Create a header for the directory\n content += `\\n\\n${indent}### ${item.name}\\n`\n\n // Process the subdirectory\n content += processDirectory(subDirPath, level + 1)\n }\n }\n } catch (ex) {\n const error = ex as Error\n console.warn(`⚠️ Error processing directory ${dir}:`, error.message)\n }\n\n return content\n }\n\n // Process all files in the tempDir\n consolidated += processDirectory(tempDir)\n\n // Clean up the markdown (fix duplicate headers, etc.)\n consolidated = consolidated\n .replaceAll(/\\n\\n\\n+/g, '\\n\\n') // Remove excess newlines\n .replaceAll(/^#### /gm, '### ') // Adjust heading levels\n .replaceAll(/^##### /gm, '#### ') // Adjust heading levels\n .replaceAll(/^###### /gm, '##### ') // Adjust heading levels\n\n return consolidated\n}\n"],"mappings":"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","names":["writeFile","path","fileURLToPath","path","fileURLToPath","writeFile"]}
1
+ {"version":3,"sources":["../../src/generateReadmeFiles.ts","../../src/generateTypeDoc.ts"],"sourcesContent":["#!/usr/bin/env node\n/* eslint-disable no-console */\n\n// generate-readmes.mjs\nimport { readFile, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport { yarnWorkspaces } from '@xylabs/ts-scripts-yarn3'\n\nimport { generateTypeDoc } from './generateTypeDoc.ts'\n\nconst dirName = () => path.dirname(fileURLToPath(import.meta.url))\nconst templatePath = () => path.join(dirName(), 'README.template.md')\n\n/**\n * Replaces `{{key}}` placeholders in a template string with values from the data object.\n * @param template - The template string containing `{{key}}` placeholders\n * @param data - A key-value map of replacement values\n * @returns The template with all placeholders replaced\n */\nfunction fillTemplate(template: string, data: { [key: string]: string }) {\n const additionalData: { [key: string]: string } = { ...data, safeName: data.name.replaceAll('/', '__').replaceAll('@', '') }\n return template.replaceAll(/{{(.*?)}}/g, (_, key) => additionalData[(key as string).trim()] ?? '')\n}\n\n/**\n * Attempts to load a `README.body.md` file from the given package location.\n * @param location - The package directory path\n * @returns The file contents, or undefined if the file does not exist\n */\nasync function tryLoadReadmeBody(location: string) {\n try {\n return await readFile(path.join(location, 'README.body.md'), 'utf8')\n } catch {\n return\n }\n}\n\n/**\n * Attempts to load a `README.reference.md` file from the given package location.\n * @param location - The package directory path\n * @returns The file contents, or undefined if the file does not exist\n */\nasync function tryLoadReadmeReference(location: string) {\n try {\n return await readFile(path.join(location, 'README.reference.md'), 'utf8')\n } catch {\n return\n }\n}\n\n/**\n * Generates README.md files for all workspace packages using a shared template.\n * Fills each README with package metadata, an optional body, and auto-generated TypeDoc reference.\n */\nexport async function generateReadmeFiles(customTemplatePath?: string) {\n const template = await readFile(customTemplatePath ?? templatePath(), 'utf8')\n const pkgs = yarnWorkspaces()\n\n for (const { location } of pkgs) {\n try {\n if (location.includes('wallet-chrome')) {\n continue\n }\n const pkgJsonPath = path.join(location, 'package.json')\n const pkg = JSON.parse(await readFile(pkgJsonPath, 'utf8'))\n const body = await tryLoadReadmeBody(location) ?? ''\n const reference = await tryLoadReadmeReference(location) ?? await generateTypeDoc(location, ['src/index*.ts'])\n const readmeContent = fillTemplate(template, {\n ...pkg, body, reference,\n })\n await writeFile(path.join(location, 'README.md'), readmeContent)\n console.log(`✅ Created README.md for ${pkg.name}`)\n } catch (ex) {\n const error = ex as Error\n console.warn(`⚠️ Skipped ${location}:`, error.message)\n }\n }\n}\n","/* eslint-disable no-console */\nimport { execSync } from 'node:child_process'\nimport {\n existsSync, mkdirSync, readdirSync,\n readFileSync,\n} from 'node:fs'\nimport { rm, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n/**\n * Generates inline TypeDoc markdown documentation\n * @param {string} packageLocation - The package location path\n * @param {string} sourceGlob - The glob pattern for source files\n * @returns {Promise<string>} A markdown string containing Reference\n */\nexport async function generateTypeDoc(packageLocation: string, entryPoints: string[]) {\n const __dirname = path.dirname(fileURLToPath(import.meta.url))\n const tempDir = path.join(__dirname, '.temp-typedoc')\n\n console.log(`Generating TypeDoc for package at: ${packageLocation}`)\n for (const ep of entryPoints) {\n console.log(` - Entry point: ${path.resolve(packageLocation, ep)}`)\n }\n\n try {\n // Create temp directory if it doesn't exist\n if (!existsSync(tempDir)) {\n mkdirSync(tempDir, { recursive: true })\n }\n\n // Create a minimal TypeDoc config for markdown generation\n const typedocConfig = {\n entryPoints: entryPoints.map(ep => path.resolve(packageLocation, ep)),\n entryPointStrategy: 'expand',\n out: tempDir,\n plugin: ['typedoc-plugin-markdown'],\n readme: 'none',\n theme: 'markdown',\n useCodeBlocks: true,\n hidePageTitle: true,\n githubPages: false,\n hideGenerator: true,\n hideBreadcrumbs: true,\n disableSources: true,\n skipErrorChecking: true,\n excludeExternals: true,\n excludeInternal: true,\n excludePrivate: true,\n sort: ['source-order'],\n expandObjects: true,\n expandParameters: true,\n parametersFormat: 'table',\n propertiesFormat: 'table',\n enumMembersFormat: 'table',\n typeDeclarationFormat: 'table',\n indexFormat: 'table',\n tableColumnSettings: {\n hideDefaults: false,\n hideInherited: false,\n hideModifiers: false,\n hideOverrides: false,\n hideSources: true,\n },\n }\n\n // Create temporary typedoc.json file\n const typedocJsonPath = path.join(tempDir, 'typedoc.json')\n await writeFile(typedocJsonPath, JSON.stringify(typedocConfig, null, 2))\n\n // Run TypeDoc with the config\n try {\n console.log(`Generating docs for: ${packageLocation}`)\n execSync(`npx typedoc --options ${typedocJsonPath}`, {\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n } catch (ex) {\n const error = ex as Error\n console.error(`TypeDoc error: ${error.message}`)\n return '## Reference\\n\\nReference generation failed.'\n }\n\n // Combine all markdown files into a single document\n return consolidateMarkdown(tempDir)\n } catch (ex) {\n const error = ex as Error\n console.warn(`⚠️ Error generating TypeDoc for ${packageLocation}:`, error.message)\n return '## Reference\\n\\nReference generation failed.'\n } finally {\n // Clean up the temp directory\n try {\n await rm(tempDir, { recursive: true, force: true })\n } catch (ex) {\n const error = ex as Error\n console.warn('⚠️ Failed to clean up temp directory:', error.message)\n }\n }\n}\n\n/**\n * Consolidates all markdown files in the TypeDoc output directory into a single markdown string\n * @param {string} tempDir - The temporary directory containing TypeDoc output\n * @returns {string} - Consolidated markdown content\n */\nfunction consolidateMarkdown(tempDir: string) {\n // Start with the main README content\n let consolidated = '## Reference\\n\\n'\n\n // Read main README.md first (if it exists)\n const mainReadmePath = path.join(tempDir, 'README.md')\n if (existsSync(mainReadmePath)) {\n const mainContent = readFileSync(mainReadmePath, 'utf8')\n .replace(/^---(.|\\n)*?---\\n/, '') // Remove front matter\n .replace(/^# .+\\n/, '') // Remove top-level header\n .replaceAll(/\\]\\((.+?)\\.md\\)/g, '](#$1)') // Fix internal links to use anchors\n\n consolidated += mainContent + '\\n\\n'\n }\n\n // Function to process a directory recursively\n function processDirectory(dir: string, level = 0): string {\n const indent = ' '.repeat(level)\n let content = ''\n\n try {\n const items = readdirSync(dir, { withFileTypes: true })\n\n // Process files first\n for (const item of items) {\n const itemPath = path.join(dir, item.name)\n\n // Skip directories for now (process them later)\n if (item.isDirectory()) continue\n\n // Skip README.md (already processed) and files that aren't markdown\n if (item.name === 'README.md' || !item.name.endsWith('.md')) continue\n\n // Read file content\n const fileContent = readFileSync(itemPath, 'utf8')\n .replace(/^---(.|\\n)*?---\\n/, '') // Remove front matter\n\n // Get the module name from filename (without extension)\n const moduleName = item.name.replace('.md', '')\n\n // Create a header with anchor\n content += `\\n\\n${indent}### <a id=\"${moduleName}\"></a>${moduleName}\\n\\n`\n\n // Add file content with fixed links\n content += fileContent\n .replace(/^# .+\\n/, '') // Remove top-level header\n .replaceAll(/\\]\\((.+?)\\.md\\)/g, '](#$1)') // Fix internal links to use anchors\n }\n\n // Process subdirectories\n for (const item of items) {\n if (item.isDirectory()) {\n const subDirPath = path.join(dir, item.name)\n // Skip spec directories\n if (item.name === 'spec' || item.name.includes('.spec')) continue\n\n // Create a header for the directory\n content += `\\n\\n${indent}### ${item.name}\\n`\n\n // Process the subdirectory\n content += processDirectory(subDirPath, level + 1)\n }\n }\n } catch (ex) {\n const error = ex as Error\n console.warn(`⚠️ Error processing directory ${dir}:`, error.message)\n }\n\n return content\n }\n\n // Process all files in the tempDir\n consolidated += processDirectory(tempDir)\n\n // Clean up the markdown (fix duplicate headers, etc.)\n consolidated = consolidated\n .replaceAll(/\\n\\n\\n+/g, '\\n\\n') // Remove excess newlines\n .replaceAll(/^#### /gm, '### ') // Adjust heading levels\n .replaceAll(/^##### /gm, '#### ') // Adjust heading levels\n .replaceAll(/^###### /gm, '##### ') // Adjust heading levels\n\n return consolidated\n}\n"],"mappings":"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","names":["writeFile","path","fileURLToPath","path","fileURLToPath","writeFile"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xylabs/readme-gen",
3
- "version": "5.0.84",
3
+ "version": "5.0.87",
4
4
  "description": "Base functionality used throughout XY Labs TypeScript/JavaScript libraries",
5
5
  "keywords": [
6
6
  "readme",
@@ -44,12 +44,12 @@
44
44
  "!**/*.test.*"
45
45
  ],
46
46
  "dependencies": {
47
- "@xylabs/ts-scripts-yarn3": "~7.4.13"
47
+ "@xylabs/ts-scripts-yarn3": "~7.4.24"
48
48
  },
49
49
  "devDependencies": {
50
- "@xylabs/tsconfig": "~7.4.13",
50
+ "@xylabs/tsconfig": "~7.4.24",
51
51
  "typescript": "~5.9.3",
52
- "vitest": "^4.0.18"
52
+ "vitest": "^4.1.0"
53
53
  },
54
54
  "engines": {
55
55
  "node": ">=18"