nx/scripts/documentation/package-schemas/generatePackageSchemas.ts
Isaac Mann 12eb5df469
docs(core): powerpack docs (#27904)
-  Activate powerpack recipe
-  Powerpack owners documentation
- [x] Powerpack custom remote cache documentation
- [x] Powerpack conformance documentation

Infrastructure for powerpack docs

- Adds the ability to generate API docs from ocean packages

To generate API documentation for plugins in the ocean repository, run
the `nx documentation` command with the `NX_OCEAN_RELATIVE_PATH`
environment variable set to the relative path to your checked out copy
of the ocean repo.

```
NX_OCEAN_RELATIVE_PATH=../ocean nx documentation
```

This will create generated API documentation in the
`docs/external-generated` folder. This API will be merged into the
normal `docs/generated` documentation when the docs site is built.

Because there are two separate output folders, if someone runs `nx
documentation` without the `NX_OCEAN_RELATIVE_PATH` environment
variable, the ocean documentation will not be overwritten. The ocean
documentation will only be updated or deleted when someone explicitly
chooses to do so.

---------

Co-authored-by: Juri Strumpflohner <juri.strumpflohner@gmail.com>
2024-09-25 10:15:47 -04:00

194 lines
5.8 KiB
TypeScript

/*
* Lookup for all the schema.json and add create a list with their path and related package information
* */
import { createDocumentMetadata } from '@nx/nx-dev/models-document';
import * as chalk from 'chalk';
import { join, resolve } from 'path';
import {
getSchemaFromReference,
InternalLookup,
} from '@nx/nx-dev/data-access-packages';
import { NxSchema, PackageMetadata } from '@nx/nx-dev/models-package';
import { generateJsonFile, generateMarkdownFile } from '../utils';
import { findPackageMetadataList } from './package-metadata';
import { schemaResolver } from './schema.resolver';
function processSchemaData(data: NxSchema, path: string): NxSchema {
const lookup = new InternalLookup(data);
const schema = getSchemaFromReference('#', lookup) as NxSchema;
if (schema === undefined)
throw new Error('ERROR: Could not look up the schema at: ' + data.title);
if (typeof schema === 'boolean')
throw new Error('ERROR: Boolean schema not supported.');
const resolver = schemaResolver(schema, lookup, path);
resolver.resolveReferences();
resolver.resolveExamplesFile();
return resolver.getSchema();
}
function pathResolver(root: string): (path: string) => string {
return (path) => join(root, path.replace('schema.json', ''));
}
export function generateLocalPackageSchemas(): Promise<void[]> {
return generatePackageSchemas();
}
export function generateExternalPackageSchemas(): Promise<any> {
const sourceRepositoryRelativePath = process.env.NX_OCEAN_RELATIVE_PATH;
if (!sourceRepositoryRelativePath) {
return Promise.all([]);
}
const sourcePackagesDirectory = 'libs/nx-packages';
const sourcePackagesNamePrefix = 'powerpack-';
return generatePackageSchemas(
sourceRepositoryRelativePath,
sourcePackagesDirectory,
sourcePackagesNamePrefix
);
}
export function generatePackageSchemas(
sourceRepositoryRelativePath = '',
sourcePackagesDirectory = 'packages',
sourcePackagesNamePrefix = ''
): Promise<void[]> {
console.log(`${chalk.blue('i')} Generating Package Schemas`);
const absoluteRoot = resolve(join(__dirname, '../../../'));
const sourceRepositoryRoot = resolve(
join(__dirname, '../../../', sourceRepositoryRelativePath)
);
const generatedFolderName = sourceRepositoryRelativePath
? 'external-generated'
: 'generated';
const packages = findPackageMetadataList(
sourceRepositoryRoot,
sourcePackagesDirectory,
sourcePackagesNamePrefix
).map((packageMetadata) => {
const getCurrentSchemaPath = pathResolver(absoluteRoot);
if (!!packageMetadata.executors.length) {
packageMetadata.executors = packageMetadata.executors.map((item) => ({
...item,
schema: processSchemaData(
item.schema as NxSchema,
getCurrentSchemaPath(item['path'].replace('schema.json', ''))
),
}));
}
if (!!packageMetadata.generators.length) {
packageMetadata.generators = packageMetadata.generators.map((item) => ({
...item,
schema: processSchemaData(
item.schema as NxSchema,
getCurrentSchemaPath(item['path'].replace('schema.json', ''))
),
}));
}
return packageMetadata;
});
const packagesMetadata = packages.map(
(p): PackageMetadata => ({
description: p.description,
documents: p.documents.map((d) => ({
...createDocumentMetadata({
description: d.description || p.description,
file: [
generatedFolderName,
'packages',
p.name,
'documents',
d.id,
].join('/'),
id: d.id,
itemList: d.itemList,
name: d.name,
path: [p.name, 'documents', d.id].join('/'),
tags: d.tags,
}),
originalFilePath: d.file,
})),
executors: p.executors.map((e) => ({
description: e.description,
file: [
generatedFolderName,
'packages',
p.name,
'executors',
e.name + '.json',
].join('/'),
hidden: e.hidden,
name: e.name,
originalFilePath: e.path,
path: [p.name, 'executors', e.name].join('/'),
type: 'executor',
})),
generators: p.generators.map((g) => ({
description: g.description,
file: [
generatedFolderName,
'packages',
p.name,
'generators',
g.name + '.json',
].join('/'),
hidden: g.hidden,
name: g.name,
originalFilePath: g.path,
path: [p.name, 'generators', g.name].join('/'),
type: 'generator',
})),
githubRoot: p.githubRoot,
name: p.name,
packageName: p.packageName,
root: p.root,
source: p.source,
})
);
const outputPath: string = join(absoluteRoot, 'docs', generatedFolderName);
const outputPackagesPath: string = join(outputPath, 'packages');
const fileGenerationPromises: Promise<void>[] = [];
// Generates all documents and schemas into their own directories per packages.
packages.forEach((p) => {
p.documents.forEach((d) =>
fileGenerationPromises.push(
generateMarkdownFile(join(outputPackagesPath, p.name, 'documents'), {
name: d.id,
template: d.content,
})
)
);
p.executors.forEach((e) =>
fileGenerationPromises.push(
generateJsonFile(
join(outputPackagesPath, p.name, 'executors', e.name + '.json'),
e
)
)
);
p.generators.forEach((g) =>
fileGenerationPromises.push(
generateJsonFile(
join(outputPackagesPath, p.name, 'generators', g.name + '.json'),
g
)
)
);
});
// Generates the packages-metadata.json file.
fileGenerationPromises.push(
generateJsonFile(
join(outputPath, 'packages-metadata.json'),
packagesMetadata
)
);
return Promise.all(fileGenerationPromises);
}