@patternfly/patternfly-doc-core 1.2.1 → 1.4.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.
Files changed (88) hide show
  1. package/.astro/collections/textContent.schema.json +6 -0
  2. package/README.md +11 -10
  3. package/astro.config.mjs +8 -1
  4. package/cli/buildPropsData.ts +113 -0
  5. package/cli/cli.ts +54 -6
  6. package/cli/getConfig.ts +6 -0
  7. package/cli/hasFile.ts +5 -0
  8. package/cli/symLinkConfig.ts +21 -0
  9. package/cli/templates/pf-docs.config.mjs +14 -2
  10. package/cli/tsDocGen.js +199 -0
  11. package/dist/cli/buildPropsData.js +68 -0
  12. package/dist/cli/cli.js +39 -4
  13. package/dist/cli/hasFile.js +4 -0
  14. package/dist/cli/symLinkConfig.js +15 -0
  15. package/dist/cli/templates/pf-docs.config.mjs +13 -1
  16. package/dist/cli/tsDocGen.js +153 -0
  17. package/dist/cli/tsconfig.tsbuildinfo +1 -1
  18. package/dist/client/_astro/Navigation.75VF_8AW.js +1 -0
  19. package/dist/client/_astro/_page_.SnUmZn2y.css +1 -0
  20. package/dist/client/design-foundations/typography/index.html +219 -0
  21. package/dist/client/design-foundations/usage-and-behavior/index.html +368 -0
  22. package/dist/client/get-started/contribute/index.html +115 -0
  23. package/dist/client/index.html +42 -0
  24. package/dist/server/_@astrojs-ssr-adapter.mjs +1 -0
  25. package/dist/server/_noop-middleware.mjs +3 -0
  26. package/dist/server/chunks/PropsTables_D_v4KAMn.mjs +1826 -0
  27. package/dist/server/chunks/_@astrojs-ssr-adapter_ByVMUK8O.mjs +3621 -0
  28. package/dist/server/chunks/_astro_assets_CLOMnm-3.mjs +1507 -0
  29. package/dist/server/chunks/_astro_data-layer-content_DDGBHvtb.mjs +1 -0
  30. package/dist/server/chunks/angle-down-icon_BNJvzYv-.mjs +3970 -0
  31. package/dist/server/chunks/astro/server_D4f31GMD.mjs +2769 -0
  32. package/dist/server/chunks/astro-designed-error-pages_CpHpbfhr.mjs +282 -0
  33. package/dist/server/chunks/consts_BmVDRGlB.mjs +32 -0
  34. package/dist/server/chunks/content-assets_DleWbedO.mjs +1 -0
  35. package/dist/server/chunks/content-modules_Dz-S_Wwv.mjs +1 -0
  36. package/dist/server/chunks/path_Cvt6sEOY.mjs +58 -0
  37. package/dist/server/chunks/sharp_BYpUyJGL.mjs +88 -0
  38. package/dist/server/entry.mjs +45 -0
  39. package/dist/server/manifest_CBenwYiZ.mjs +102 -0
  40. package/dist/server/pages/_image.astro.mjs +132 -0
  41. package/dist/server/pages/_section_/_---page_.astro.mjs +1 -0
  42. package/dist/server/pages/_section_/_page_/_---tab_.astro.mjs +1 -0
  43. package/dist/server/pages/index.astro.mjs +1 -0
  44. package/dist/server/pages/props.astro.mjs +25 -0
  45. package/dist/server/renderers.mjs +259 -0
  46. package/jest.config.ts +1 -1
  47. package/package.json +4 -1
  48. package/pf-docs.config.mjs +31 -0
  49. package/src/components/Navigation.astro +15 -4
  50. package/src/components/Navigation.tsx +26 -2
  51. package/src/components/PropsTable.tsx +3 -3
  52. package/src/components/PropsTables.astro +38 -0
  53. package/src/content.config.ts +1 -0
  54. package/src/pages/[section]/[...page].astro +16 -8
  55. package/src/pages/[section]/[page]/[...tab].astro +4 -1
  56. package/src/pages/props.ts +17 -0
  57. package/src/pf-docs.config.mjs +21 -0
  58. package/textContent/contribute.md +1 -0
  59. package/dist/_astro/Navigation.Cede__Ud.js +0 -1
  60. package/dist/design-foundations/typography/index.html +0 -193
  61. package/dist/design-foundations/usage-and-behavior/index.html +0 -342
  62. package/dist/get-started/contribute/index.html +0 -89
  63. package/dist/index.html +0 -42
  64. /package/dist/{PF-HorizontalLogo-Color.svg → client/PF-HorizontalLogo-Color.svg} +0 -0
  65. /package/dist/{PF-HorizontalLogo-Reverse.svg → client/PF-HorizontalLogo-Reverse.svg} +0 -0
  66. /package/dist/{_astro → client/_astro}/Button.C3_jB5tC.js +0 -0
  67. /package/dist/{_astro → client/_astro}/ClientRouter.astro_astro_type_script_index_0_lang.Cainpjm5.js +0 -0
  68. /package/dist/{_astro → client/_astro}/PageContext.C7BqCh9N.js +0 -0
  69. /package/dist/{_astro → client/_astro}/PageToggle.DDEjruql.js +0 -0
  70. /package/dist/{_astro → client/_astro}/RedHatDisplayVF-Italic.CRpusWc8.woff2 +0 -0
  71. /package/dist/{_astro → client/_astro}/RedHatDisplayVF.CYDHf1NI.woff2 +0 -0
  72. /package/dist/{_astro → client/_astro}/RedHatMonoVF-Italic.DGQo2ogW.woff2 +0 -0
  73. /package/dist/{_astro → client/_astro}/RedHatMonoVF.C4fMH6Vz.woff2 +0 -0
  74. /package/dist/{_astro → client/_astro}/RedHatTextVF-Italic.Dkj_WqbA.woff2 +0 -0
  75. /package/dist/{_astro → client/_astro}/RedHatTextVF.wYvZ7prR.woff2 +0 -0
  76. /package/dist/{_astro → client/_astro}/Toolbar.TAdHxLSQ.js +0 -0
  77. /package/dist/{_astro → client/_astro}/_page_.CXyz_BEo.css +0 -0
  78. /package/dist/{_astro → client/_astro}/_page_.DVvr_Mfl.css +0 -0
  79. /package/dist/{_astro → client/_astro}/client.CeeiqVaE.js +0 -0
  80. /package/dist/{_astro → client/_astro}/divider.BSD-oFoh.js +0 -0
  81. /package/dist/{_astro → client/_astro}/fa-solid-900.DguXoeIz.woff2 +0 -0
  82. /package/dist/{_astro → client/_astro}/index.CTH3fVMn.js +0 -0
  83. /package/dist/{_astro → client/_astro}/page.B65lVdBS.js +0 -0
  84. /package/dist/{_astro → client/_astro}/pf-v6-pficon.Dy6oiu9u.woff2 +0 -0
  85. /package/dist/{avatarImg.svg → client/avatarImg.svg} +0 -0
  86. /package/dist/{avatarImgDark.svg → client/avatarImgDark.svg} +0 -0
  87. /package/dist/{content → client/content}/typography/line-height.png +0 -0
  88. /package/dist/{favicon.svg → client/favicon.svg} +0 -0
@@ -16,6 +16,12 @@
16
16
  "title": {
17
17
  "type": "string"
18
18
  },
19
+ "propComponents": {
20
+ "type": "array",
21
+ "items": {
22
+ "type": "string"
23
+ }
24
+ },
19
25
  "tab": {
20
26
  "type": "string"
21
27
  },
package/README.md CHANGED
@@ -37,13 +37,14 @@ To define the markdown schema this project uses a typescript based schema known
37
37
 
38
38
  All commands are run from the root of the project, from a terminal:
39
39
 
40
- | Command | Action |
41
- | :------------------------ | :----------------------------------------------- |
42
- | `npm install` | Installs dependencies |
43
- | `npm run dev` | Starts local dev server at `localhost:4321` |
44
- | `npm run build` | Build your production site to `./dist/` |
45
- | `npm run preview` | Preview your build locally, before deploying |
46
- | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
47
- | `npm run astro -- --help` | Get help using the Astro CLI |
48
- | `npm run build:cli` | Create a JS build of the documentation core CLI |
49
- | `npm run build:cli:watch` | Run the CLI builder in watch mode |
40
+ | Command | Action |
41
+ | :------------------------ | :-----------------------------------------------------------------|
42
+ | `npm install` | Installs dependencies |
43
+ | `npm run dev` | Starts local dev server at `localhost:4321` |
44
+ | `npm run build` | Build your production site to `./dist/` |
45
+ | `npm run preview` | Preview your build locally, before deploying |
46
+ | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
47
+ | `npm run astro -- --help` | Get help using the Astro CLI |
48
+ | `npm run build:cli` | Create a JS build of the documentation core CLI |
49
+ | `npm run build:cli:watch` | Run the CLI builder in watch mode |
50
+ | `npm run build:props` | Create a json file of your TsDoc compatible in code documentation |
package/astro.config.mjs CHANGED
@@ -2,9 +2,12 @@
2
2
  import { defineConfig } from 'astro/config';
3
3
  import react from '@astrojs/react';
4
4
 
5
+ import node from '@astrojs/node';
6
+
5
7
  // https://astro.build/config
6
8
  export default defineConfig({
7
9
  integrations: [react()],
10
+
8
11
  vite: {
9
12
  ssr: {
10
13
  noExternal: ["@patternfly/*", "react-dropzone"],
@@ -14,5 +17,9 @@ export default defineConfig({
14
17
  allow: ['./']
15
18
  }
16
19
  }
17
- }
20
+ },
21
+
22
+ adapter: node({
23
+ mode: 'standalone'
24
+ })
18
25
  });
@@ -0,0 +1,113 @@
1
+ /* eslint-disable no-console */
2
+
3
+ import { glob } from 'glob'
4
+ import { writeFile } from 'fs/promises'
5
+ import { join } from 'path'
6
+
7
+ import { tsDocgen } from './tsDocGen.js'
8
+ import { getConfig, PropsGlobs } from './getConfig.js'
9
+
10
+ interface Prop {
11
+ name: string
12
+ type: string
13
+ description?: string
14
+ required?: boolean
15
+ defaultValue?: string
16
+ hide?: boolean
17
+ }
18
+ interface TsDoc {
19
+ name: string
20
+ description: string
21
+ props: Prop[]
22
+ }
23
+ interface PropsData {
24
+ [key: string]: TsDoc
25
+ }
26
+
27
+ // Build unique names for components with a "variant" extension
28
+ type TsDocVariants = 'next' | 'deprecated' | undefined
29
+ function getTsDocName(name: string, variant: TsDocVariants) {
30
+ return `${name}${variant ? `-${variant}` : ''}`
31
+ }
32
+
33
+ function getTsDocNameVariant(source: string) {
34
+ if (source.includes('next')) {
35
+ return 'next'
36
+ }
37
+
38
+ if (source.includes('deprecated')) {
39
+ return 'deprecated'
40
+ }
41
+ }
42
+
43
+ async function getFiles(root: string, globs: PropsGlobs[]) {
44
+ const files = await Promise.all(
45
+ globs.map(async ({ include, exclude }) => {
46
+ const files = await glob(include, { cwd: root, ignore: exclude })
47
+ return files
48
+ }),
49
+ )
50
+ return files.flat()
51
+ }
52
+
53
+ async function getPropsData(files: string[], verbose: boolean) {
54
+ const perFilePropsData = await Promise.all(
55
+ files.map(async (file) => {
56
+ if (verbose) {
57
+ console.log(`Parsing props from ${file}`)
58
+ }
59
+
60
+ const props = (await tsDocgen(file)) as TsDoc[]
61
+
62
+ const tsDocs = props.reduce((acc, { name, description, props }) => {
63
+ const key = getTsDocName(name, getTsDocNameVariant(file))
64
+ return { ...acc, [key]: { name, description, props } }
65
+ }, {} as PropsData)
66
+
67
+ return tsDocs
68
+ }),
69
+ )
70
+
71
+ const combinedPropsData = perFilePropsData.reduce((acc, props) => {
72
+ Object.keys(props).forEach((key) => {
73
+ const propsData = props[key]
74
+ if (acc[key]) {
75
+ acc[key].props = [...acc[key].props, ...propsData.props]
76
+ } else {
77
+ acc[key] = propsData
78
+ }
79
+ })
80
+ return acc
81
+ }, {})
82
+
83
+ return combinedPropsData
84
+ }
85
+
86
+ export async function buildPropsData(
87
+ rootDir: string,
88
+ astroRoot: string,
89
+ configFile: string,
90
+ verbose: boolean,
91
+ ) {
92
+ const config = await getConfig(configFile)
93
+ if (!config) {
94
+ return
95
+ }
96
+
97
+ const { propsGlobs } = config
98
+ if (!propsGlobs) {
99
+ console.error('No props data found in config')
100
+ return
101
+ }
102
+
103
+ const files = await getFiles(rootDir, propsGlobs)
104
+ if (verbose) {
105
+ console.log(`Found ${files.length} files to parse`)
106
+ }
107
+
108
+ const propsData = await getPropsData(files, verbose)
109
+
110
+ const propsFile = join(astroRoot, 'dist', 'props.json')
111
+
112
+ await writeFile(propsFile, JSON.stringify(propsData))
113
+ }
package/cli/cli.ts CHANGED
@@ -8,6 +8,9 @@ import { setFsRootDir } from './setFsRootDir.js'
8
8
  import { createConfigFile } from './createConfigFile.js'
9
9
  import { updatePackageFile } from './updatePackageFile.js'
10
10
  import { getConfig } from './getConfig.js'
11
+ import { symLinkConfig } from './symLinkConfig.js'
12
+ import { buildPropsData } from './buildPropsData.js'
13
+ import { hasFile } from './hasFile.js'
11
14
 
12
15
  function updateContent(program: Command) {
13
16
  const { verbose } = program.opts()
@@ -23,16 +26,47 @@ function updateContent(program: Command) {
23
26
  )
24
27
  }
25
28
 
26
- const astroRoot = import.meta
27
- .resolve('@patternfly/patternfly-doc-core')
28
- .replace('dist/cli/cli.js', '')
29
- .replace('file://', '')
29
+ async function generateProps(program: Command, forceProps: boolean = false) {
30
+ const { verbose, props } = program.opts()
31
+
32
+ if (!props && !forceProps) {
33
+ return
34
+ }
35
+
36
+ if (verbose) {
37
+ console.log('Verbose mode enabled')
38
+ }
39
+
40
+ buildPropsData(
41
+ currentDir,
42
+ astroRoot,
43
+ `${currentDir}/pf-docs.config.mjs`,
44
+ verbose,
45
+ )
46
+ }
47
+
48
+ let astroRoot = ''
49
+
50
+ try {
51
+ astroRoot = import.meta
52
+ .resolve('@patternfly/patternfly-doc-core')
53
+ .replace('dist/cli/cli.js', '')
54
+ .replace('file://', '')
55
+ } catch (e: any) {
56
+ if (e.code === 'ERR_MODULE_NOT_FOUND') {
57
+ astroRoot = process.cwd()
58
+ } else {
59
+ console.error('Error resolving astroRoot', e)
60
+ }
61
+ }
62
+
30
63
  const currentDir = process.cwd()
31
64
 
32
65
  const program = new Command()
33
66
  program.name('pf-doc-core')
34
67
 
35
68
  program.option('--verbose', 'verbose mode', false)
69
+ program.option('--props', 'generate props data', false)
36
70
 
37
71
  program.command('setup').action(async () => {
38
72
  await Promise.all([
@@ -47,6 +81,7 @@ program.command('setup').action(async () => {
47
81
 
48
82
  program.command('init').action(async () => {
49
83
  await setFsRootDir(astroRoot, currentDir)
84
+ await symLinkConfig(astroRoot, currentDir)
50
85
  console.log(
51
86
  '\nInitialization complete, next update your pf-docs.config.mjs file and then run the `start` script to start the dev server',
52
87
  )
@@ -54,11 +89,17 @@ program.command('init').action(async () => {
54
89
 
55
90
  program.command('start').action(async () => {
56
91
  updateContent(program)
92
+
93
+ // if a props file hasn't been generated yet, but the consumer has propsData, it will cause a runtime error so to
94
+ // prevent that we're just creating a props file regardless of what they say if one doesn't exist yet
95
+ const hasPropsFile = await hasFile(join(astroRoot, 'dist', 'props.json'))
96
+ await generateProps(program, !hasPropsFile)
57
97
  dev({ mode: 'development', root: astroRoot })
58
98
  })
59
99
 
60
100
  program.command('build').action(async () => {
61
101
  updateContent(program)
102
+ await generateProps(program, true)
62
103
  const config = await getConfig(`${currentDir}/pf-docs.config.mjs`)
63
104
  if (!config) {
64
105
  console.error(
@@ -68,13 +109,20 @@ program.command('build').action(async () => {
68
109
  }
69
110
 
70
111
  if (!config.outputDir) {
71
- console.error("No outputDir found in config file, an output directory must be defined in your config file e.g. 'dist'")
112
+ console.error(
113
+ "No outputDir found in config file, an output directory must be defined in your config file e.g. 'dist'",
114
+ )
72
115
  return
73
116
  }
74
-
117
+
75
118
  build({ root: astroRoot, outDir: join(currentDir, config.outputDir) })
76
119
  })
77
120
 
121
+ program.command('generate-props').action(async () => {
122
+ await generateProps(program, true)
123
+ console.log('\nProps data generated')
124
+ })
125
+
78
126
  program.command('serve').action(async () => {
79
127
  updateContent(program)
80
128
  preview({ root: astroRoot })
package/cli/getConfig.ts CHANGED
@@ -6,9 +6,15 @@ export interface CollectionDefinition {
6
6
  name: string
7
7
  }
8
8
 
9
+ export interface PropsGlobs {
10
+ include: string[]
11
+ exclude: string[]
12
+ }
13
+
9
14
  export interface DocsConfig {
10
15
  content: CollectionDefinition[];
11
16
  outputDir: string;
17
+ propsGlobs: PropsGlobs[];
12
18
  }
13
19
 
14
20
  export async function getConfig(fileLocation: string): Promise<DocsConfig | undefined> {
package/cli/hasFile.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { readFile } from "fs/promises";
2
+
3
+ export async function hasFile(path: string) {
4
+ return readFile(path).then(() => true, () => false)
5
+ }
@@ -0,0 +1,21 @@
1
+ /* eslint-disable no-console */
2
+ import { symlink } from 'fs/promises'
3
+
4
+ export async function symLinkConfig(
5
+ astroRootDir: string,
6
+ consumerRootDir: string,
7
+ ) {
8
+ const configFileName = '/pf-docs.config.mjs'
9
+ const docsConfigFile = consumerRootDir + configFileName
10
+
11
+ try {
12
+ await symlink(docsConfigFile, astroRootDir + configFileName)
13
+ } catch (e: any) {
14
+ console.error(
15
+ `Error creating symlink to ${docsConfigFile} in ${astroRootDir}`,
16
+ e,
17
+ )
18
+ } finally {
19
+ console.log(`Symlink to ${docsConfigFile} in ${astroRootDir} created`)
20
+ }
21
+ }
@@ -16,5 +16,17 @@ export const config = {
16
16
  // name: "react-component-docs",
17
17
  // },
18
18
  ],
19
- outputDir: "./dist/docs"
20
- };
19
+ navSectionOrder: ["get-started", "design-foundations"],
20
+ outputDir: './dist/docs',
21
+ propsGlobs: [
22
+ // {
23
+ // include: ['*/@patternfly/react-core/src/**/*.tsx'],
24
+ // exclude: [
25
+ // '/**/examples/**',
26
+ // '/**/__mocks__/**',
27
+ // '/**/__tests__/**',
28
+ // '/**/*.test.tsx',
29
+ // ],
30
+ // },
31
+ ],
32
+ }
@@ -0,0 +1,199 @@
1
+ import { readFile } from 'fs/promises'
2
+ import { parse } from 'react-docgen'
3
+ import ts from 'typescript'
4
+
5
+ const annotations = [
6
+ {
7
+ regex: /@deprecated/,
8
+ name: 'deprecated',
9
+ type: 'Boolean',
10
+ },
11
+ {
12
+ regex: /@hide/,
13
+ name: 'hide',
14
+ type: 'Boolean',
15
+ },
16
+ {
17
+ regex: /@beta/,
18
+ name: 'beta',
19
+ type: 'Boolean',
20
+ },
21
+ {
22
+ regex: /@propType\s+(.*)/,
23
+ name: 'type',
24
+ type: 'String',
25
+ },
26
+ ]
27
+
28
+ function addAnnotations(prop) {
29
+ if (prop.description) {
30
+ annotations.forEach(({ regex, name }) => {
31
+ const match = prop.description.match(regex)
32
+ if (match) {
33
+ prop.description = prop.description.replace(regex, '').trim()
34
+ if (name) {
35
+ prop[name] = match[2] || match[1] || true
36
+ }
37
+ }
38
+ })
39
+ }
40
+
41
+ return prop
42
+ }
43
+
44
+ function getComponentMetadata(filename, sourceText) {
45
+ let parsedComponents = null
46
+ try {
47
+ parsedComponents = parse(sourceText, { filename })
48
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
49
+ } catch (_err) {
50
+ // eslint-disable-next-line no-console
51
+ // console.warn(`No component found in ${filename}:`, err);
52
+ }
53
+
54
+ return (parsedComponents || []).filter(
55
+ (parsed) => parsed && parsed.displayName,
56
+ )
57
+ }
58
+
59
+ const getNodeText = (node, sourceText) => {
60
+ if (!node || !node.pos || !node.end) {
61
+ return undefined
62
+ }
63
+
64
+ return sourceText.substring(node.pos, node.end).trim()
65
+ }
66
+
67
+ const buildJsDocProps = (nodes, sourceText) =>
68
+ nodes?.reduce((acc, member) => {
69
+ const name =
70
+ (member.name && member.name.escapedText) ||
71
+ (member.parameters &&
72
+ `[${getNodeText(member.parameters[0], sourceText)}]`) ||
73
+ 'Unknown'
74
+ acc[name] = {
75
+ description: member.jsDoc
76
+ ? member.jsDoc.map((doc) => doc.comment).join('\n')
77
+ : null,
78
+ required: member.questionToken === undefined,
79
+ type: {
80
+ raw: getNodeText(member.type, sourceText).trim(),
81
+ },
82
+ }
83
+ return acc
84
+ }, {})
85
+
86
+ const getSourceFileStatements = (filename, sourceText) => {
87
+ const { statements } = ts.createSourceFile(
88
+ filename,
89
+ sourceText,
90
+ ts.ScriptTarget.Latest, // languageVersion
91
+ )
92
+
93
+ return statements
94
+ }
95
+
96
+ const getInterfaceMetadata = (filename, sourceText) =>
97
+ getSourceFileStatements(filename, sourceText).reduce(
98
+ (metaDataAcc, statement) => {
99
+ if (statement.kind === ts.SyntaxKind.InterfaceDeclaration) {
100
+ const _statement = statement
101
+ metaDataAcc.push({
102
+ displayName: _statement.name.escapedText,
103
+ description: _statement.jsDoc?.map((doc) => doc.comment).join('\n'),
104
+ props: buildJsDocProps(_statement.members, sourceText),
105
+ })
106
+ }
107
+
108
+ return metaDataAcc
109
+ },
110
+ [],
111
+ )
112
+
113
+ const getTypeAliasMetadata = (filename, sourceText) =>
114
+ getSourceFileStatements(filename, sourceText).reduce(
115
+ (metaDataAcc, statement) => {
116
+ if (statement.kind === ts.SyntaxKind.TypeAliasDeclaration) {
117
+ const _statement = statement
118
+ const props = _statement.type.types?.reduce((propAcc, type) => {
119
+ if (type.members) {
120
+ propAcc.push(buildJsDocProps(type.members, sourceText))
121
+ }
122
+
123
+ return propAcc
124
+ }, [])
125
+
126
+ metaDataAcc.push({
127
+ props,
128
+ displayName: _statement.name.escapedText,
129
+ description: _statement.jsDoc?.map((doc) => doc.comment).join('\n'),
130
+ })
131
+ }
132
+
133
+ return metaDataAcc
134
+ },
135
+ [],
136
+ )
137
+
138
+ function normalizeProp([
139
+ name,
140
+ { required, annotatedType, type, tsType, description, defaultValue },
141
+ ]) {
142
+ const res = {
143
+ name,
144
+ type:
145
+ annotatedType ||
146
+ (type && type.name) ||
147
+ (type && (type.raw || type.name)) ||
148
+ (tsType && (tsType.raw || tsType.name)) ||
149
+ 'No type info',
150
+ description,
151
+ }
152
+ if (required) {
153
+ res.required = true
154
+ }
155
+ if (defaultValue && defaultValue.value) {
156
+ res.defaultValue = defaultValue.value
157
+ }
158
+
159
+ return res
160
+ }
161
+
162
+ export async function tsDocgen(file) {
163
+ const sourceText = await readFile(file, 'utf8')
164
+ const componentMeta = getComponentMetadata(file, sourceText) // Array of components with props
165
+ const interfaceMeta = getInterfaceMetadata(file, sourceText) // Array of interfaces with props
166
+ const typeAliasMeta = getTypeAliasMetadata(file, sourceText) // Array of type aliases with props
167
+ const propsMetaMap = [...interfaceMeta, ...typeAliasMeta].reduce(function (
168
+ target,
169
+ interfaceOrTypeAlias,
170
+ ) {
171
+ target[interfaceOrTypeAlias.displayName] = interfaceOrTypeAlias
172
+ return target
173
+ }, {})
174
+
175
+ // Go through each component and check if they have an interface or type alias with a jsDoc description
176
+ // If so copy it over (fix for https://github.com/patternfly/patternfly-react/issues/7612)
177
+ componentMeta.forEach((c) => {
178
+ if (c.description) {
179
+ return c
180
+ }
181
+
182
+ const propsName = `${c.displayName}Props`
183
+ if (propsMetaMap[propsName]?.description) {
184
+ c.description = propsMetaMap[propsName].description
185
+ }
186
+ })
187
+
188
+ return [...componentMeta, ...interfaceMeta, ...typeAliasMeta].map(
189
+ (parsed) => ({
190
+ name: parsed.displayName,
191
+ description: parsed.description || '',
192
+ props: Object.entries(parsed.props || {})
193
+ .map(normalizeProp)
194
+ .map(addAnnotations)
195
+ .filter((prop) => !prop.hide)
196
+ .sort((p1, p2) => p1.name.localeCompare(p2.name)),
197
+ }),
198
+ )
199
+ }
@@ -0,0 +1,68 @@
1
+ /* eslint-disable no-console */
2
+ import { glob } from 'glob';
3
+ import { writeFile } from 'fs/promises';
4
+ import { join } from 'path';
5
+ import { tsDocgen } from './tsDocGen.js';
6
+ import { getConfig } from './getConfig.js';
7
+ function getTsDocName(name, variant) {
8
+ return `${name}${variant ? `-${variant}` : ''}`;
9
+ }
10
+ function getTsDocNameVariant(source) {
11
+ if (source.includes('next')) {
12
+ return 'next';
13
+ }
14
+ if (source.includes('deprecated')) {
15
+ return 'deprecated';
16
+ }
17
+ }
18
+ async function getFiles(root, globs) {
19
+ const files = await Promise.all(globs.map(async ({ include, exclude }) => {
20
+ const files = await glob(include, { cwd: root, ignore: exclude });
21
+ return files;
22
+ }));
23
+ return files.flat();
24
+ }
25
+ async function getPropsData(files, verbose) {
26
+ const perFilePropsData = await Promise.all(files.map(async (file) => {
27
+ if (verbose) {
28
+ console.log(`Parsing props from ${file}`);
29
+ }
30
+ const props = (await tsDocgen(file));
31
+ const tsDocs = props.reduce((acc, { name, description, props }) => {
32
+ const key = getTsDocName(name, getTsDocNameVariant(file));
33
+ return { ...acc, [key]: { name, description, props } };
34
+ }, {});
35
+ return tsDocs;
36
+ }));
37
+ const combinedPropsData = perFilePropsData.reduce((acc, props) => {
38
+ Object.keys(props).forEach((key) => {
39
+ const propsData = props[key];
40
+ if (acc[key]) {
41
+ acc[key].props = [...acc[key].props, ...propsData.props];
42
+ }
43
+ else {
44
+ acc[key] = propsData;
45
+ }
46
+ });
47
+ return acc;
48
+ }, {});
49
+ return combinedPropsData;
50
+ }
51
+ export async function buildPropsData(rootDir, astroRoot, configFile, verbose) {
52
+ const config = await getConfig(configFile);
53
+ if (!config) {
54
+ return;
55
+ }
56
+ const { propsGlobs } = config;
57
+ if (!propsGlobs) {
58
+ console.error('No props data found in config');
59
+ return;
60
+ }
61
+ const files = await getFiles(rootDir, propsGlobs);
62
+ if (verbose) {
63
+ console.log(`Found ${files.length} files to parse`);
64
+ }
65
+ const propsData = await getPropsData(files, verbose);
66
+ const propsFile = join(astroRoot, 'dist', 'props.json');
67
+ await writeFile(propsFile, JSON.stringify(propsData));
68
+ }