Skip to content

feat: json, json-all generators #287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
309 changes: 210 additions & 99 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
"reading-time": "^1.5.0",
"recma-jsx": "^1.0.0",
"rehype-recma": "^1.0.0",
"json-schema-to-typescript": "^15.0.4",
"jsonc-parser": "^3.3.1",
"rehype-stringify": "^10.0.1",
"remark-gfm": "^4.0.1",
"remark-parse": "^11.0.0",
Expand Down
4 changes: 4 additions & 0 deletions src/generators/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import legacyJsonAll from './legacy-json-all/index.mjs';
import llmsTxt from './llms-txt/index.mjs';
import manPage from './man-page/index.mjs';
import oramaDb from './orama-db/index.mjs';
import json from './json/index.mjs';
import jsonAll from './json-all/index.mjs';

export const publicGenerators = {
'json-simple': jsonSimple,
Expand All @@ -25,6 +27,8 @@ export const publicGenerators = {
'orama-db': oramaDb,
'llms-txt': llmsTxt,
'jsx-ast': jsxAst,
json,
'json-all': jsonAll,
};

export const allGenerators = {
Expand Down
78 changes: 78 additions & 0 deletions src/generators/json-all/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// @ts-check
'use strict';

import { writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { DOC_NODE_VERSION } from '../../constants.mjs';
import { generateJsonSchema } from './util/generateJsonSchema.mjs';

// TODO add test w/ https://www.npmjs.com/package/jsonschema

/**
* TODO docs
*
* @typedef {Array<ApiDocMetadataEntry>} Input
*
* @type {GeneratorMetadata<Input, object>}
*/
export default {
name: 'json-all',

// This should be kept in sync with the JSON schema version for this
// generator AND the `json` generator
version: '2.0.0',

description: 'TODO',

dependsOn: 'json',

/**
* Generates a JSON file.
*
* @param {Input} input
* @param {Partial<GeneratorOptions>} param1
* @returns {Promise<object>}
*/
async generate(input, { output }) {
const generatedValue = {
$schema: `https://nodejs.org/docs/${DOC_NODE_VERSION}/api/node-doc-all-schema.jsonc`,
modules: [],
text: [],
};

const propertiesToIgnore = ['$schema', 'source'];

input.forEach(section => {
const copiedSection = {};

Object.keys(section).forEach(key => {
if (!propertiesToIgnore.includes(key)) {
copiedSection[key] = section[key];
}
});

switch (section.type) {
case 'module':
generatedValue.modules.push(copiedSection);
break;
case 'text':
generatedValue.text.push(copiedSection);
break;
default:
throw new TypeError(`unsupported root section type ${section.type}`);
}
});

if (output) {
const schema = generateJsonSchema();

// Write the parsed JSON schema to the output directory
await writeFile(
join(output, 'node-doc-schema.json'),
JSON.stringify(schema)
);
}

return generatedValue;
},
};
26 changes: 26 additions & 0 deletions src/generators/json-all/util/generateJsonSchema.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// @ts-check
'use strict';

import { DOC_NODE_VERSION } from '../../../constants.mjs';

const JSON_SCHEMA_URL = `https://nodejs.org/docs/${DOC_NODE_VERSION}/api/node-doc-schema.json`;

export const generateJsonSchema = () => ({
$schema: 'http://json-schema.org/draft-07/schema#',
// This should be kept in sync with the generator version for this generator
// AND the `json` generator and schema
$id: '[email protected]', // This should be kept in sync with the generator version.
title: 'Node.js API Documentation Schema (All)',
readOnly: true,

properties: {
modules: {
type: 'array',
items: { $ref: `${JSON_SCHEMA_URL}/#/definitions/Module` },
},
text: {
type: 'array',
items: { $ref: `${JSON_SCHEMA_URL}/#/definitions/Text` },
},
},
});
1 change: 1 addition & 0 deletions src/generators/json/constants.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'use strict';
180 changes: 180 additions & 0 deletions src/generators/json/generated.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/* eslint-disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/

export type NodeJsAPIDocumentationSchema = DocumentRoot & (Module | Text);
/**
* A JavaScript module.
*/
export type Module = SectionBase & {
type: 'module';
/**
* https://jsdoc.app/tags-see
*/
'@see': string;
/**
* https://jsdoc.app/tags-module
*/
'@module': string;
/**
* Classes exported from this module.
*/
classes?: Class[];
/**
* Methods exported from this module.
*/
methods?: Method[];
/**
* APIs that are available globally.
*/
globals?: (Class | Method)[];
properties?: Property[];
[k: string]: unknown;
};
export type Text = SectionBase;
/**
* Node.js version number
*/
export type NodeCoreVersion = string;
export type Class = SectionBase & {
type: 'class';
'@constructor': MethodSignature[];
methods: Method[];
staticMethods: Method[];
properties: Property[];
[k: string]: unknown;
};
/**
* A JavaScript function.
*/
export type Method = SectionBase & {
type: 'method';
signatures: MethodSignature[];
[k: string]: unknown;
};
/**
* A property on a JavaScript object or class.
*/
export type Property = SectionBase & {
type: 'property';
/**
* JavaScript type of the property.
*/
'@type'?: string | [string, ...string[]];
/**
* Is this property modifiable by user code?
*/
mutable?: boolean;
[k: string]: unknown;
};

/**
* Common properties found at the root of each document.
*/
export interface DocumentRoot {
/**
* The path to the Markdown source used to generate this document. It is relative to the Node.js repository root.
*/
source: string;
[k: string]: unknown;
}
/**
* Common properties found in each section of a document.
*/
export interface SectionBase {
/**
* Type of the section
*/
type: 'module' | 'class' | 'method' | 'property' | 'text';
/**
* https://jsdoc.app/tags-name
*/
'@name': string;
/**
* Description of the section.
*/
description?: string;
/**
* Sections that just hold further text on this section.
*/
text?: Text[];
/**
* https://jsdoc.app/tags-example
*/
'@example'?: string | string[];
/**
* https://jsdoc.app/tags-deprecated
*/
'@deprecated'?: NodeCoreVersion[];
stability?: Stability;
/**
* The changes this API has underwent.
*/
changes?: Change[];
/**
* https://jsdoc.app/tags-since
*/
'@since'?: NodeCoreVersion[];
/**
* todo what does this describe lol
*/
napiVersion?: number[];
/**
* Versions that this was removed in.
*/
removedIn?: NodeCoreVersion[];
[k: string]: unknown;
}
/**
* Describes the stability of an object.
*/
export interface Stability {
/**
* The stability value.
*/
value: number;
/**
* Textual representation of the stability.
*/
text: string;
[k: string]: unknown;
}
export interface Change {
version: NodeCoreVersion[];
/**
* URL to the PR that introduced this change.
*/
prUrl?: string;
/**
* Description of the change.
*/
description: string;
[k: string]: unknown;
}
export interface MethodSignature {
parameters?: MethodParameter[];
/**
* The method signature's return type.
*/
'@returns'?: string | [string, ...string[]];
[k: string]: unknown;
}
export interface MethodParameter {
/**
* Name of the parameter.
*/
'@name': string;
/**
* Type of the parameter
*/
'@type': string | [string, ...string[]];
description?: string;
/**
* The parameter's default value
*/
'@default'?: string;
[k: string]: unknown;
}
Loading
Loading