diff --git a/src/__tests__/__snapshots__/options.defaults.test.ts.snap b/src/__tests__/__snapshots__/options.defaults.test.ts.snap index 302b31a..9219708 100644 --- a/src/__tests__/__snapshots__/options.defaults.test.ts.snap +++ b/src/__tests__/__snapshots__/options.defaults.test.ts.snap @@ -1,84 +1,71 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`options defaults should return specific properties 1`] = ` +exports[`options defaults should return specific properties: defaults 1`] = ` { - "DEFAULT_OPTIONS": { - "contextPath": "/", - "docsHost": false, - "docsPath": "/documentation", - "http": { - "allowedHosts": [], - "allowedOrigins": [], - "host": "127.0.0.1", - "port": 8080, + "contextPath": "/", + "contextUrl": "file:///", + "docsHost": false, + "docsPath": "/documentation", + "http": { + "allowedHosts": [], + "allowedOrigins": [], + "host": "127.0.0.1", + "port": 8080, + }, + "isHttp": false, + "llmsFilesPath": "/llms-files", + "logging": { + "level": "info", + "logger": "@patternfly/patternfly-mcp", + "protocol": false, + "stderr": false, + "transport": "stdio", + }, + "name": "@patternfly/patternfly-mcp", + "nodeVersion": 22, + "pfExternal": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content", + "pfExternalAccessibility": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/accessibility", + "pfExternalChartsDesign": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/charts", + "pfExternalDesignComponents": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/components", + "pfExternalDesignLayouts": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/layouts", + "pfExternalExamplesCharts": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-charts/src/victory/components", + "pfExternalExamplesComponents": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-core/src/components", + "pfExternalExamplesLayouts": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-core/src/layouts", + "pfExternalExamplesTable": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-table/src/components", + "repoName": "patternfly-mcp", + "resourceMemoOptions": { + "default": { + "cacheLimit": 3, }, - "isHttp": false, - "llmsFilesPath": "/llms-files", - "logging": { - "level": "info", - "logger": "@patternfly/patternfly-mcp", - "protocol": false, - "stderr": false, - "transport": "stdio", + "fetchUrl": { + "cacheErrors": false, + "cacheLimit": 100, + "expire": 180000, }, - "name": "@patternfly/patternfly-mcp", - "pfExternal": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content", - "pfExternalAccessibility": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/accessibility", - "pfExternalChartsDesign": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/charts", - "pfExternalDesignComponents": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/components", - "pfExternalDesignLayouts": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/layouts", - "pfExternalExamplesCharts": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-charts/src/victory/components", - "pfExternalExamplesComponents": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-core/src/components", - "pfExternalExamplesLayouts": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-core/src/layouts", - "pfExternalExamplesTable": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-table/src/components", - "repoName": "patternfly-mcp", - "resourceMemoOptions": { - "default": { - "cacheLimit": 3, - }, - "fetchUrl": { - "cacheErrors": false, - "cacheLimit": 100, - "expire": 180000, - }, - "readFile": { - "cacheErrors": false, - "cacheLimit": 50, - "expire": 120000, - }, + "readFile": { + "cacheErrors": false, + "cacheLimit": 50, + "expire": 120000, }, - "separator": " + }, + "separator": " --- ", - "toolMemoOptions": { - "fetchDocs": { - "cacheErrors": false, - "cacheLimit": 15, - "expire": 60000, - }, - "usePatternFlyDocs": { - "cacheErrors": false, - "cacheLimit": 10, - "expire": 60000, - }, + "toolMemoOptions": { + "fetchDocs": { + "cacheErrors": false, + "cacheLimit": 15, + "expire": 60000, + }, + "usePatternFlyDocs": { + "cacheErrors": false, + "cacheLimit": 10, + "expire": 60000, }, - "urlRegex": /\\^\\(https\\?:\\)\\\\/\\\\//i, - "version": "0.0.0", }, - "LOG_BASENAME": "pf-mcp:log", - "PF_EXTERNAL": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content", - "PF_EXTERNAL_ACCESSIBILITY": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/accessibility", - "PF_EXTERNAL_CHARTS_DESIGN": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/charts", - "PF_EXTERNAL_DESIGN_COMPONENTS": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/components", - "PF_EXTERNAL_DESIGN_LAYOUTS": "https://raw.githubusercontent.com/patternfly/patternfly-org/fb05713aba75998b5ecf5299ee3c1a259119bd74/packages/documentation-site/patternfly-docs/content/design-guidelines/layouts", - "PF_EXTERNAL_EXAMPLES": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages", - "PF_EXTERNAL_EXAMPLES_CHARTS": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-charts/src/victory/components", - "PF_EXTERNAL_EXAMPLES_LAYOUTS": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-core/src/layouts", - "PF_EXTERNAL_EXAMPLES_REACT_CORE": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-core/src/components", - "PF_EXTERNAL_EXAMPLES_TABLE": "https://raw.githubusercontent.com/patternfly/patternfly-react/refs/tags/v6.4.0/packages/react-table/src/components", - "PF_EXTERNAL_EXAMPLES_VERSION": "v6.4.0", - "PF_EXTERNAL_VERSION": "fb05713aba75998b5ecf5299ee3c1a259119bd74", + "urlRegex": /\\^\\(https\\?:\\)\\\\/\\\\//i, + "version": "0.0.0", } `; diff --git a/src/__tests__/options.defaults.test.ts b/src/__tests__/options.defaults.test.ts index a31464d..3e5e254 100644 --- a/src/__tests__/options.defaults.test.ts +++ b/src/__tests__/options.defaults.test.ts @@ -1,7 +1,31 @@ -import * as options from '../options.defaults'; +import { DEFAULT_OPTIONS, getNodeMajorVersion } from '../options.defaults'; describe('options defaults', () => { it('should return specific properties', () => { - expect(options).toMatchSnapshot(); + expect(DEFAULT_OPTIONS).toMatchSnapshot('defaults'); + }); +}); + +describe('getNodeMajorVersion', () => { + it('should get the current Node.js version', () => { + // Purposeful failure in the event the process.versions.node value is not available + expect(getNodeMajorVersion()).not.toBe(0); + }); + + it.each([ + { + description: 'number', + value: 1_000_000 + }, + { + description: 'string', + value: 'lorem ipsum' + }, + { + description: 'null', + value: null + } + ])('should handle basic failure, $description', ({ value }) => { + expect(getNodeMajorVersion(value as any)).toBe(0); }); }); diff --git a/src/options.defaults.ts b/src/options.defaults.ts index 9275388..e35aa7a 100644 --- a/src/options.defaults.ts +++ b/src/options.defaults.ts @@ -1,13 +1,15 @@ -import { basename, join } from 'node:path'; +import { basename, join, resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; import packageJson from '../package.json'; /** - * Application defaults, not user-configurable + * Application defaults, not all fields are user-configurable * * @interface DefaultOptions * * @template TLogOptions The logging options type, defaulting to LoggingOptions. * @property contextPath - Current working directory. + * @property contextUrl - Current working directory URL. * @property docsHost - Flag indicating whether to use the docs-host. * @property docsPath - Path to the documentation directory. * @property isHttp - Flag indicating whether the server is running in HTTP mode. @@ -15,12 +17,13 @@ import packageJson from '../package.json'; * @property llmsFilesPath - Path to the LLMs files directory. * @property {LoggingOptions} logging - Logging options. * @property name - Name of the package. + * @property nodeVersion - Node.js major version. * @property repoName - Name of the repository. * @property pfExternal - PatternFly external docs URL. * @property pfExternalDesignComponents - PatternFly design guidelines' components' URL. * @property pfExternalExamplesComponents - PatternFly examples' core components' URL. * @property pfExternalExamplesLayouts - PatternFly examples' core layouts' URL. - * @property pfExternalExamplesCharts - PatternFly examples' charts' components' URL.' + * @property pfExternalExamplesCharts - PatternFly examples' charts' components' URL. * @property pfExternalExamplesTable - PatternFly examples' table components' URL. * @property pfExternalChartsDesign - PatternFly charts' design guidelines URL. * @property pfExternalDesignLayouts - PatternFly design guidelines' layouts' URL. @@ -33,6 +36,7 @@ import packageJson from '../package.json'; */ interface DefaultOptions { contextPath: string; + contextUrl: string; docsHost: boolean; docsPath: string; http: HttpOptions; @@ -40,6 +44,7 @@ interface DefaultOptions { llmsFilesPath: string; logging: TLogOptions; name: string; + nodeVersion: number; pfExternal: string; pfExternalDesignComponents: string; pfExternalExamplesComponents: string; @@ -253,6 +258,23 @@ const PF_EXTERNAL_ACCESSIBILITY = `${PF_EXTERNAL}/accessibility`; */ const PF_EXTERNAL_CHARTS_DESIGN = `${PF_EXTERNAL}/design-guidelines/charts`; +/** + * Get the current Node.js major version. + * + * @param nodeVersion + * @returns Node.js major version. + */ +const getNodeMajorVersion = (nodeVersion = process.versions.node) => { + const updatedNodeVersion = nodeVersion || '0.0.0'; + const major = Number.parseInt(updatedNodeVersion?.split?.('.')?.[0] || '0', 10); + + if (Number.isFinite(major)) { + return major; + } + + return 0; +}; + /** * Global default options. Base defaults before CLI/programmatic overrides. * @@ -260,13 +282,15 @@ const PF_EXTERNAL_CHARTS_DESIGN = `${PF_EXTERNAL}/design-guidelines/charts`; */ const DEFAULT_OPTIONS: DefaultOptions = { docsHost: false, - contextPath: (process.env.NODE_ENV === 'local' && '/') || process.cwd(), - docsPath: (process.env.NODE_ENV === 'local' && '/documentation') || join(process.cwd(), 'documentation'), + contextPath: (process.env.NODE_ENV === 'local' && '/') || resolve(process.cwd()), + contextUrl: pathToFileURL((process.env.NODE_ENV === 'local' && '/') || resolve(process.cwd())).href, + docsPath: (process.env.NODE_ENV === 'local' && '/documentation') || join(resolve(process.cwd()), 'documentation'), isHttp: false, http: HTTP_OPTIONS, - llmsFilesPath: (process.env.NODE_ENV === 'local' && '/llms-files') || join(process.cwd(), 'llms-files'), + llmsFilesPath: (process.env.NODE_ENV === 'local' && '/llms-files') || join(resolve(process.cwd()), 'llms-files'), logging: LOGGING_OPTIONS, name: packageJson.name, + nodeVersion: (process.env.NODE_ENV === 'local' && 22) || getNodeMajorVersion(), pfExternal: PF_EXTERNAL, pfExternalDesignComponents: PF_EXTERNAL_DESIGN_COMPONENTS, pfExternalExamplesComponents: PF_EXTERNAL_EXAMPLES_REACT_CORE, @@ -299,6 +323,7 @@ export { PF_EXTERNAL_ACCESSIBILITY, LOG_BASENAME, DEFAULT_OPTIONS, + getNodeMajorVersion, type DefaultOptions, type DefaultOptionsOverrides, type HttpOptions,