Generate schema for extension pack file
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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[];
|
||||
};
|
||||
@@ -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]}`;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user