@genetik/schema 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +39 -0
- package/dist/index.cjs +204 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +159 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +159 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +169 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Eugene Michasiw
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @genetik/schema
|
|
2
|
+
|
|
3
|
+
Block types, config (JSON Schema), slots, and reference modes for the Genetik JSON-driven UI ecosystem.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @genetik/schema
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import {
|
|
15
|
+
createSchema,
|
|
16
|
+
registerBlockType,
|
|
17
|
+
getBlockType,
|
|
18
|
+
validateConfig,
|
|
19
|
+
} from "@genetik/schema";
|
|
20
|
+
|
|
21
|
+
const schema = createSchema({ version: "1.0.0" });
|
|
22
|
+
registerBlockType(schema, {
|
|
23
|
+
name: "text",
|
|
24
|
+
configSchema: { type: "object", properties: { content: { type: "string" } }, required: ["content"] },
|
|
25
|
+
slots: [],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const result = validateConfig(schema, "text", { content: "Hello" });
|
|
29
|
+
// result.valid === true
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
See the [docs](https://github.com/...) or `apps/docs/docs/packages/schema.md` in the repo for full API and concepts.
|
|
33
|
+
|
|
34
|
+
## Scripts
|
|
35
|
+
|
|
36
|
+
- `pnpm build` - Build with tsdown (ESM + CJS + types)
|
|
37
|
+
- `pnpm test` - Run tests
|
|
38
|
+
- `pnpm check-types` - TypeScript check
|
|
39
|
+
- `pnpm lint` - ESLint
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: ((k) => from[k]).bind(null, key),
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
24
|
+
value: mod,
|
|
25
|
+
enumerable: true
|
|
26
|
+
}) : target, mod));
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
let ajv = require("ajv");
|
|
30
|
+
ajv = __toESM(ajv);
|
|
31
|
+
let ajv_formats = require("ajv-formats");
|
|
32
|
+
ajv_formats = __toESM(ajv_formats);
|
|
33
|
+
|
|
34
|
+
//#region src/registry.ts
|
|
35
|
+
const DEFAULT_REFERENCE_MODE = "id";
|
|
36
|
+
function resolveOptions(configOptions) {
|
|
37
|
+
return {
|
|
38
|
+
slotReferenceMode: DEFAULT_REFERENCE_MODE,
|
|
39
|
+
...configOptions
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function toSlotDefinition(slot, referenceMode) {
|
|
43
|
+
return {
|
|
44
|
+
name: slot.name,
|
|
45
|
+
multiple: slot.multiple,
|
|
46
|
+
referenceMode
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function toBlockTypeDefinition(block, referenceMode) {
|
|
50
|
+
return {
|
|
51
|
+
name: block.name,
|
|
52
|
+
configSchema: block.configSchema,
|
|
53
|
+
slots: block.slots.map((s) => toSlotDefinition(s, referenceMode))
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function buildContentSchema(blockNames) {
|
|
57
|
+
return {
|
|
58
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
59
|
+
type: "object",
|
|
60
|
+
required: ["entryId", "nodes"],
|
|
61
|
+
properties: {
|
|
62
|
+
entryId: { type: "string" },
|
|
63
|
+
nodes: {
|
|
64
|
+
type: "object",
|
|
65
|
+
additionalProperties: { $ref: "#/definitions/ContentNode" }
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
definitions: { ContentNode: {
|
|
69
|
+
type: "object",
|
|
70
|
+
required: [
|
|
71
|
+
"id",
|
|
72
|
+
"block",
|
|
73
|
+
"config"
|
|
74
|
+
],
|
|
75
|
+
properties: {
|
|
76
|
+
id: { type: "string" },
|
|
77
|
+
block: blockNames.length > 0 ? {
|
|
78
|
+
type: "string",
|
|
79
|
+
enum: blockNames
|
|
80
|
+
} : { type: "string" },
|
|
81
|
+
config: { type: "object" }
|
|
82
|
+
},
|
|
83
|
+
additionalProperties: true
|
|
84
|
+
} }
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Creates a schema from config. Runs plugins (which can register blocks and add options),
|
|
89
|
+
* then builds block types with global slotReferenceMode. Returns the schema with getters
|
|
90
|
+
* and a contentSchema (JSON Schema for the content document).
|
|
91
|
+
*/
|
|
92
|
+
function createSchema(config) {
|
|
93
|
+
const blocks = [...config.registerBlocks ?? []];
|
|
94
|
+
const options = resolveOptions(config.options);
|
|
95
|
+
const context = {
|
|
96
|
+
registerBlock(block) {
|
|
97
|
+
blocks.push(block);
|
|
98
|
+
},
|
|
99
|
+
options,
|
|
100
|
+
version: config.version
|
|
101
|
+
};
|
|
102
|
+
for (const plugin of config.registerPlugins ?? []) plugin(context);
|
|
103
|
+
const referenceMode = options.slotReferenceMode ?? DEFAULT_REFERENCE_MODE;
|
|
104
|
+
const blockTypes = /* @__PURE__ */ new Map();
|
|
105
|
+
for (const block of blocks) blockTypes.set(block.name, toBlockTypeDefinition(block, referenceMode));
|
|
106
|
+
const contentSchema = buildContentSchema(Array.from(blockTypes.keys()));
|
|
107
|
+
return {
|
|
108
|
+
blockTypes,
|
|
109
|
+
meta: config.version !== void 0 ? { version: config.version } : void 0,
|
|
110
|
+
contentSchema,
|
|
111
|
+
options,
|
|
112
|
+
version: config.version,
|
|
113
|
+
getBlockType(name) {
|
|
114
|
+
return blockTypes.get(name);
|
|
115
|
+
},
|
|
116
|
+
getBlockTypeNames() {
|
|
117
|
+
return Array.from(blockTypes.keys());
|
|
118
|
+
},
|
|
119
|
+
hasBlockType(name) {
|
|
120
|
+
return blockTypes.has(name);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Returns the block type definition for the given name, or undefined if not registered.
|
|
126
|
+
*/
|
|
127
|
+
function getBlockType(schema, name) {
|
|
128
|
+
return schema.blockTypes.get(name);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Returns true if the schema has a block type with the given name.
|
|
132
|
+
*/
|
|
133
|
+
function hasBlockType(schema, name) {
|
|
134
|
+
return schema.blockTypes.has(name);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Returns all registered block type names.
|
|
138
|
+
*/
|
|
139
|
+
function getBlockTypeNames(schema) {
|
|
140
|
+
return Array.from(schema.blockTypes.keys());
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/validate.ts
|
|
145
|
+
const Ajv = ajv.default;
|
|
146
|
+
const addFormats = ajv_formats.default;
|
|
147
|
+
const ajv$1 = new Ajv({
|
|
148
|
+
allErrors: true,
|
|
149
|
+
strict: false
|
|
150
|
+
});
|
|
151
|
+
addFormats(ajv$1);
|
|
152
|
+
/**
|
|
153
|
+
* Validates a config object against a block type's JSON Schema.
|
|
154
|
+
* Returns { valid: true, errors: null } on success, or { valid: false, errors } on failure.
|
|
155
|
+
*/
|
|
156
|
+
function validateConfig(schema, blockTypeName, config) {
|
|
157
|
+
const blockType = getBlockType(schema, blockTypeName);
|
|
158
|
+
if (!blockType) return {
|
|
159
|
+
valid: false,
|
|
160
|
+
errors: [{
|
|
161
|
+
instancePath: "",
|
|
162
|
+
schemaPath: "",
|
|
163
|
+
keyword: "blockType",
|
|
164
|
+
message: `Unknown block type: ${blockTypeName}`,
|
|
165
|
+
params: {}
|
|
166
|
+
}]
|
|
167
|
+
};
|
|
168
|
+
return validateConfigAgainstDefinition(blockType, config);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Validates a config object against a block type definition's JSON Schema.
|
|
172
|
+
* Use this when you already have the BlockTypeDefinition (e.g. from getBlockType).
|
|
173
|
+
*/
|
|
174
|
+
function validateConfigAgainstDefinition(blockType, config) {
|
|
175
|
+
let validate;
|
|
176
|
+
try {
|
|
177
|
+
validate = ajv$1.compile(blockType.configSchema);
|
|
178
|
+
} catch (err) {
|
|
179
|
+
return {
|
|
180
|
+
valid: false,
|
|
181
|
+
errors: [{
|
|
182
|
+
instancePath: "",
|
|
183
|
+
schemaPath: "",
|
|
184
|
+
keyword: "schema",
|
|
185
|
+
message: err instanceof Error ? err.message : "Invalid config schema",
|
|
186
|
+
params: {}
|
|
187
|
+
}]
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
const valid = validate(config);
|
|
191
|
+
return {
|
|
192
|
+
valid,
|
|
193
|
+
errors: valid ? null : validate.errors ?? []
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
//#endregion
|
|
198
|
+
exports.createSchema = createSchema;
|
|
199
|
+
exports.getBlockType = getBlockType;
|
|
200
|
+
exports.getBlockTypeNames = getBlockTypeNames;
|
|
201
|
+
exports.hasBlockType = hasBlockType;
|
|
202
|
+
exports.validateConfig = validateConfig;
|
|
203
|
+
exports.validateConfigAgainstDefinition = validateConfigAgainstDefinition;
|
|
204
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["AjvDefault","addFormatsDefault","ajv"],"sources":["../src/registry.ts","../src/validate.ts"],"sourcesContent":["import type {\n BlockInput,\n BlockTypeDefinition,\n GenetikSchema,\n JsonSchema,\n SchemaConfig,\n SchemaOptions,\n SlotDefinition,\n SlotReferenceMode,\n} from \"./types.js\";\n\nconst DEFAULT_REFERENCE_MODE: SlotReferenceMode = \"id\";\n\nfunction resolveOptions(configOptions?: SchemaOptions): SchemaOptions {\n return {\n slotReferenceMode: DEFAULT_REFERENCE_MODE,\n ...configOptions,\n };\n}\n\nfunction toSlotDefinition(slot: { name: string; multiple: boolean }, referenceMode: SlotReferenceMode): SlotDefinition {\n return {\n name: slot.name,\n multiple: slot.multiple,\n referenceMode,\n };\n}\n\nfunction toBlockTypeDefinition(block: BlockInput, referenceMode: SlotReferenceMode): BlockTypeDefinition {\n return {\n name: block.name,\n configSchema: block.configSchema,\n slots: block.slots.map((s) => toSlotDefinition(s, referenceMode)),\n };\n}\n\nfunction buildContentSchema(blockNames: string[]): JsonSchema {\n return {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n required: [\"entryId\", \"nodes\"],\n properties: {\n entryId: { type: \"string\" },\n nodes: {\n type: \"object\",\n additionalProperties: { $ref: \"#/definitions/ContentNode\" },\n },\n },\n definitions: {\n ContentNode: {\n type: \"object\",\n required: [\"id\", \"block\", \"config\"],\n properties: {\n id: { type: \"string\" },\n block: blockNames.length > 0 ? { type: \"string\", enum: blockNames } : { type: \"string\" },\n config: { type: \"object\" },\n },\n additionalProperties: true,\n },\n },\n };\n}\n\nexport interface SchemaInstance extends GenetikSchema {\n /** JSON Schema that describes the content document (entryId + nodes). */\n contentSchema: JsonSchema;\n /** Resolved options (includes slotReferenceMode). */\n options: SchemaOptions;\n /** Schema version if set. */\n version?: string;\n getBlockType(name: string): BlockTypeDefinition | undefined;\n getBlockTypeNames(): string[];\n hasBlockType(name: string): boolean;\n}\n\n/**\n * Creates a schema from config. Runs plugins (which can register blocks and add options),\n * then builds block types with global slotReferenceMode. Returns the schema with getters\n * and a contentSchema (JSON Schema for the content document).\n */\nexport function createSchema(config: SchemaConfig): SchemaInstance {\n const blocks: BlockInput[] = [...(config.registerBlocks ?? [])];\n const options = resolveOptions(config.options);\n\n const context: import(\"./types.js\").SchemaPluginContext = {\n registerBlock(block: BlockInput) {\n blocks.push(block);\n },\n options,\n version: config.version,\n };\n\n for (const plugin of config.registerPlugins ?? []) {\n plugin(context);\n }\n\n const referenceMode = (options.slotReferenceMode ?? DEFAULT_REFERENCE_MODE) as SlotReferenceMode;\n const blockTypes = new Map<string, BlockTypeDefinition>();\n for (const block of blocks) {\n blockTypes.set(block.name, toBlockTypeDefinition(block, referenceMode));\n }\n\n const blockNames = Array.from(blockTypes.keys());\n const contentSchema = buildContentSchema(blockNames);\n\n const schema: GenetikSchema = {\n blockTypes,\n meta: config.version !== undefined ? { version: config.version } : undefined,\n };\n\n return {\n ...schema,\n contentSchema,\n options,\n version: config.version,\n getBlockType(name: string) {\n return blockTypes.get(name);\n },\n getBlockTypeNames() {\n return Array.from(blockTypes.keys());\n },\n hasBlockType(name: string) {\n return blockTypes.has(name);\n },\n };\n}\n\n/**\n * Returns the block type definition for the given name, or undefined if not registered.\n */\nexport function getBlockType(schema: GenetikSchema, name: string): BlockTypeDefinition | undefined {\n return schema.blockTypes.get(name);\n}\n\n/**\n * Returns true if the schema has a block type with the given name.\n */\nexport function hasBlockType(schema: GenetikSchema, name: string): boolean {\n return schema.blockTypes.has(name);\n}\n\n/**\n * Returns all registered block type names.\n */\nexport function getBlockTypeNames(schema: GenetikSchema): string[] {\n return Array.from(schema.blockTypes.keys());\n}\n","import AjvDefault from \"ajv\";\nimport addFormatsDefault from \"ajv-formats\";\nimport type { ErrorObject, ValidateFunction } from \"ajv\";\nimport type { BlockTypeDefinition, GenetikSchema } from \"./types.js\";\nimport { getBlockType } from \"./registry.js\";\n\n// ESM/NodeNext: default export types don't expose constructor/call; assert through unknown\nconst Ajv = AjvDefault as unknown as new (opts?: { allErrors?: boolean; strict?: boolean }) => { compile: (schema: object) => ValidateFunction };\nconst addFormats = addFormatsDefault as unknown as (ajv: InstanceType<typeof Ajv>) => void;\nconst ajv = new Ajv({ allErrors: true, strict: false });\naddFormats(ajv);\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ErrorObject[] | null;\n}\n\n/**\n * Validates a config object against a block type's JSON Schema.\n * Returns { valid: true, errors: null } on success, or { valid: false, errors } on failure.\n */\nexport function validateConfig(\n schema: GenetikSchema,\n blockTypeName: string,\n config: unknown\n): ValidationResult {\n const blockType = getBlockType(schema, blockTypeName);\n if (!blockType) {\n return {\n valid: false,\n errors: [\n {\n instancePath: \"\",\n schemaPath: \"\",\n keyword: \"blockType\",\n message: `Unknown block type: ${blockTypeName}`,\n params: {},\n } satisfies ErrorObject,\n ],\n };\n }\n return validateConfigAgainstDefinition(blockType, config);\n}\n\n/**\n * Validates a config object against a block type definition's JSON Schema.\n * Use this when you already have the BlockTypeDefinition (e.g. from getBlockType).\n */\nexport function validateConfigAgainstDefinition(\n blockType: BlockTypeDefinition,\n config: unknown\n): ValidationResult {\n let validate: ValidateFunction;\n try {\n validate = ajv.compile(blockType.configSchema);\n } catch (err) {\n return {\n valid: false,\n errors: [\n {\n instancePath: \"\",\n schemaPath: \"\",\n keyword: \"schema\",\n message: err instanceof Error ? err.message : \"Invalid config schema\",\n params: {},\n } satisfies ErrorObject,\n ],\n };\n }\n const valid = validate(config);\n return {\n valid,\n errors: valid ? null : (validate.errors ?? []),\n };\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { ErrorObject } from "ajv";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Reference mode for slots (global on schema). How child nodes can be specified.
|
|
6
|
+
* - id: slot value is an id or array of ids (canonical form).
|
|
7
|
+
* - inline: slot may contain inline node(s), normalized to flat + ids before storage/rendering.
|
|
8
|
+
* - both: slot accepts either id(s) or inline node(s).
|
|
9
|
+
*/
|
|
10
|
+
type SlotReferenceMode = "id" | "inline" | "both";
|
|
11
|
+
/**
|
|
12
|
+
* Slot definition at runtime: has referenceMode (from schema options).
|
|
13
|
+
*/
|
|
14
|
+
interface SlotDefinition {
|
|
15
|
+
/** Slot name (e.g. "children", "header", "footer"). */
|
|
16
|
+
name: string;
|
|
17
|
+
/** If true, slot holds an ordered list of nodes; if false, a single node. */
|
|
18
|
+
multiple: boolean;
|
|
19
|
+
/** From schema options; whether the slot accepts id references, inline nodes, or both. */
|
|
20
|
+
referenceMode: SlotReferenceMode;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Slot input when registering a block. No referenceMode — that comes from schema options.
|
|
24
|
+
*/
|
|
25
|
+
interface SlotInput {
|
|
26
|
+
/** Slot name (e.g. "children", "header", "footer"). */
|
|
27
|
+
name: string;
|
|
28
|
+
/** If true, slot holds an ordered list of nodes; if false, a single node. */
|
|
29
|
+
multiple: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* JSON Schema is a plain object. We use a generic object type for flexibility.
|
|
33
|
+
* Block config is validated against this schema (e.g. via ajv).
|
|
34
|
+
*/
|
|
35
|
+
type JsonSchema = Record<string, unknown>;
|
|
36
|
+
/**
|
|
37
|
+
* Block input when registering. Slots have no referenceMode (global on schema).
|
|
38
|
+
*/
|
|
39
|
+
interface BlockInput {
|
|
40
|
+
/** Block type name (e.g. "hero", "card", "text"). */
|
|
41
|
+
name: string;
|
|
42
|
+
/** JSON Schema for this block's config. */
|
|
43
|
+
configSchema: JsonSchema;
|
|
44
|
+
/** Slots this block exposes. */
|
|
45
|
+
slots: SlotInput[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Runtime block type: slots have referenceMode filled from schema options.
|
|
49
|
+
*/
|
|
50
|
+
interface BlockTypeDefinition {
|
|
51
|
+
/** Block type name (e.g. "hero", "card", "text"). */
|
|
52
|
+
name: string;
|
|
53
|
+
/** JSON Schema for this block's config. */
|
|
54
|
+
configSchema: JsonSchema;
|
|
55
|
+
/** Slots with referenceMode applied. */
|
|
56
|
+
slots: SlotDefinition[];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Schema-level options. slotReferenceMode applies to all slots globally.
|
|
60
|
+
*/
|
|
61
|
+
interface SchemaOptions {
|
|
62
|
+
/** How slots accept children. Default "id". */
|
|
63
|
+
slotReferenceMode?: SlotReferenceMode;
|
|
64
|
+
[key: string]: unknown;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Context passed to plugins. Plugins can register blocks and read/mutate options.
|
|
68
|
+
*/
|
|
69
|
+
interface SchemaPluginContext {
|
|
70
|
+
/** Register a block type. */
|
|
71
|
+
registerBlock(block: BlockInput): void;
|
|
72
|
+
/** Resolved options (includes slotReferenceMode). Mutate to add plugin options. */
|
|
73
|
+
options: SchemaOptions;
|
|
74
|
+
/** Schema version if set. */
|
|
75
|
+
version?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Build-time plugin. Can register blocks and/or add options.
|
|
79
|
+
*/
|
|
80
|
+
type SchemaPlugin = (context: SchemaPluginContext) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Config for createSchema. Our API (not JSON Schema).
|
|
83
|
+
*/
|
|
84
|
+
interface SchemaConfig {
|
|
85
|
+
/** Block types to register. */
|
|
86
|
+
registerBlocks?: BlockInput[];
|
|
87
|
+
/** Plugins run in order; each can register blocks and add options. */
|
|
88
|
+
registerPlugins?: SchemaPlugin[];
|
|
89
|
+
/** Schema version (e.g. "1.0.0"). */
|
|
90
|
+
version?: string;
|
|
91
|
+
/** Schema options (e.g. slotReferenceMode). Merged with plugin-added options. */
|
|
92
|
+
options?: SchemaOptions;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Schema metadata: version for migrations and compatibility.
|
|
96
|
+
*/
|
|
97
|
+
interface SchemaMeta {
|
|
98
|
+
/** Schema version (e.g. "1.0.0"). */
|
|
99
|
+
version: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Runtime schema: block types + meta. createSchema also adds contentSchema and getters.
|
|
103
|
+
*/
|
|
104
|
+
interface GenetikSchema {
|
|
105
|
+
/** Map of block type name to definition. */
|
|
106
|
+
blockTypes: Map<string, BlockTypeDefinition>;
|
|
107
|
+
/** Optional schema metadata (e.g. version). */
|
|
108
|
+
meta?: SchemaMeta;
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region src/registry.d.ts
|
|
112
|
+
interface SchemaInstance extends GenetikSchema {
|
|
113
|
+
/** JSON Schema that describes the content document (entryId + nodes). */
|
|
114
|
+
contentSchema: JsonSchema;
|
|
115
|
+
/** Resolved options (includes slotReferenceMode). */
|
|
116
|
+
options: SchemaOptions;
|
|
117
|
+
/** Schema version if set. */
|
|
118
|
+
version?: string;
|
|
119
|
+
getBlockType(name: string): BlockTypeDefinition | undefined;
|
|
120
|
+
getBlockTypeNames(): string[];
|
|
121
|
+
hasBlockType(name: string): boolean;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Creates a schema from config. Runs plugins (which can register blocks and add options),
|
|
125
|
+
* then builds block types with global slotReferenceMode. Returns the schema with getters
|
|
126
|
+
* and a contentSchema (JSON Schema for the content document).
|
|
127
|
+
*/
|
|
128
|
+
declare function createSchema(config: SchemaConfig): SchemaInstance;
|
|
129
|
+
/**
|
|
130
|
+
* Returns the block type definition for the given name, or undefined if not registered.
|
|
131
|
+
*/
|
|
132
|
+
declare function getBlockType(schema: GenetikSchema, name: string): BlockTypeDefinition | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Returns true if the schema has a block type with the given name.
|
|
135
|
+
*/
|
|
136
|
+
declare function hasBlockType(schema: GenetikSchema, name: string): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Returns all registered block type names.
|
|
139
|
+
*/
|
|
140
|
+
declare function getBlockTypeNames(schema: GenetikSchema): string[];
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region src/validate.d.ts
|
|
143
|
+
interface ValidationResult {
|
|
144
|
+
valid: boolean;
|
|
145
|
+
errors: ErrorObject[] | null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Validates a config object against a block type's JSON Schema.
|
|
149
|
+
* Returns { valid: true, errors: null } on success, or { valid: false, errors } on failure.
|
|
150
|
+
*/
|
|
151
|
+
declare function validateConfig(schema: GenetikSchema, blockTypeName: string, config: unknown): ValidationResult;
|
|
152
|
+
/**
|
|
153
|
+
* Validates a config object against a block type definition's JSON Schema.
|
|
154
|
+
* Use this when you already have the BlockTypeDefinition (e.g. from getBlockType).
|
|
155
|
+
*/
|
|
156
|
+
declare function validateConfigAgainstDefinition(blockType: BlockTypeDefinition, config: unknown): ValidationResult;
|
|
157
|
+
//#endregion
|
|
158
|
+
export { type BlockInput, type BlockTypeDefinition, type GenetikSchema, type JsonSchema, type SchemaConfig, type SchemaInstance, type SchemaMeta, type SchemaOptions, type SchemaPlugin, type SchemaPluginContext, type SlotDefinition, type SlotInput, type SlotReferenceMode, type ValidationResult, createSchema, getBlockType, getBlockTypeNames, hasBlockType, validateConfig, validateConfigAgainstDefinition };
|
|
159
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/registry.ts","../src/validate.ts"],"mappings":";;;;;;AAMA;;;KAAY,iBAAA;;AAKZ;;UAAiB,cAAA;EAMiB;EAJhC,IAAA;EAEA;EAAA,QAAA;EAEe;EAAf,aAAA,EAAe,iBAAA;AAAA;AAMjB;;;AAAA,UAAiB,SAAA;EAIP;EAFR,IAAA;EASoB;EAPpB,QAAA;AAAA;;AAYF;;;KALY,UAAA,GAAa,MAAA;;;;UAKR,UAAA;EAMR;EAJP,IAAA;EAIgB;EAFhB,YAAA,EAAc,UAAA;EAQoB;EANlC,KAAA,EAAO,SAAA;AAAA;;;;UAMQ,mBAAA;EAMR;EAJP,IAAA;EAIqB;EAFrB,YAAA,EAAc,UAAA;EAQc;EAN5B,KAAA,EAAO,cAAA;AAAA;;;;UAMQ,aAAA;EAGH;EADZ,iBAAA,GAAoB,iBAAA;EAAA,CACnB,GAAA;AAAA;;;;UAMc,mBAAA;EAIf;EAFA,aAAA,CAAc,KAAA,EAAO,UAAA;EAIrB;EAFA,OAAA,EAAS,aAAA;EAEF;EAAP,OAAA;AAAA;;;;KAMU,YAAA,IAAgB,OAAA,EAAS,mBAAA;;;;UAKpB,YAAA;EAQL;EANV,cAAA,GAAiB,UAAA;EAMM;EAJvB,eAAA,GAAkB,YAAA;EAFD;EAIjB,OAAA;EAFkB;EAIlB,OAAA,GAAU,aAAA;AAAA;;;;UAMK,UAAA;EAAU;EAEzB,OAAA;AAAA;;AAMF;;UAAiB,aAAA;EAES;EAAxB,UAAA,EAAY,GAAA,SAAY,mBAAA;EAEjB;EAAP,IAAA,GAAO,UAAA;AAAA;;;UCpDQ,cAAA,SAAuB,aAAA;;EAEtC,aAAA,EAAe,UAAA;ED3DY;EC6D3B,OAAA,EAAS,aAAA;ED7DkB;EC+D3B,OAAA;EACA,YAAA,CAAa,IAAA,WAAe,mBAAA;EAC5B,iBAAA;EACA,YAAA,CAAa,IAAA;AAAA;;;;;;iBAQC,YAAA,CAAa,MAAA,EAAQ,YAAA,GAAe,cAAA;ADzDpD;;;AAAA,iBC2GgB,YAAA,CAAa,MAAA,EAAQ,aAAA,EAAe,IAAA,WAAe,mBAAA;;ADhGnE;;iBCuGgB,YAAA,CAAa,MAAA,EAAQ,aAAA,EAAe,IAAA;;;ADlGpD;iBCyGgB,iBAAA,CAAkB,MAAA,EAAQ,aAAA;;;UCpIzB,gBAAA;EACf,KAAA;EACA,MAAA,EAAQ,WAAA;AAAA;;;AFHV;;iBEUgB,cAAA,CACd,MAAA,EAAQ,aAAA,EACR,aAAA,UACA,MAAA,YACC,gBAAA;;;;;iBAuBa,+BAAA,CACd,SAAA,EAAW,mBAAA,EACX,MAAA,YACC,gBAAA"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { ErrorObject } from "ajv";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Reference mode for slots (global on schema). How child nodes can be specified.
|
|
6
|
+
* - id: slot value is an id or array of ids (canonical form).
|
|
7
|
+
* - inline: slot may contain inline node(s), normalized to flat + ids before storage/rendering.
|
|
8
|
+
* - both: slot accepts either id(s) or inline node(s).
|
|
9
|
+
*/
|
|
10
|
+
type SlotReferenceMode = "id" | "inline" | "both";
|
|
11
|
+
/**
|
|
12
|
+
* Slot definition at runtime: has referenceMode (from schema options).
|
|
13
|
+
*/
|
|
14
|
+
interface SlotDefinition {
|
|
15
|
+
/** Slot name (e.g. "children", "header", "footer"). */
|
|
16
|
+
name: string;
|
|
17
|
+
/** If true, slot holds an ordered list of nodes; if false, a single node. */
|
|
18
|
+
multiple: boolean;
|
|
19
|
+
/** From schema options; whether the slot accepts id references, inline nodes, or both. */
|
|
20
|
+
referenceMode: SlotReferenceMode;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Slot input when registering a block. No referenceMode — that comes from schema options.
|
|
24
|
+
*/
|
|
25
|
+
interface SlotInput {
|
|
26
|
+
/** Slot name (e.g. "children", "header", "footer"). */
|
|
27
|
+
name: string;
|
|
28
|
+
/** If true, slot holds an ordered list of nodes; if false, a single node. */
|
|
29
|
+
multiple: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* JSON Schema is a plain object. We use a generic object type for flexibility.
|
|
33
|
+
* Block config is validated against this schema (e.g. via ajv).
|
|
34
|
+
*/
|
|
35
|
+
type JsonSchema = Record<string, unknown>;
|
|
36
|
+
/**
|
|
37
|
+
* Block input when registering. Slots have no referenceMode (global on schema).
|
|
38
|
+
*/
|
|
39
|
+
interface BlockInput {
|
|
40
|
+
/** Block type name (e.g. "hero", "card", "text"). */
|
|
41
|
+
name: string;
|
|
42
|
+
/** JSON Schema for this block's config. */
|
|
43
|
+
configSchema: JsonSchema;
|
|
44
|
+
/** Slots this block exposes. */
|
|
45
|
+
slots: SlotInput[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Runtime block type: slots have referenceMode filled from schema options.
|
|
49
|
+
*/
|
|
50
|
+
interface BlockTypeDefinition {
|
|
51
|
+
/** Block type name (e.g. "hero", "card", "text"). */
|
|
52
|
+
name: string;
|
|
53
|
+
/** JSON Schema for this block's config. */
|
|
54
|
+
configSchema: JsonSchema;
|
|
55
|
+
/** Slots with referenceMode applied. */
|
|
56
|
+
slots: SlotDefinition[];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Schema-level options. slotReferenceMode applies to all slots globally.
|
|
60
|
+
*/
|
|
61
|
+
interface SchemaOptions {
|
|
62
|
+
/** How slots accept children. Default "id". */
|
|
63
|
+
slotReferenceMode?: SlotReferenceMode;
|
|
64
|
+
[key: string]: unknown;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Context passed to plugins. Plugins can register blocks and read/mutate options.
|
|
68
|
+
*/
|
|
69
|
+
interface SchemaPluginContext {
|
|
70
|
+
/** Register a block type. */
|
|
71
|
+
registerBlock(block: BlockInput): void;
|
|
72
|
+
/** Resolved options (includes slotReferenceMode). Mutate to add plugin options. */
|
|
73
|
+
options: SchemaOptions;
|
|
74
|
+
/** Schema version if set. */
|
|
75
|
+
version?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Build-time plugin. Can register blocks and/or add options.
|
|
79
|
+
*/
|
|
80
|
+
type SchemaPlugin = (context: SchemaPluginContext) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Config for createSchema. Our API (not JSON Schema).
|
|
83
|
+
*/
|
|
84
|
+
interface SchemaConfig {
|
|
85
|
+
/** Block types to register. */
|
|
86
|
+
registerBlocks?: BlockInput[];
|
|
87
|
+
/** Plugins run in order; each can register blocks and add options. */
|
|
88
|
+
registerPlugins?: SchemaPlugin[];
|
|
89
|
+
/** Schema version (e.g. "1.0.0"). */
|
|
90
|
+
version?: string;
|
|
91
|
+
/** Schema options (e.g. slotReferenceMode). Merged with plugin-added options. */
|
|
92
|
+
options?: SchemaOptions;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Schema metadata: version for migrations and compatibility.
|
|
96
|
+
*/
|
|
97
|
+
interface SchemaMeta {
|
|
98
|
+
/** Schema version (e.g. "1.0.0"). */
|
|
99
|
+
version: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Runtime schema: block types + meta. createSchema also adds contentSchema and getters.
|
|
103
|
+
*/
|
|
104
|
+
interface GenetikSchema {
|
|
105
|
+
/** Map of block type name to definition. */
|
|
106
|
+
blockTypes: Map<string, BlockTypeDefinition>;
|
|
107
|
+
/** Optional schema metadata (e.g. version). */
|
|
108
|
+
meta?: SchemaMeta;
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region src/registry.d.ts
|
|
112
|
+
interface SchemaInstance extends GenetikSchema {
|
|
113
|
+
/** JSON Schema that describes the content document (entryId + nodes). */
|
|
114
|
+
contentSchema: JsonSchema;
|
|
115
|
+
/** Resolved options (includes slotReferenceMode). */
|
|
116
|
+
options: SchemaOptions;
|
|
117
|
+
/** Schema version if set. */
|
|
118
|
+
version?: string;
|
|
119
|
+
getBlockType(name: string): BlockTypeDefinition | undefined;
|
|
120
|
+
getBlockTypeNames(): string[];
|
|
121
|
+
hasBlockType(name: string): boolean;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Creates a schema from config. Runs plugins (which can register blocks and add options),
|
|
125
|
+
* then builds block types with global slotReferenceMode. Returns the schema with getters
|
|
126
|
+
* and a contentSchema (JSON Schema for the content document).
|
|
127
|
+
*/
|
|
128
|
+
declare function createSchema(config: SchemaConfig): SchemaInstance;
|
|
129
|
+
/**
|
|
130
|
+
* Returns the block type definition for the given name, or undefined if not registered.
|
|
131
|
+
*/
|
|
132
|
+
declare function getBlockType(schema: GenetikSchema, name: string): BlockTypeDefinition | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Returns true if the schema has a block type with the given name.
|
|
135
|
+
*/
|
|
136
|
+
declare function hasBlockType(schema: GenetikSchema, name: string): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Returns all registered block type names.
|
|
139
|
+
*/
|
|
140
|
+
declare function getBlockTypeNames(schema: GenetikSchema): string[];
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region src/validate.d.ts
|
|
143
|
+
interface ValidationResult {
|
|
144
|
+
valid: boolean;
|
|
145
|
+
errors: ErrorObject[] | null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Validates a config object against a block type's JSON Schema.
|
|
149
|
+
* Returns { valid: true, errors: null } on success, or { valid: false, errors } on failure.
|
|
150
|
+
*/
|
|
151
|
+
declare function validateConfig(schema: GenetikSchema, blockTypeName: string, config: unknown): ValidationResult;
|
|
152
|
+
/**
|
|
153
|
+
* Validates a config object against a block type definition's JSON Schema.
|
|
154
|
+
* Use this when you already have the BlockTypeDefinition (e.g. from getBlockType).
|
|
155
|
+
*/
|
|
156
|
+
declare function validateConfigAgainstDefinition(blockType: BlockTypeDefinition, config: unknown): ValidationResult;
|
|
157
|
+
//#endregion
|
|
158
|
+
export { type BlockInput, type BlockTypeDefinition, type GenetikSchema, type JsonSchema, type SchemaConfig, type SchemaInstance, type SchemaMeta, type SchemaOptions, type SchemaPlugin, type SchemaPluginContext, type SlotDefinition, type SlotInput, type SlotReferenceMode, type ValidationResult, createSchema, getBlockType, getBlockTypeNames, hasBlockType, validateConfig, validateConfigAgainstDefinition };
|
|
159
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/registry.ts","../src/validate.ts"],"mappings":";;;;;;AAMA;;;KAAY,iBAAA;;AAKZ;;UAAiB,cAAA;EAMiB;EAJhC,IAAA;EAEA;EAAA,QAAA;EAEe;EAAf,aAAA,EAAe,iBAAA;AAAA;AAMjB;;;AAAA,UAAiB,SAAA;EAIP;EAFR,IAAA;EASoB;EAPpB,QAAA;AAAA;;AAYF;;;KALY,UAAA,GAAa,MAAA;;;;UAKR,UAAA;EAMR;EAJP,IAAA;EAIgB;EAFhB,YAAA,EAAc,UAAA;EAQoB;EANlC,KAAA,EAAO,SAAA;AAAA;;;;UAMQ,mBAAA;EAMR;EAJP,IAAA;EAIqB;EAFrB,YAAA,EAAc,UAAA;EAQc;EAN5B,KAAA,EAAO,cAAA;AAAA;;;;UAMQ,aAAA;EAGH;EADZ,iBAAA,GAAoB,iBAAA;EAAA,CACnB,GAAA;AAAA;;;;UAMc,mBAAA;EAIf;EAFA,aAAA,CAAc,KAAA,EAAO,UAAA;EAIrB;EAFA,OAAA,EAAS,aAAA;EAEF;EAAP,OAAA;AAAA;;;;KAMU,YAAA,IAAgB,OAAA,EAAS,mBAAA;;;;UAKpB,YAAA;EAQL;EANV,cAAA,GAAiB,UAAA;EAMM;EAJvB,eAAA,GAAkB,YAAA;EAFD;EAIjB,OAAA;EAFkB;EAIlB,OAAA,GAAU,aAAA;AAAA;;;;UAMK,UAAA;EAAU;EAEzB,OAAA;AAAA;;AAMF;;UAAiB,aAAA;EAES;EAAxB,UAAA,EAAY,GAAA,SAAY,mBAAA;EAEjB;EAAP,IAAA,GAAO,UAAA;AAAA;;;UCpDQ,cAAA,SAAuB,aAAA;;EAEtC,aAAA,EAAe,UAAA;ED3DY;EC6D3B,OAAA,EAAS,aAAA;ED7DkB;EC+D3B,OAAA;EACA,YAAA,CAAa,IAAA,WAAe,mBAAA;EAC5B,iBAAA;EACA,YAAA,CAAa,IAAA;AAAA;;;;;;iBAQC,YAAA,CAAa,MAAA,EAAQ,YAAA,GAAe,cAAA;ADzDpD;;;AAAA,iBC2GgB,YAAA,CAAa,MAAA,EAAQ,aAAA,EAAe,IAAA,WAAe,mBAAA;;ADhGnE;;iBCuGgB,YAAA,CAAa,MAAA,EAAQ,aAAA,EAAe,IAAA;;;ADlGpD;iBCyGgB,iBAAA,CAAkB,MAAA,EAAQ,aAAA;;;UCpIzB,gBAAA;EACf,KAAA;EACA,MAAA,EAAQ,WAAA;AAAA;;;AFHV;;iBEUgB,cAAA,CACd,MAAA,EAAQ,aAAA,EACR,aAAA,UACA,MAAA,YACC,gBAAA;;;;;iBAuBa,+BAAA,CACd,SAAA,EAAW,mBAAA,EACX,MAAA,YACC,gBAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import AjvDefault from "ajv";
|
|
2
|
+
import addFormatsDefault from "ajv-formats";
|
|
3
|
+
|
|
4
|
+
//#region src/registry.ts
|
|
5
|
+
const DEFAULT_REFERENCE_MODE = "id";
|
|
6
|
+
function resolveOptions(configOptions) {
|
|
7
|
+
return {
|
|
8
|
+
slotReferenceMode: DEFAULT_REFERENCE_MODE,
|
|
9
|
+
...configOptions
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function toSlotDefinition(slot, referenceMode) {
|
|
13
|
+
return {
|
|
14
|
+
name: slot.name,
|
|
15
|
+
multiple: slot.multiple,
|
|
16
|
+
referenceMode
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function toBlockTypeDefinition(block, referenceMode) {
|
|
20
|
+
return {
|
|
21
|
+
name: block.name,
|
|
22
|
+
configSchema: block.configSchema,
|
|
23
|
+
slots: block.slots.map((s) => toSlotDefinition(s, referenceMode))
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function buildContentSchema(blockNames) {
|
|
27
|
+
return {
|
|
28
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
29
|
+
type: "object",
|
|
30
|
+
required: ["entryId", "nodes"],
|
|
31
|
+
properties: {
|
|
32
|
+
entryId: { type: "string" },
|
|
33
|
+
nodes: {
|
|
34
|
+
type: "object",
|
|
35
|
+
additionalProperties: { $ref: "#/definitions/ContentNode" }
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
definitions: { ContentNode: {
|
|
39
|
+
type: "object",
|
|
40
|
+
required: [
|
|
41
|
+
"id",
|
|
42
|
+
"block",
|
|
43
|
+
"config"
|
|
44
|
+
],
|
|
45
|
+
properties: {
|
|
46
|
+
id: { type: "string" },
|
|
47
|
+
block: blockNames.length > 0 ? {
|
|
48
|
+
type: "string",
|
|
49
|
+
enum: blockNames
|
|
50
|
+
} : { type: "string" },
|
|
51
|
+
config: { type: "object" }
|
|
52
|
+
},
|
|
53
|
+
additionalProperties: true
|
|
54
|
+
} }
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Creates a schema from config. Runs plugins (which can register blocks and add options),
|
|
59
|
+
* then builds block types with global slotReferenceMode. Returns the schema with getters
|
|
60
|
+
* and a contentSchema (JSON Schema for the content document).
|
|
61
|
+
*/
|
|
62
|
+
function createSchema(config) {
|
|
63
|
+
const blocks = [...config.registerBlocks ?? []];
|
|
64
|
+
const options = resolveOptions(config.options);
|
|
65
|
+
const context = {
|
|
66
|
+
registerBlock(block) {
|
|
67
|
+
blocks.push(block);
|
|
68
|
+
},
|
|
69
|
+
options,
|
|
70
|
+
version: config.version
|
|
71
|
+
};
|
|
72
|
+
for (const plugin of config.registerPlugins ?? []) plugin(context);
|
|
73
|
+
const referenceMode = options.slotReferenceMode ?? DEFAULT_REFERENCE_MODE;
|
|
74
|
+
const blockTypes = /* @__PURE__ */ new Map();
|
|
75
|
+
for (const block of blocks) blockTypes.set(block.name, toBlockTypeDefinition(block, referenceMode));
|
|
76
|
+
const contentSchema = buildContentSchema(Array.from(blockTypes.keys()));
|
|
77
|
+
return {
|
|
78
|
+
blockTypes,
|
|
79
|
+
meta: config.version !== void 0 ? { version: config.version } : void 0,
|
|
80
|
+
contentSchema,
|
|
81
|
+
options,
|
|
82
|
+
version: config.version,
|
|
83
|
+
getBlockType(name) {
|
|
84
|
+
return blockTypes.get(name);
|
|
85
|
+
},
|
|
86
|
+
getBlockTypeNames() {
|
|
87
|
+
return Array.from(blockTypes.keys());
|
|
88
|
+
},
|
|
89
|
+
hasBlockType(name) {
|
|
90
|
+
return blockTypes.has(name);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Returns the block type definition for the given name, or undefined if not registered.
|
|
96
|
+
*/
|
|
97
|
+
function getBlockType(schema, name) {
|
|
98
|
+
return schema.blockTypes.get(name);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Returns true if the schema has a block type with the given name.
|
|
102
|
+
*/
|
|
103
|
+
function hasBlockType(schema, name) {
|
|
104
|
+
return schema.blockTypes.has(name);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Returns all registered block type names.
|
|
108
|
+
*/
|
|
109
|
+
function getBlockTypeNames(schema) {
|
|
110
|
+
return Array.from(schema.blockTypes.keys());
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/validate.ts
|
|
115
|
+
const Ajv = AjvDefault;
|
|
116
|
+
const addFormats = addFormatsDefault;
|
|
117
|
+
const ajv = new Ajv({
|
|
118
|
+
allErrors: true,
|
|
119
|
+
strict: false
|
|
120
|
+
});
|
|
121
|
+
addFormats(ajv);
|
|
122
|
+
/**
|
|
123
|
+
* Validates a config object against a block type's JSON Schema.
|
|
124
|
+
* Returns { valid: true, errors: null } on success, or { valid: false, errors } on failure.
|
|
125
|
+
*/
|
|
126
|
+
function validateConfig(schema, blockTypeName, config) {
|
|
127
|
+
const blockType = getBlockType(schema, blockTypeName);
|
|
128
|
+
if (!blockType) return {
|
|
129
|
+
valid: false,
|
|
130
|
+
errors: [{
|
|
131
|
+
instancePath: "",
|
|
132
|
+
schemaPath: "",
|
|
133
|
+
keyword: "blockType",
|
|
134
|
+
message: `Unknown block type: ${blockTypeName}`,
|
|
135
|
+
params: {}
|
|
136
|
+
}]
|
|
137
|
+
};
|
|
138
|
+
return validateConfigAgainstDefinition(blockType, config);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Validates a config object against a block type definition's JSON Schema.
|
|
142
|
+
* Use this when you already have the BlockTypeDefinition (e.g. from getBlockType).
|
|
143
|
+
*/
|
|
144
|
+
function validateConfigAgainstDefinition(blockType, config) {
|
|
145
|
+
let validate;
|
|
146
|
+
try {
|
|
147
|
+
validate = ajv.compile(blockType.configSchema);
|
|
148
|
+
} catch (err) {
|
|
149
|
+
return {
|
|
150
|
+
valid: false,
|
|
151
|
+
errors: [{
|
|
152
|
+
instancePath: "",
|
|
153
|
+
schemaPath: "",
|
|
154
|
+
keyword: "schema",
|
|
155
|
+
message: err instanceof Error ? err.message : "Invalid config schema",
|
|
156
|
+
params: {}
|
|
157
|
+
}]
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const valid = validate(config);
|
|
161
|
+
return {
|
|
162
|
+
valid,
|
|
163
|
+
errors: valid ? null : validate.errors ?? []
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
//#endregion
|
|
168
|
+
export { createSchema, getBlockType, getBlockTypeNames, hasBlockType, validateConfig, validateConfigAgainstDefinition };
|
|
169
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/registry.ts","../src/validate.ts"],"sourcesContent":["import type {\n BlockInput,\n BlockTypeDefinition,\n GenetikSchema,\n JsonSchema,\n SchemaConfig,\n SchemaOptions,\n SlotDefinition,\n SlotReferenceMode,\n} from \"./types.js\";\n\nconst DEFAULT_REFERENCE_MODE: SlotReferenceMode = \"id\";\n\nfunction resolveOptions(configOptions?: SchemaOptions): SchemaOptions {\n return {\n slotReferenceMode: DEFAULT_REFERENCE_MODE,\n ...configOptions,\n };\n}\n\nfunction toSlotDefinition(slot: { name: string; multiple: boolean }, referenceMode: SlotReferenceMode): SlotDefinition {\n return {\n name: slot.name,\n multiple: slot.multiple,\n referenceMode,\n };\n}\n\nfunction toBlockTypeDefinition(block: BlockInput, referenceMode: SlotReferenceMode): BlockTypeDefinition {\n return {\n name: block.name,\n configSchema: block.configSchema,\n slots: block.slots.map((s) => toSlotDefinition(s, referenceMode)),\n };\n}\n\nfunction buildContentSchema(blockNames: string[]): JsonSchema {\n return {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n required: [\"entryId\", \"nodes\"],\n properties: {\n entryId: { type: \"string\" },\n nodes: {\n type: \"object\",\n additionalProperties: { $ref: \"#/definitions/ContentNode\" },\n },\n },\n definitions: {\n ContentNode: {\n type: \"object\",\n required: [\"id\", \"block\", \"config\"],\n properties: {\n id: { type: \"string\" },\n block: blockNames.length > 0 ? { type: \"string\", enum: blockNames } : { type: \"string\" },\n config: { type: \"object\" },\n },\n additionalProperties: true,\n },\n },\n };\n}\n\nexport interface SchemaInstance extends GenetikSchema {\n /** JSON Schema that describes the content document (entryId + nodes). */\n contentSchema: JsonSchema;\n /** Resolved options (includes slotReferenceMode). */\n options: SchemaOptions;\n /** Schema version if set. */\n version?: string;\n getBlockType(name: string): BlockTypeDefinition | undefined;\n getBlockTypeNames(): string[];\n hasBlockType(name: string): boolean;\n}\n\n/**\n * Creates a schema from config. Runs plugins (which can register blocks and add options),\n * then builds block types with global slotReferenceMode. Returns the schema with getters\n * and a contentSchema (JSON Schema for the content document).\n */\nexport function createSchema(config: SchemaConfig): SchemaInstance {\n const blocks: BlockInput[] = [...(config.registerBlocks ?? [])];\n const options = resolveOptions(config.options);\n\n const context: import(\"./types.js\").SchemaPluginContext = {\n registerBlock(block: BlockInput) {\n blocks.push(block);\n },\n options,\n version: config.version,\n };\n\n for (const plugin of config.registerPlugins ?? []) {\n plugin(context);\n }\n\n const referenceMode = (options.slotReferenceMode ?? DEFAULT_REFERENCE_MODE) as SlotReferenceMode;\n const blockTypes = new Map<string, BlockTypeDefinition>();\n for (const block of blocks) {\n blockTypes.set(block.name, toBlockTypeDefinition(block, referenceMode));\n }\n\n const blockNames = Array.from(blockTypes.keys());\n const contentSchema = buildContentSchema(blockNames);\n\n const schema: GenetikSchema = {\n blockTypes,\n meta: config.version !== undefined ? { version: config.version } : undefined,\n };\n\n return {\n ...schema,\n contentSchema,\n options,\n version: config.version,\n getBlockType(name: string) {\n return blockTypes.get(name);\n },\n getBlockTypeNames() {\n return Array.from(blockTypes.keys());\n },\n hasBlockType(name: string) {\n return blockTypes.has(name);\n },\n };\n}\n\n/**\n * Returns the block type definition for the given name, or undefined if not registered.\n */\nexport function getBlockType(schema: GenetikSchema, name: string): BlockTypeDefinition | undefined {\n return schema.blockTypes.get(name);\n}\n\n/**\n * Returns true if the schema has a block type with the given name.\n */\nexport function hasBlockType(schema: GenetikSchema, name: string): boolean {\n return schema.blockTypes.has(name);\n}\n\n/**\n * Returns all registered block type names.\n */\nexport function getBlockTypeNames(schema: GenetikSchema): string[] {\n return Array.from(schema.blockTypes.keys());\n}\n","import AjvDefault from \"ajv\";\nimport addFormatsDefault from \"ajv-formats\";\nimport type { ErrorObject, ValidateFunction } from \"ajv\";\nimport type { BlockTypeDefinition, GenetikSchema } from \"./types.js\";\nimport { getBlockType } from \"./registry.js\";\n\n// ESM/NodeNext: default export types don't expose constructor/call; assert through unknown\nconst Ajv = AjvDefault as unknown as new (opts?: { allErrors?: boolean; strict?: boolean }) => { compile: (schema: object) => ValidateFunction };\nconst addFormats = addFormatsDefault as unknown as (ajv: InstanceType<typeof Ajv>) => void;\nconst ajv = new Ajv({ allErrors: true, strict: false });\naddFormats(ajv);\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ErrorObject[] | null;\n}\n\n/**\n * Validates a config object against a block type's JSON Schema.\n * Returns { valid: true, errors: null } on success, or { valid: false, errors } on failure.\n */\nexport function validateConfig(\n schema: GenetikSchema,\n blockTypeName: string,\n config: unknown\n): ValidationResult {\n const blockType = getBlockType(schema, blockTypeName);\n if (!blockType) {\n return {\n valid: false,\n errors: [\n {\n instancePath: \"\",\n schemaPath: \"\",\n keyword: \"blockType\",\n message: `Unknown block type: ${blockTypeName}`,\n params: {},\n } satisfies ErrorObject,\n ],\n };\n }\n return validateConfigAgainstDefinition(blockType, config);\n}\n\n/**\n * Validates a config object against a block type definition's JSON Schema.\n * Use this when you already have the BlockTypeDefinition (e.g. from getBlockType).\n */\nexport function validateConfigAgainstDefinition(\n blockType: BlockTypeDefinition,\n config: unknown\n): ValidationResult {\n let validate: ValidateFunction;\n try {\n validate = ajv.compile(blockType.configSchema);\n } catch (err) {\n return {\n valid: false,\n errors: [\n {\n instancePath: \"\",\n schemaPath: \"\",\n keyword: \"schema\",\n message: err instanceof Error ? err.message : \"Invalid config schema\",\n params: {},\n } satisfies ErrorObject,\n ],\n };\n }\n const valid = validate(config);\n return {\n valid,\n errors: valid ? null : (validate.errors ?? []),\n };\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@genetik/schema",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.cjs",
|
|
15
|
+
"types": "./dist/index.d.mts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"ajv": "^8.17.1",
|
|
23
|
+
"ajv-formats": "^3.0.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"eslint": "^9.39.1",
|
|
27
|
+
"tsdown": "0.20.3",
|
|
28
|
+
"typescript": "5.9.2",
|
|
29
|
+
"vitest": "^2.1.8",
|
|
30
|
+
"@genetik/eslint-config": "0.0.0",
|
|
31
|
+
"@genetik/typescript-config": "0.0.0"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18"
|
|
35
|
+
},
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsdown",
|
|
39
|
+
"dev": "tsdown --watch",
|
|
40
|
+
"lint": "eslint . --max-warnings 0",
|
|
41
|
+
"check-types": "tsc --noEmit",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"test:watch": "vitest"
|
|
44
|
+
}
|
|
45
|
+
}
|