Generate schema for extension pack file

This commit is contained in:
Koen Vlaswinkel
2023-09-25 15:24:11 +02:00
parent bc01d73ba5
commit c55e87c64b
7 changed files with 111 additions and 62 deletions

View File

@@ -20,6 +20,21 @@ const schemas = [
"extension-pack-metadata.schema.json",
),
},
{
path: join(
extensionDirectory,
"src",
"model-editor",
"model-extension-file.ts",
),
type: "ModelExtensionFile",
schemaPath: join(
extensionDirectory,
"src",
"model-editor",
"model-extension-file.schema.json",
),
},
];
async function generateSchemas() {

View File

@@ -1,45 +0,0 @@
{
"type": "object",
"properties": {
"extensions": {
"type": "array",
"items": {
"type": "object",
"required": ["addsTo", "data"],
"properties": {
"addsTo": {
"type": "object",
"required": ["pack", "extensible"],
"properties": {
"pack": {
"type": "string"
},
"extensible": {
"type": "string"
}
}
},
"data": {
"type": "array",
"items": {
"type": "array",
"items": {
"oneOf": [
{
"type": "string"
},
{
"type": "boolean"
},
{
"type": "number"
}
]
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,54 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/ModelExtensionFile",
"definitions": {
"ModelExtensionFile": {
"type": "object",
"properties": {
"extensions": {
"type": "array",
"items": {
"$ref": "#/definitions/ModelExtension"
}
}
},
"required": ["extensions"]
},
"ModelExtension": {
"type": "object",
"properties": {
"addsTo": {
"$ref": "#/definitions/ExtensibleReference"
},
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/DataRow"
}
}
},
"required": ["addsTo", "data"]
},
"ExtensibleReference": {
"type": "object",
"properties": {
"pack": {
"type": "string"
},
"extensible": {
"type": "string"
}
},
"required": ["pack", "extensible"]
},
"DataRow": {
"type": "array",
"items": {
"$ref": "#/definitions/DataTuple"
}
},
"DataTuple": {
"type": ["boolean", "number", "string"]
}
}
}

View File

@@ -0,0 +1,17 @@
export type ExtensibleReference = {
pack: string;
extensible: string;
};
export type DataTuple = boolean | number | string;
export type DataRow = DataTuple[];
export type ModelExtension = {
addsTo: ExtensibleReference;
data: DataRow[];
};
export type ModelExtensionFile = {
extensions: ModelExtension[];
};

View File

@@ -1,16 +1,15 @@
import { ModeledMethod, ModeledMethodType, Provenance } from "./modeled-method";
import { DataTuple } from "./model-extension-file";
export type ExtensiblePredicateDefinition = {
extensiblePredicate: string;
generateMethodDefinition: (method: ModeledMethod) => Tuple[];
readModeledMethod: (row: Tuple[]) => ModeledMethod;
generateMethodDefinition: (method: ModeledMethod) => DataTuple[];
readModeledMethod: (row: DataTuple[]) => ModeledMethod;
supportedKinds?: string[];
};
type Tuple = boolean | number | string;
function readRowToMethod(row: Tuple[]): string {
function readRowToMethod(row: DataTuple[]): string {
return `${row[0]}.${row[1]}#${row[3]}${row[4]}`;
}

View File

@@ -7,12 +7,13 @@ import {
extensiblePredicateDefinitions,
} from "./predicates";
import * as dataSchemaJson from "./data-schema.json";
import * as modelExtensionFileSchema from "./model-extension-file.schema.json";
import { Mode } from "./shared/mode";
import { assertNever } from "../common/helpers-pure";
import { ModelExtensionFile } from "./model-extension-file";
const ajv = new Ajv({ allErrors: true });
const dataSchemaValidate = ajv.compile(dataSchemaJson);
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true });
const modelExtensionFileSchemaValidate = ajv.compile(modelExtensionFileSchema);
function createDataProperty(
methods: ModeledMethod[],
@@ -211,24 +212,29 @@ export function createFilenameForPackage(
return `${prefix}${packageName}${suffix}.yml`;
}
export function loadDataExtensionYaml(
data: any,
): Record<string, ModeledMethod> | undefined {
dataSchemaValidate(data);
function validateModelExtensionFile(data: unknown): data is ModelExtensionFile {
modelExtensionFileSchemaValidate(data);
if (dataSchemaValidate.errors) {
if (modelExtensionFileSchemaValidate.errors) {
throw new Error(
`Invalid data extension YAML: ${dataSchemaValidate.errors
`Invalid data extension YAML: ${modelExtensionFileSchemaValidate.errors
.map((error) => `${error.instancePath} ${error.message}`)
.join(", ")}`,
);
}
const extensions = data.extensions;
if (!Array.isArray(extensions)) {
return true;
}
export function loadDataExtensionYaml(
data: unknown,
): Record<string, ModeledMethod> | undefined {
if (!validateModelExtensionFile(data)) {
return undefined;
}
const extensions = data.extensions;
const modeledMethods: Record<string, ModeledMethod> = {};
for (const extension of extensions) {

View File

@@ -20,6 +20,7 @@ import { pathExists, readFile } from "fs-extra";
import { load as loadYaml } from "js-yaml";
import { CancellationTokenSource } from "vscode-jsonrpc";
import { QueryOutputDir } from "../../../../src/run-queries-shared";
import { ModelExtensionFile } from "../../../../src/model-editor/model-extension-file";
describe("runAutoModelQueries", () => {
let resolveQueriesSpy: jest.SpiedFunction<
@@ -186,7 +187,9 @@ describe("generateCandidateFilterPack", () => {
const filterFile = join(packDir, "filter.yml");
expect(await pathExists(filterFile)).toBe(true);
// Read the contents of filterFile and parse as yaml
const yaml = await loadYaml(await readFile(filterFile, "utf8"));
const yaml = (await loadYaml(
await readFile(filterFile, "utf8"),
)) as ModelExtensionFile;
const extensions = yaml.extensions;
expect(extensions).toBeInstanceOf(Array);
expect(extensions).toHaveLength(1);