feat: improve monorepo dev experience

This commit is contained in:
2023-10-27 22:45:44 +02:00
parent f618725598
commit c6ab4ae48b
124 changed files with 2647 additions and 2857 deletions

View File

@@ -0,0 +1,78 @@
{
"name": "@openstapps/json-schema-generator",
"description": "Validator for @openstapps/core",
"version": "3.0.0",
"type": "module",
"license": "GPL-3.0-only",
"repository": "git@gitlab.com:openstapps/openstapps.git",
"author": "Thea Schöbl <dev@theaninova.de>",
"keywords": [
"StApps",
"StAppsCore",
"converter",
"core",
"validator"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib",
"README.md",
"CHANGELOG.md"
],
"scripts": {
"build": "tsup-node --dts",
"docs": "typedoc --json ./docs/docs.json --options ../../typedoc.base.json src/index.ts",
"format": "prettier . -c --ignore-path ../../.gitignore",
"format:fix": "prettier --write . --ignore-path ../../.gitignore",
"lint": "eslint --ext .ts src/",
"lint:fix": "eslint --fix --ext .ts src/",
"test": "c8 mocha"
},
"dependencies": {
"@openstapps/tsup-plugin": "workspace:*",
"deepmerge": "4.3.1",
"ts-json-schema-generator": "1.4.0"
},
"devDependencies": {
"@openstapps/eslint-config": "workspace:*",
"@openstapps/prettier-config": "workspace:*",
"@openstapps/tsconfig": "workspace:*",
"@types/chai": "4.3.5",
"@types/fs-extra": "9.0.13",
"@types/glob": "8.0.1",
"@types/json-schema": "7.0.14",
"@types/mocha": "10.0.1",
"@types/mustache": "4.2.2",
"@types/node": "18.15.3",
"c8": "7.14.0",
"chai": "4.3.7",
"esbuild": "0.17.19",
"mocha": "10.2.0",
"mocha-junit-reporter": "2.2.0",
"nock": "13.3.1",
"ts-node": "10.9.1",
"tsup": "6.7.0",
"typedoc": "0.24.8",
"typescript": "5.1.6"
},
"tsup": {
"entry": [
"src/app.ts",
"src/index.ts"
],
"sourcemap": true,
"clean": true,
"format": "esm",
"outDir": "lib"
},
"prettier": "@openstapps/prettier-config",
"eslintConfig": {
"extends": [
"@openstapps"
]
},
"eslintIgnore": [
"resources"
]
}

View File

@@ -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;
}

View File

@@ -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';
}

View 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);
}
},
};
}

View File

@@ -0,0 +1,3 @@
{
"extends": "@openstapps/tsconfig"
}