diff --git a/cli/__tests__/symLinkConfig.test.ts b/cli/__tests__/symLinkConfig.test.ts index e9f5152..de4f2ab 100644 --- a/cli/__tests__/symLinkConfig.test.ts +++ b/cli/__tests__/symLinkConfig.test.ts @@ -1,12 +1,15 @@ -import { symlink } from 'fs/promises' +import { symlink, rm } from 'fs/promises' import { symLinkConfig } from '../symLinkConfig' +import { fileExists } from '../fileExists' jest.mock('fs/promises') +jest.mock('../fileExists') // suppress console.log so that it doesn't clutter the test output jest.spyOn(console, 'log').mockImplementation(() => {}) -it('should create a symlink successfully', async () => { +it('should create a symlink successfully when one does not exist', async () => { + ;(fileExists as jest.Mock).mockResolvedValue(false) ;(symlink as jest.Mock).mockResolvedValue(undefined) await symLinkConfig('/astro', '/consumer') @@ -17,11 +20,36 @@ it('should create a symlink successfully', async () => { ) }) +it('should not try to remove a file that does not exist', async () => { + ;(fileExists as jest.Mock).mockResolvedValue(false) + ;(symlink as jest.Mock).mockResolvedValue(undefined) + + await symLinkConfig('/astro', '/consumer') + + expect(rm).not.toHaveBeenCalled() +}) + +it('should remove existing file before creating symlink', async () => { + ;(fileExists as jest.Mock).mockResolvedValue(true) + ;(rm as jest.Mock).mockResolvedValue(undefined) + ;(symlink as jest.Mock).mockResolvedValue(undefined) + + await symLinkConfig('/astro', '/consumer') + + expect(fileExists).toHaveBeenCalledWith('/astro/pf-docs.config.mjs') + expect(rm).toHaveBeenCalledWith('/astro/pf-docs.config.mjs') + expect(symlink).toHaveBeenCalledWith( + '/consumer/pf-docs.config.mjs', + '/astro/pf-docs.config.mjs', + ) +}) + it('should log an error if symlink creation fails', async () => { const consoleErrorSpy = jest .spyOn(console, 'error') .mockImplementation(() => {}) + ;(fileExists as jest.Mock).mockResolvedValue(false) const error = new Error('Symlink creation failed') ;(symlink as jest.Mock).mockRejectedValue(error) @@ -36,6 +64,9 @@ it('should log an error if symlink creation fails', async () => { it('should log a success message after creating the symlink', async () => { const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {}) + ;(fileExists as jest.Mock).mockResolvedValue(false) + ;(symlink as jest.Mock).mockResolvedValue(undefined) + await symLinkConfig('/astro', '/consumer') expect(consoleLogSpy).toHaveBeenCalledWith( diff --git a/cli/symLinkConfig.ts b/cli/symLinkConfig.ts index 9f267c0..0fd5559 100644 --- a/cli/symLinkConfig.ts +++ b/cli/symLinkConfig.ts @@ -1,21 +1,28 @@ /* eslint-disable no-console */ -import { symlink } from 'fs/promises' +import { symlink, rm } from 'fs/promises' +import { join } from 'path' +import { fileExists } from './fileExists.js' export async function symLinkConfig( astroRootDir: string, consumerRootDir: string, ) { const configFileName = '/pf-docs.config.mjs' - const docsConfigFile = consumerRootDir + configFileName + const defaultConfigFile = join(astroRootDir, configFileName) + const consumerConfigFile = consumerRootDir + configFileName + + if (await fileExists(defaultConfigFile)) { + await rm(defaultConfigFile) + } try { - await symlink(docsConfigFile, astroRootDir + configFileName) + await symlink(consumerConfigFile, defaultConfigFile) } catch (e: any) { console.error( - `Error creating symlink to ${docsConfigFile} in ${astroRootDir}`, + `Error creating symlink to ${consumerConfigFile} in ${astroRootDir}`, e, ) } finally { - console.log(`Symlink to ${docsConfigFile} in ${astroRootDir} created`) + console.log(`Symlink to ${consumerConfigFile} in ${astroRootDir} created`) } } diff --git a/pf-docs.config.mjs b/pf-docs.config.mjs index 549d4d0..02fde7a 100644 --- a/pf-docs.config.mjs +++ b/pf-docs.config.mjs @@ -11,12 +11,20 @@ export const config = { // example content entry for remote content, this would fetch all markdown files matching the glob in 'pattern' // from the specified npm package and serve them with a content identifier of 'react-component-docs': { - packageName: "@patternfly/react-core", - pattern: "**/components/**/*.md", - name: "react-component-docs", + packageName: '@patternfly/react-core', + pattern: '**/components/**/*.md', + name: 'react-component-docs', + }, + { + packageName: '@patternfly/patternfly', + pattern: '*/**/*.md', + name: 'core-docs', + }, + { + packageName: '@patternfly/quickstarts', + pattern: '*/patternfly-docs/**/*.md', + name: 'quickstarts-docs', }, - { packageName: "@patternfly/patternfly", pattern: "*/**/*.md", name: "core-docs" }, - { packageName: "@patternfly/quickstarts", pattern: "*/patternfly-docs/**/*.md", name: "quickstarts-docs" }, ], outputDir: './dist', propsGlobs: [ @@ -30,11 +38,6 @@ export const config = { ], }, ], - // Add custom scope items for LiveExample component - // These will be available in your example code blocks - // Example: - // scope: { - // MyCustomComponent: () =>
Custom
, - // myUtilFunction: (x) => x * 2, - // }, + navSectionOrder: ['get-started', 'design-foundations'], + scope: {}, } diff --git a/src/components/LiveExample.astro b/src/components/LiveExample.astro index 6792c36..bb28e52 100644 --- a/src/components/LiveExample.astro +++ b/src/components/LiveExample.astro @@ -1,8 +1,7 @@ --- import { LiveExample as LiveExampleBase } from './LiveExample' -import { config } from '../pf-docs.config.mjs' const { src, html } = Astro.props --- - + diff --git a/src/components/LiveExample.tsx b/src/components/LiveExample.tsx index ccbace0..3f2eae7 100644 --- a/src/components/LiveExample.tsx +++ b/src/components/LiveExample.tsx @@ -14,12 +14,12 @@ import * as reactDragDropModule from '@patternfly/react-drag-drop' import styles from '@patternfly/react-styles/css/components/_index' import * as reactTokensModule from '@patternfly/react-tokens' import { ExampleToolbar } from './ExampleToolbar' +import { config } from '../../pf-docs.config.mjs' interface LiveExampleProps { src?: string html?: string isFullscreenPreview?: boolean - customScope?: Record } function fallbackRender({ error }: any) { @@ -31,7 +31,7 @@ function fallbackRender({ error }: any) { ) } -function getLivePreview(editorCode: string, customScope?: Record) { +function getLivePreview(editorCode: string) { const scope = { ...reactCoreModule, ...reactIconsModule, @@ -39,7 +39,7 @@ function getLivePreview(editorCode: string, customScope?: Record) { styles, ...reactTokensModule, ...{ useState, Fragment, useRef, useEffect, createRef, useReducer }, - ...customScope, + ...config.scope, } const { code: transformedCode } = convertToReactComponent(editorCode) @@ -60,7 +60,6 @@ export const LiveExample = ({ src, html, isFullscreenPreview, - customScope, }: LiveExampleProps) => { const inputCode = src || html || '' const [code, setCode] = useState(inputCode) @@ -76,7 +75,7 @@ export const LiveExample = ({ ) lang = 'html' } else { - livePreview = getLivePreview(code, customScope) + livePreview = getLivePreview(code) lang = 'ts' } diff --git a/src/components/Navigation.astro b/src/components/Navigation.astro index ddfb742..fea0b66 100644 --- a/src/components/Navigation.astro +++ b/src/components/Navigation.astro @@ -6,7 +6,7 @@ import { TextContentEntry } from './NavEntry.tsx' import { content } from '../content' -import { config } from '../pf-docs.config.mjs' +import { config } from '../../pf-docs.config.mjs' const collections = await Promise.all( content.map( diff --git a/src/pf-docs.config.mjs b/src/pf-docs.config.mjs deleted file mode 100644 index e3e002a..0000000 --- a/src/pf-docs.config.mjs +++ /dev/null @@ -1,28 +0,0 @@ -export const config = { - content: [ - // example content entry for local content, this would feed all markdown files in the content directory to the - // documentation core with a content identifier of 'content': - // { - // base: 'content', - // pattern: "*.md", - // name: 'content' - // }, - // - // example content entry for remote content, this would fetch all markdown files matching the glob in 'pattern' - // from the specified npm package and serve them with a content identifier of 'react-component-docs': - // { - // packageName: "@patternfly/react-core", - // pattern: "**/components/**/*.md", - // name: "react-component-docs", - // }, - ], - outputDir: "./dist", - navSectionOrder: ["get-started", "design-foundations"], - // Add custom scope items for LiveExample component - // These will be available in your example code blocks - // Example: - // scope: { - // MyCustomComponent: () =>
Custom
, - // myUtilFunction: (x) => x * 2, - // }, -};