mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-04-22 14:19:41 +00:00
feat: improve monorepo dev experience
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import {createGenerator, SchemaGenerator} from 'ts-json-schema-generator';
|
||||
import {getValidatableTypes} from './get-validatable-types.js';
|
||||
|
||||
/**
|
||||
* Compile the JSON schema for a path
|
||||
*/
|
||||
export function compileSchema(path: string, tsconfig: string): ReturnType<SchemaGenerator['createSchema']> {
|
||||
const generator = createGenerator({
|
||||
path,
|
||||
tsconfig,
|
||||
extraTags: ['elasticsearch'],
|
||||
skipTypeCheck: true,
|
||||
});
|
||||
// @ts-expect-error private access
|
||||
const program = generator.program;
|
||||
const schemaNames = getValidatableTypes(program);
|
||||
const fullSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
definitions: {},
|
||||
};
|
||||
|
||||
for (const schema of schemaNames) {
|
||||
Object.assign(fullSchema.definitions, generator.createSchema(schema).definitions);
|
||||
}
|
||||
|
||||
return fullSchema;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import {ts} from 'ts-json-schema-generator';
|
||||
|
||||
/**
|
||||
* Get all types with `@validatable` annotations
|
||||
*/
|
||||
export function getValidatableTypes(program: ts.Program) {
|
||||
const checker = program.getTypeChecker();
|
||||
const declarationNames: string[] = [];
|
||||
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
const sourceFileSymbol = checker.getSymbolAtLocation(sourceFile);
|
||||
if (!sourceFileSymbol) continue;
|
||||
for (const exportSymbol of checker.getExportsOfModule(sourceFileSymbol)) {
|
||||
for (const declaration of exportSymbol.getDeclarations() ?? []) {
|
||||
const validatableTags = ts.getAllJSDocTags(declaration, isValidatableJSDocTag);
|
||||
const name = ts.getNameOfDeclaration(declaration);
|
||||
|
||||
if (name && validatableTags.length > 0) {
|
||||
declarationNames.push(name.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return declarationNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type predicate for if a JSDoc tag is `@validatable`
|
||||
*/
|
||||
// eslint-disable-next-line unicorn/prevent-abbreviations
|
||||
function isValidatableJSDocTag(tag: ts.JSDocTag): tag is ts.JSDocTag {
|
||||
return tag.tagName.escapedText === 'validatable';
|
||||
}
|
||||
37
packages/json-schema-generator/src/index.ts
Normal file
37
packages/json-schema-generator/src/index.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {compileSchema} from './generator/compile-schema.js';
|
||||
import {generateFiles, Plugin, PluginContext} from '@openstapps/tsup-plugin';
|
||||
|
||||
export type SchemaConsumer = (
|
||||
this: PluginContext,
|
||||
schema: ReturnType<typeof compileSchema>,
|
||||
) => Record<string, string | Buffer>;
|
||||
|
||||
/**
|
||||
* TSUp plugin for generating JSONSchema files
|
||||
* @param schemaName the name of the generated schema
|
||||
* @param schemaConsumers any consumers that can directly use the schema
|
||||
*/
|
||||
export function jsonSchemaPlugin(
|
||||
schemaName: string,
|
||||
...schemaConsumers: Array<[string, SchemaConsumer]>
|
||||
): Plugin {
|
||||
return {
|
||||
name: 'json-schema-generator',
|
||||
async buildEnd() {
|
||||
let schema: ReturnType<typeof compileSchema>;
|
||||
await generateFiles('JSON-Schema', async function () {
|
||||
schema = compileSchema((this.options.entry as string[])[0], this.options.tsconfig!);
|
||||
|
||||
return {
|
||||
[schemaName]: JSON.stringify(schema),
|
||||
};
|
||||
}).call(this);
|
||||
|
||||
for (const [name, consumer] of schemaConsumers) {
|
||||
await generateFiles(name, async function () {
|
||||
return consumer.call(this, schema);
|
||||
}).call(this);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user