Design system.
 
 
 

115 行
3.7 KiB

  1. import { stat, writeFile } from 'fs/promises';
  2. import { resolve } from 'path';
  3. import { Argv } from 'yargs';
  4. import { Stats } from 'fs';
  5. import { getPackages } from '../utils/data';
  6. import { useBasePath } from '../mixins/base-path';
  7. import { CommandError } from '../utils/error';
  8. import { useInternalPath } from '../mixins/internal-path';
  9. export enum GenerateReturnCode {
  10. SUCCESS = 0,
  11. NO_TYPEDOC_JSON = -3,
  12. COULD_NOT_GENERATE_TYPEDOC_DATA = -4,
  13. COULD_NOT_GENERATE_PACKAGE_DATA = -5,
  14. }
  15. const ensureTypedocJson = async (typedocPath: string) => {
  16. const trueTypedocPath = resolve(typedocPath);
  17. process.stdout.write(`Using typedoc.json path: ${trueTypedocPath}\n`);
  18. process.stdout.write('Does the file exist? ');
  19. let statResult: Stats;
  20. try {
  21. statResult = await stat(trueTypedocPath);
  22. } catch (errRaw) {
  23. const err = errRaw as NodeJS.ErrnoException;
  24. if (err.code === 'ENOENT') {
  25. process.stdout.write('no\n');
  26. throw new CommandError(GenerateReturnCode.NO_TYPEDOC_JSON, 'Could not find typedoc.json');
  27. }
  28. process.stdout.write('maybe?\n');
  29. throw new CommandError(GenerateReturnCode.NO_TYPEDOC_JSON, 'Could not ensure typedoc.json', err);
  30. }
  31. if (statResult.isDirectory()) {
  32. process.stdout.write('no\n');
  33. throw new CommandError(GenerateReturnCode.NO_TYPEDOC_JSON, 'typedoc.json is a directory');
  34. }
  35. process.stdout.write('yes\n');
  36. };
  37. const generateTypedocData = async (basePath: string, internalPath: string) => {
  38. process.stdout.write('Generating typedoc data...\n');
  39. const outPath = resolve(internalPath, '.amanuensis', 'types.json');
  40. const typedocBinPath = resolve(internalPath, 'node_modules', '.bin', 'typedoc');
  41. const { execa } = await import('execa');
  42. const result = await execa(typedocBinPath, ['--json', outPath, '--pretty', 'false'], {
  43. stdout: 'inherit',
  44. stderr: 'inherit',
  45. cwd: basePath,
  46. });
  47. if (result.exitCode !== 0) {
  48. process.stdout.write('failed\n');
  49. throw new CommandError(GenerateReturnCode.COULD_NOT_GENERATE_TYPEDOC_DATA, 'Could not generate typedoc data');
  50. }
  51. process.stdout.write('done\n');
  52. };
  53. const generatePackageData = async (
  54. basePath: string,
  55. internalPath: string,
  56. ) => {
  57. process.stdout.write('Grouping typedoc data...\n');
  58. const configPath = resolve(basePath, 'amanuensis.config.json');
  59. const typedocDataJsonPath = resolve(internalPath, '.amanuensis', 'packages.json');
  60. const packages = await getPackages(configPath, basePath);
  61. try {
  62. await writeFile(typedocDataJsonPath, JSON.stringify(packages));
  63. process.stdout.write(`File written to ${typedocDataJsonPath}\n`);
  64. } catch (errRaw) {
  65. const err = errRaw as NodeJS.ErrnoException;
  66. process.stderr.write(`Could not write to ${typedocDataJsonPath}: ${err.message}\n`);
  67. throw new CommandError(GenerateReturnCode.COULD_NOT_GENERATE_PACKAGE_DATA, 'Could not generate package data', err);
  68. }
  69. };
  70. export const description = 'Analyze project for fetching documentation data' as const;
  71. export interface AnalyzeArgs {
  72. typedocJsonPath?: string;
  73. subcommands?: string[];
  74. }
  75. export const builder = (yargs: Argv) => yargs
  76. .option('typedocJsonPath', {
  77. type: 'string',
  78. alias: 't',
  79. });
  80. const analyze = async (args: AnalyzeArgs) => {
  81. try {
  82. const basePath = await useBasePath();
  83. process.stdout.write(`Using base path: ${basePath}\n`);
  84. const typedocJsonPath = args.typedocJsonPath ?? resolve(basePath, 'typedoc.json');
  85. await ensureTypedocJson(typedocJsonPath);
  86. const internalPath = await useInternalPath();
  87. await generateTypedocData(basePath, internalPath);
  88. await generatePackageData(basePath, internalPath);
  89. } catch (errRaw) {
  90. const err = errRaw as CommandError;
  91. process.stderr.write(`${err.message}\n`);
  92. return err.exitCode;
  93. }
  94. return GenerateReturnCode.SUCCESS;
  95. };
  96. export default analyze;