@json-to-office/shared-docx 0.1.3 → 0.3.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/dist/{chunk-36K7MD3C.js → chunk-3D6HY6AC.js} +160 -87
- package/dist/chunk-3D6HY6AC.js.map +1 -0
- package/dist/{chunk-HHMK2RWF.js → chunk-AMVS7BRX.js} +7 -2
- package/dist/chunk-AMVS7BRX.js.map +1 -0
- package/dist/{chunk-FV6RFK6S.js → chunk-CVI7GFWX.js} +6 -7
- package/dist/chunk-CVI7GFWX.js.map +1 -0
- package/dist/{chunk-2YG3S7G3.js → chunk-DEIEJUY4.js} +2 -2
- package/dist/{chunk-HE6AENGO.js → chunk-EDYWA2KA.js} +2 -2
- package/dist/{chunk-ITHHY2YT.js → chunk-GGNGVIZO.js} +14 -39
- package/dist/{chunk-ITHHY2YT.js.map → chunk-GGNGVIZO.js.map} +1 -1
- package/dist/{chunk-THYJPIZN.js → chunk-S4EFGCIC.js} +2 -2
- package/dist/{chunk-JIF2EIDR.js → chunk-WJA5TGNI.js} +25 -15
- package/dist/chunk-WJA5TGNI.js.map +1 -0
- package/dist/{chunk-MEEABCM6.js → chunk-YNBTESFN.js} +6 -6
- package/dist/index.d.ts +1 -202
- package/dist/index.js +22 -22
- package/dist/schemas/api.js +3 -3
- package/dist/schemas/component-registry.d.ts +35 -5
- package/dist/schemas/component-registry.js +3 -1
- package/dist/schemas/components.d.ts +12 -200
- package/dist/schemas/components.js +6 -4
- package/dist/schemas/document.js +4 -4
- package/dist/schemas/export.js +3 -1
- package/dist/schemas/generator.js +2 -2
- package/dist/schemas/theme.d.ts +3 -597
- package/dist/schemas/theme.js +3 -3
- package/dist/validation/unified/index.d.ts +3 -201
- package/dist/validation/unified/index.js +5 -5
- package/package.json +2 -2
- package/dist/chunk-36K7MD3C.js.map +0 -1
- package/dist/chunk-FV6RFK6S.js.map +0 -1
- package/dist/chunk-HHMK2RWF.js.map +0 -1
- package/dist/chunk-JIF2EIDR.js.map +0 -1
- /package/dist/{chunk-2YG3S7G3.js.map → chunk-DEIEJUY4.js.map} +0 -0
- /package/dist/{chunk-HE6AENGO.js.map → chunk-EDYWA2KA.js.map} +0 -0
- /package/dist/{chunk-THYJPIZN.js.map → chunk-S4EFGCIC.js.map} +0 -0
- /package/dist/{chunk-MEEABCM6.js.map → chunk-YNBTESFN.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/export.ts"],"sourcesContent":["/**\n * Unified Schema Export Utility\n *\n * Single source of truth for converting TypeBox schemas to JSON Schema format.\n * Eliminates duplication between generate-schemas.mjs and plugin/schema.ts\n */\n\nimport { TSchema } from '@sinclair/typebox';\nimport { getContainerComponents } from './component-registry';\n\n/**\n * Configuration for a component schema\n */\nexport interface ComponentSchemaConfig {\n schema: TSchema;\n title: string;\n description: string;\n requiresName?: boolean;\n enhanceForRichContent?: boolean;\n}\n\n/**\n * Fix TypeBox recursive references in a schema\n * Handles both \"T0\" and \"ComponentDefinition\" reference patterns\n */\nexport function fixSchemaReferences(\n schema: Record<string, unknown>,\n rootDefinitionName = 'ComponentDefinition'\n): void {\n function traverse(obj: Record<string, unknown>, path = ''): void {\n if (typeof obj !== 'object' || obj === null) return;\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = path ? `${path}.${key}` : key;\n\n if (value && typeof value === 'object') {\n // Type guard to check if value has expected properties\n const schemaValue = value as Record<string, unknown>;\n\n // Fix arrays with empty items\n if (\n schemaValue.type === 'array' &&\n schemaValue.items &&\n Object.keys(schemaValue.items).length === 0\n ) {\n schemaValue.items = {\n $ref: `#/definitions/${rootDefinitionName}`,\n };\n }\n\n // Fix arrays with items that reference broken \"T0\"\n if (\n schemaValue.type === 'array' &&\n schemaValue.items &&\n typeof schemaValue.items === 'object' &&\n '$ref' in schemaValue.items &&\n (schemaValue.items as Record<string, unknown>).$ref === 'T0'\n ) {\n schemaValue.items = {\n $ref: `#/definitions/${rootDefinitionName}`,\n };\n }\n\n // Fix direct $ref properties that point to \"T0\" or bare definition names\n if (\n schemaValue.$ref === 'T0' ||\n schemaValue.$ref === rootDefinitionName\n ) {\n schemaValue.$ref = `#/definitions/${rootDefinitionName}`;\n }\n\n // Remove problematic $id properties that reference \"T0\"\n if (\n key === '$id' &&\n typeof value === 'string' &&\n (value === 'T0' || value === rootDefinitionName) &&\n currentPath !== `definitions.${rootDefinitionName}.$id`\n ) {\n delete obj[key];\n continue;\n }\n\n traverse(value as Record<string, unknown>, currentPath);\n }\n }\n }\n\n traverse(schema);\n}\n\n/**\n * Convert TypeBox schema to JSON Schema format with proper definitions\n */\nexport function convertToJsonSchema(\n schema: TSchema,\n options: {\n $schema?: string;\n $id?: string;\n title?: string;\n description?: string;\n definitions?: Record<string, unknown>;\n } = {}\n): Record<string, unknown> {\n const {\n $schema = 'https://json-schema.org/draft-07/schema#',\n $id,\n title,\n description,\n definitions = {},\n } = options;\n\n // Clone the schema to avoid mutations\n const schemaJson = JSON.parse(JSON.stringify(schema));\n\n // Extract recursive schemas to definitions\n const extractedDefinitions: Record<string, unknown> = { ...definitions };\n\n function extractRecursiveSchemas(\n obj: Record<string, unknown>,\n path = ''\n ): void {\n if (typeof obj !== 'object' || obj === null) return;\n\n for (const [key, value] of Object.entries(obj)) {\n if (value && typeof value === 'object') {\n const schemaValue = value as Record<string, unknown>;\n\n // If this schema has an $id, extract it to definitions\n if (schemaValue.$id && typeof schemaValue.$id === 'string') {\n const definitionName = schemaValue.$id;\n\n // Don't extract if it's already in the root definitions section\n if (path !== `definitions.${definitionName}`) {\n // Clone the schema without the $id\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { $id: _, ...schemaWithoutId } = schemaValue;\n extractedDefinitions[definitionName] = schemaWithoutId;\n\n // Replace the inline schema with a $ref\n obj[key] = { $ref: `#/definitions/${definitionName}` };\n\n // Continue processing the extracted schema for nested recursions\n extractRecursiveSchemas(\n schemaWithoutId,\n `definitions.${definitionName}`\n );\n continue;\n }\n }\n\n extractRecursiveSchemas(\n value as Record<string, unknown>,\n path ? `${path}.${key}` : key\n );\n }\n }\n }\n\n // Extract recursive schemas from the main schema\n extractRecursiveSchemas(schemaJson);\n\n // Build the final JSON Schema\n const jsonSchema: Record<string, unknown> = {\n $schema,\n };\n\n if ($id) jsonSchema.$id = $id;\n\n // Merge schema properties first to preserve original metadata\n Object.assign(jsonSchema, schemaJson);\n\n // Only override title and description if explicitly provided\n if (title !== undefined) jsonSchema.title = title;\n if (description !== undefined) jsonSchema.description = description;\n\n // Add definitions section if we have any\n if (Object.keys(extractedDefinitions).length > 0) {\n jsonSchema.definitions = extractedDefinitions;\n }\n\n // Fix any remaining recursive references\n fixSchemaReferences(jsonSchema);\n\n return jsonSchema;\n}\n\n/**\n * Create a component schema with proper structure\n */\nexport function createComponentSchema(\n name: string,\n config: ComponentSchemaConfig,\n componentDefinitionSchema?: TSchema\n): Record<string, unknown> {\n const componentStructure: Record<string, unknown> = {\n $schema: 'https://json-schema.org/draft-07/schema#',\n $id: `${name}.schema.json`,\n title: config.title,\n description: config.description,\n type: 'object',\n required: ['name', 'props'],\n properties: {\n name: {\n type: 'string',\n const: name,\n description: `Component name identifier (must be \"${name}\")`,\n },\n id: {\n type: 'string',\n description: 'Optional unique identifier for the component',\n },\n props: JSON.parse(JSON.stringify(config.schema)),\n },\n };\n\n // Add children array for container types\n const containerNames = getContainerComponents().map((c) => c.name);\n if (containerNames.includes(name)) {\n (componentStructure.properties as Record<string, unknown>).children = {\n type: 'array',\n description: 'Children within this container',\n items: {\n $ref: '#/definitions/ComponentDefinition',\n },\n };\n\n // Add the ComponentDefinition for recursive references\n if (componentDefinitionSchema) {\n componentStructure.definitions = {\n ComponentDefinition: JSON.parse(\n JSON.stringify(componentDefinitionSchema)\n ),\n };\n }\n }\n\n // Enhance table component to support rich content in cells\n if (config.enhanceForRichContent && name === 'table') {\n // Add ComponentDefinition to support rich content in table cells\n const componentStructureWithDefs = componentStructure as Record<\n string,\n unknown\n > & {\n definitions?: Record<string, unknown>;\n };\n if (!componentStructureWithDefs.definitions) {\n componentStructureWithDefs.definitions = {};\n }\n if (componentDefinitionSchema) {\n componentStructureWithDefs.definitions.ComponentDefinition = JSON.parse(\n JSON.stringify(componentDefinitionSchema)\n );\n }\n\n // Enhance the rows.items.items to support components\n const properties = componentStructure.properties as Record<string, unknown>;\n const propsProp = properties.props as Record<string, unknown> | undefined;\n if (\n propsProp?.properties &&\n typeof propsProp.properties === 'object' &&\n propsProp.properties !== null\n ) {\n const propsProps = propsProp.properties as Record<string, unknown>;\n const rowsProp = propsProps.rows as Record<string, unknown> | undefined;\n if (\n rowsProp?.items &&\n typeof rowsProp.items === 'object' &&\n rowsProp.items !== null\n ) {\n const rowsItems = rowsProp.items as Record<string, unknown>;\n const cellSchema = rowsItems.items as\n | Record<string, unknown>\n | undefined;\n\n // If it has anyOf, add component reference as an option\n if (cellSchema?.anyOf && Array.isArray(cellSchema.anyOf)) {\n // Check if component reference isn't already there\n const hasComponentRef = cellSchema.anyOf.some((item: unknown) => {\n const itemObj = item as Record<string, unknown>;\n return itemObj.$ref === '#/definitions/ComponentDefinition';\n });\n if (!hasComponentRef) {\n cellSchema.anyOf.push({\n description:\n 'Rich content cell with component (e.g., image, paragraph)',\n $ref: '#/definitions/ComponentDefinition',\n });\n }\n }\n }\n }\n }\n\n // Fix empty items in arrays and broken references\n fixSchemaReferences(componentStructure);\n\n componentStructure.additionalProperties = false;\n\n return componentStructure;\n}\n\n/**\n * Export schema to file with proper formatting\n */\nexport async function exportSchemaToFile(\n schema: Record<string, unknown>,\n outputPath: string,\n options: {\n prettyPrint?: boolean;\n } = {}\n): Promise<void> {\n const { prettyPrint = true } = options;\n\n // Convert to JSON string\n const jsonSchema = prettyPrint\n ? JSON.stringify(schema, null, 2)\n : JSON.stringify(schema);\n\n // Write to file\n const fs = await import('fs/promises');\n await fs.writeFile(outputPath, jsonSchema, 'utf-8');\n}\n\n/**\n * Component metadata registry\n * Single source of truth for component titles and descriptions\n */\nexport const COMPONENT_METADATA: Record<\n string,\n Omit<ComponentSchemaConfig, 'schema'>\n> = {\n report: {\n title: 'Report Component',\n description:\n 'Top-level report container component with document-wide settings',\n },\n section: {\n title: 'Section Component',\n description: 'Section container for organizing document content',\n },\n columns: {\n title: 'Columns Component',\n description: 'Multi-column layout container',\n },\n heading: {\n title: 'Heading Component',\n description: 'Heading text with configurable levels and styling',\n },\n paragraph: {\n title: 'Paragraph Component',\n description: 'Rich paragraph text content with formatting options',\n },\n 'text-box': {\n title: 'Text Box Component',\n description:\n 'Inline or floating container that groups text and image components with shared positioning',\n },\n image: {\n title: 'Image Component',\n description: 'Image content with positioning and sizing options',\n },\n statistic: {\n title: 'Statistic Component',\n description: 'Statistical display with value and label',\n },\n table: {\n title: 'Table Component',\n description: 'Tabular data display with headers and rows',\n enhanceForRichContent: true,\n },\n header: {\n title: 'Header Component',\n description: 'Document header with page numbering and metadata',\n },\n footer: {\n title: 'Footer Component',\n description: 'Document footer with page numbering and metadata',\n },\n list: {\n title: 'List Component',\n description: 'Ordered or unordered list with nested items',\n },\n highcharts: {\n title: 'Highcharts Component',\n description:\n 'Charts powered by Highcharts (line, bar, pie, heatmap, etc.) with rich configuration',\n },\n};\n\n/**\n * Base schema metadata registry\n */\nexport const BASE_SCHEMA_METADATA: Record<\n string,\n { title: string; description: string }\n> = {\n alignment: {\n title: 'Alignment',\n description: 'Text alignment options',\n },\n 'base-component': {\n title: 'Base Component Props',\n description: 'Common props for all components',\n },\n border: {\n title: 'Border',\n description: 'Border styling configuration',\n },\n spacing: {\n title: 'Spacing',\n description: 'Spacing configuration for before and after elements',\n },\n margins: {\n title: 'Margins',\n description: 'Margin configuration for all sides',\n },\n indent: {\n title: 'Indent',\n description: 'Indentation configuration',\n },\n 'line-spacing': {\n title: 'Line Spacing',\n description: 'Line height and spacing configuration',\n },\n 'heading-level': {\n title: 'Heading Level',\n description: 'Heading level from 1 to 6',\n },\n numbering: {\n title: 'Numbering',\n description: 'Numbering configuration for ordered lists',\n },\n 'justified-alignment': {\n title: 'Justified Alignment',\n description: 'Justified text alignment options',\n },\n};\n\n/**\n * Theme schema metadata\n */\nexport const THEME_SCHEMA_METADATA = {\n theme: {\n title: 'Theme Configuration',\n description: 'JSON theme configuration for document styling and appearance',\n },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
createAllComponentSchemas
|
|
3
|
-
|
|
2
|
+
createAllComponentSchemas,
|
|
3
|
+
createAllComponentSchemasNarrowed
|
|
4
|
+
} from "./chunk-3D6HY6AC.js";
|
|
4
5
|
|
|
5
6
|
// src/schemas/components.ts
|
|
6
7
|
import { Type } from "@sinclair/typebox";
|
|
@@ -16,10 +17,8 @@ var StandardComponentDefinitionSchema = Type.Union(
|
|
|
16
17
|
var ComponentDefinitionSchema = Type.Recursive(
|
|
17
18
|
(This) => Type.Union(
|
|
18
19
|
[
|
|
19
|
-
// Standard components from registry -
|
|
20
|
-
|
|
21
|
-
// Convert readonly array to mutable array for Type.Union
|
|
22
|
-
...createAllComponentSchemas(This)
|
|
20
|
+
// Standard components from registry with per-container narrowed children
|
|
21
|
+
...createAllComponentSchemasNarrowed(This).schemas
|
|
23
22
|
],
|
|
24
23
|
{
|
|
25
24
|
discriminator: { propertyName: "name" },
|
|
@@ -32,4 +31,4 @@ export {
|
|
|
32
31
|
StandardComponentDefinitionSchema,
|
|
33
32
|
ComponentDefinitionSchema
|
|
34
33
|
};
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-CVI7GFWX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/components.ts"],"sourcesContent":["/**\n * TypeBox Component Schemas\n *\n * Complete component definitions with discriminated unions for perfect\n * JSON schema autocompletion and validation.\n *\n * IMPORTANT: Standard components are defined in component-registry.ts (SINGLE SOURCE OF TRUTH).\n * This file uses that registry to generate TypeBox schemas.\n */\n\nimport { Type, Static } from '@sinclair/typebox';\nimport {\n createAllComponentSchemas,\n createAllComponentSchemasNarrowed,\n} from './component-registry';\n\n// Re-export all schemas from individual component files\nexport * from './components/common';\nexport * from './components/report';\nexport * from './components/section';\nexport * from './components/columns';\nexport * from './components/heading';\nexport * from './components/paragraph';\nexport * from './components/image';\nexport * from './components/highcharts';\nexport * from './components/statistic';\nexport * from './components/table';\nexport * from './components/header';\nexport * from './components/footer';\nexport * from './components/list';\nexport * from './components/toc';\nexport * from './components/text-box';\n\n// ============================================================================\n// Component Definitions with Discriminated Union\n// ============================================================================\n\n// StandardComponentDefinitionSchema - Union of all standard component types\n// Generated from the component registry (SINGLE SOURCE OF TRUTH)\nexport const StandardComponentDefinitionSchema = Type.Union(\n // Use Type.Any() for non-recursive standard components\n // Convert readonly array to mutable array for Type.Union\n [...createAllComponentSchemas(Type.Any())],\n {\n discriminator: { propertyName: 'name' },\n description: 'Standard component definition with discriminated union',\n }\n);\n\nexport const ComponentDefinitionSchema = Type.Recursive((This) =>\n Type.Union(\n [\n // Standard components from registry with per-container narrowed children\n ...createAllComponentSchemasNarrowed(This).schemas,\n ],\n {\n discriminator: { propertyName: 'name' },\n description: 'Component definition with discriminated union',\n }\n )\n);\n\n// ============================================================================\n// TypeScript Types\n// ============================================================================\n\nexport type ComponentDefinition = Static<typeof ComponentDefinitionSchema>;\n"],"mappings":";;;;;;AAUA,SAAS,YAAoB;AA6BtB,IAAM,oCAAoC,KAAK;AAAA;AAAA;AAAA,EAGpD,CAAC,GAAG,0BAA0B,KAAK,IAAI,CAAC,CAAC;AAAA,EACzC;AAAA,IACE,eAAe,EAAE,cAAc,OAAO;AAAA,IACtC,aAAa;AAAA,EACf;AACF;AAEO,IAAM,4BAA4B,KAAK;AAAA,EAAU,CAAC,SACvD,KAAK;AAAA,IACH;AAAA;AAAA,MAEE,GAAG,kCAAkC,IAAI,EAAE;AAAA,IAC7C;AAAA,IACA;AAAA,MACE,eAAe,EAAE,cAAc,OAAO;AAAA,MACtC,aAAa;AAAA,IACf;AAAA,EACF;AACF;","names":[]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
SectionPropsSchema,
|
|
9
9
|
StatisticPropsSchema,
|
|
10
10
|
TablePropsSchema
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-3D6HY6AC.js";
|
|
12
12
|
import {
|
|
13
13
|
FontDefinitionSchema,
|
|
14
14
|
HexColorSchema,
|
|
@@ -361,4 +361,4 @@ export {
|
|
|
361
361
|
ThemeConfigSchema,
|
|
362
362
|
isValidThemeConfig
|
|
363
363
|
};
|
|
364
|
-
//# sourceMappingURL=chunk-
|
|
364
|
+
//# sourceMappingURL=chunk-DEIEJUY4.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ComponentDefinitionSchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CVI7GFWX.js";
|
|
4
4
|
|
|
5
5
|
// src/schemas/api.ts
|
|
6
6
|
import { Type } from "@sinclair/typebox";
|
|
@@ -94,4 +94,4 @@ export {
|
|
|
94
94
|
GenerateDocumentResponseSchema,
|
|
95
95
|
ValidateDocumentResponseSchema
|
|
96
96
|
};
|
|
97
|
-
//# sourceMappingURL=chunk-
|
|
97
|
+
//# sourceMappingURL=chunk-EDYWA2KA.js.map
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ThemeConfigSchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DEIEJUY4.js";
|
|
4
4
|
import {
|
|
5
5
|
documentValidator,
|
|
6
6
|
strictDocumentValidator,
|
|
7
7
|
validateAgainstSchema,
|
|
8
8
|
validateJson
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-YNBTESFN.js";
|
|
10
10
|
import {
|
|
11
11
|
ComponentDefinitionSchema
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-CVI7GFWX.js";
|
|
13
|
+
import {
|
|
14
|
+
CustomComponentDefinitionSchema
|
|
15
|
+
} from "./chunk-VP3X6DBP.js";
|
|
13
16
|
import {
|
|
14
17
|
ColumnsPropsSchema,
|
|
15
18
|
FooterPropsSchema,
|
|
@@ -22,10 +25,7 @@ import {
|
|
|
22
25
|
SectionPropsSchema,
|
|
23
26
|
StatisticPropsSchema,
|
|
24
27
|
TablePropsSchema
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import {
|
|
27
|
-
CustomComponentDefinitionSchema
|
|
28
|
-
} from "./chunk-VP3X6DBP.js";
|
|
28
|
+
} from "./chunk-3D6HY6AC.js";
|
|
29
29
|
|
|
30
30
|
// src/validation/unified/index.ts
|
|
31
31
|
import {
|
|
@@ -196,6 +196,7 @@ function isThemeConfig(data) {
|
|
|
196
196
|
|
|
197
197
|
// src/validation/unified/component-validator.ts
|
|
198
198
|
import { Value } from "@sinclair/typebox/value";
|
|
199
|
+
import { validateCustomComponentProps as sharedValidateCustomComponentProps } from "@json-to-office/shared/plugin";
|
|
199
200
|
var COMPONENT_SCHEMA_MAP = {
|
|
200
201
|
report: ReportPropsSchema,
|
|
201
202
|
section: SectionPropsSchema,
|
|
@@ -252,37 +253,11 @@ function validateComponentDefinition(component, options) {
|
|
|
252
253
|
return componentResult;
|
|
253
254
|
}
|
|
254
255
|
function validateCustomComponentProps(componentSchema, config, options) {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
});
|
|
261
|
-
return {
|
|
262
|
-
...result,
|
|
263
|
-
success: result.valid,
|
|
264
|
-
// Add success for backward compatibility
|
|
265
|
-
data: result.data,
|
|
266
|
-
// Cast to generic type T
|
|
267
|
-
componentName: "custom",
|
|
268
|
-
isCustomComponent: true
|
|
269
|
-
};
|
|
270
|
-
} catch (error) {
|
|
271
|
-
return {
|
|
272
|
-
valid: false,
|
|
273
|
-
success: false,
|
|
274
|
-
// Add success for backward compatibility
|
|
275
|
-
errors: [
|
|
276
|
-
{
|
|
277
|
-
path: "props",
|
|
278
|
-
message: error instanceof Error ? error.message : "Unknown validation error",
|
|
279
|
-
code: "validation_exception"
|
|
280
|
-
}
|
|
281
|
-
],
|
|
282
|
-
componentName: "custom",
|
|
283
|
-
isCustomComponent: true
|
|
284
|
-
};
|
|
285
|
-
}
|
|
256
|
+
return sharedValidateCustomComponentProps(
|
|
257
|
+
componentSchema,
|
|
258
|
+
config,
|
|
259
|
+
options
|
|
260
|
+
);
|
|
286
261
|
}
|
|
287
262
|
function validateComponents(components, options) {
|
|
288
263
|
return components.map(({ name, props }) => {
|
|
@@ -451,4 +426,4 @@ export {
|
|
|
451
426
|
createErrorConfig,
|
|
452
427
|
formatErrorMessage
|
|
453
428
|
};
|
|
454
|
-
//# sourceMappingURL=chunk-
|
|
429
|
+
//# sourceMappingURL=chunk-GGNGVIZO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/validation/unified/index.ts","../src/validation/unified/error-formatter-config.ts","../src/validation/unified/theme-validator.ts","../src/validation/unified/component-validator.ts"],"sourcesContent":["/**\n * Unified validation facade\n * Simple, clean API for all validation needs\n */\n\n// Format-agnostic types re-exported from @json-to-office/shared\nexport type { ValidationError, ValidationResult } from '@json-to-office/shared';\n\n// Docx-specific extended types (local)\nexport type {\n ValidationOptions,\n JsonValidationResult,\n ThemeValidationResult,\n DocumentValidationResult,\n ComponentValidationResult,\n EnhancedValueError,\n} from './types';\n\n// Format-agnostic error utilities re-exported from @json-to-office/shared\nexport {\n transformValueError,\n transformValueErrors,\n calculatePosition,\n formatErrorSummary,\n groupErrorsByPath,\n createJsonParseError,\n} from '@json-to-office/shared';\n\n// Docx-specific error transformer (local, extends shared with docx-specific messages)\nexport {\n transformValueError as transformDocxValueError,\n transformValueErrors as transformDocxValueErrors,\n} from './error-transformer';\n\n// Export deep validation utilities (docx-specific)\nexport {\n deepValidateDocument,\n comprehensiveValidateDocument,\n} from './deep-validator';\n\n// Format-agnostic schema utilities re-exported from @json-to-office/shared\nexport {\n isUnionSchema,\n isObjectSchema,\n isLiteralSchema,\n getObjectSchemaPropertyNames,\n getLiteralValue,\n extractStandardComponentNames,\n clearComponentNamesCache,\n getSchemaMetadata,\n} from '@json-to-office/shared';\n\n// Format-agnostic error formatter config re-exported from @json-to-office/shared\nexport {\n type ErrorFormatterConfig,\n DEFAULT_ERROR_CONFIG,\n ERROR_EMOJIS,\n createErrorConfig,\n formatErrorMessage,\n} from '@json-to-office/shared';\n\n// Docx-specific error formatter extras (local)\nexport { ERROR_TEMPLATES, DOC_LINKS } from './error-formatter-config';\n\n// Export base validator utilities\nexport {\n validateAgainstSchema,\n validateJson,\n validateBatch,\n validateWithEnhancement,\n createValidator,\n createJsonValidator,\n isValidationSuccess,\n getValidationSummary,\n} from './base-validator';\n\n// Export document validation\nexport {\n validateDocument,\n validateJsonDocument,\n isValidDocument,\n createDocumentValidator,\n documentValidator,\n strictDocumentValidator,\n // Legacy compatibility\n validateJsonComponent,\n validateDocumentWithSchema,\n} from './document-validator';\n\n// Export theme validation\nexport {\n validateTheme,\n validateThemeJson,\n validateThemeWithEnhancement,\n isValidTheme,\n createThemeValidator,\n themeValidator,\n strictThemeValidator,\n getThemeName,\n isThemeConfig,\n} from './theme-validator';\n\n// Export component validation\nexport {\n validateComponent,\n validateComponentDefinition,\n validateCustomComponentProps,\n validateComponents,\n isStandardComponentName,\n createComponentValidator,\n componentValidator,\n strictComponentValidator,\n // Type guards\n isReportProps,\n isSectionProps,\n isHeadingProps,\n isParagraphProps,\n isColumnsProps,\n isImageProps,\n isStatisticProps,\n isTableProps,\n isHeaderProps,\n isFooterProps,\n isListProps,\n isCustomComponentProps,\n // Types\n type StandardComponentName,\n} from './component-validator';\n\n// Import the validators we need\nimport {\n documentValidator,\n strictDocumentValidator,\n} from './document-validator';\nimport { themeValidator, strictThemeValidator } from './theme-validator';\nimport {\n componentValidator,\n strictComponentValidator,\n} from './component-validator';\n\n/**\n * Simple validation API\n * The main entry point for most validation needs\n */\nexport const validate = {\n // Document validation\n document: (data: unknown) => documentValidator.validate(data),\n jsonDocument: (jsonInput: string | object) =>\n documentValidator.validateJson(jsonInput),\n\n // Theme validation\n theme: (data: unknown) => themeValidator.validate(data),\n jsonTheme: (jsonInput: string | object) =>\n themeValidator.validateJson(jsonInput),\n\n // Component validation\n component: (name: string, props: unknown) =>\n componentValidator.validate(name, props),\n componentDefinition: (component: unknown) =>\n componentValidator.validateDefinition(component),\n\n // Batch operations\n components: (components: Array<{ name: string; props: unknown }>) =>\n components.map((c) => componentValidator.validate(c.name, c.props)),\n\n // Type checking (non-throwing)\n isDocument: (data: unknown) => {\n const result = documentValidator.validate(data);\n return result.valid;\n },\n isTheme: (data: unknown) => {\n const result = themeValidator.validate(data);\n return result.valid;\n },\n isComponent: (name: string, props: unknown) => {\n const result = componentValidator.validate(name, props);\n return result.valid;\n },\n};\n\n/**\n * Strict validation API\n * For cases where you want no cleaning or defaults\n */\nexport const validateStrict = {\n document: (data: unknown) => strictDocumentValidator.validate(data),\n jsonDocument: (jsonInput: string | object) =>\n strictDocumentValidator.validateJson(jsonInput),\n theme: (data: unknown) => strictThemeValidator.validate(data),\n jsonTheme: (jsonInput: string | object) =>\n strictThemeValidator.validateJson(jsonInput),\n component: (name: string, props: unknown) =>\n strictComponentValidator.validate(name, props),\n componentDefinition: (component: unknown) =>\n strictComponentValidator.validateDefinition(component),\n};\n","/**\n * Error Formatter Configuration\n * Configurable error message formatting options\n */\n\n/**\n * Error formatter configuration options\n */\nexport interface ErrorFormatterConfig {\n /**\n * Include emoji indicators in error messages\n * Default: true (false in CI environments)\n */\n includeEmojis?: boolean;\n\n /**\n * Verbosity level for error messages\n * - minimal: Just the error message\n * - normal: Error message with path\n * - detailed: Full error with suggestions and context\n * Default: 'normal'\n */\n verbosity?: 'minimal' | 'normal' | 'detailed';\n\n /**\n * Include suggestions for fixing errors\n * Default: true\n */\n includeSuggestions?: boolean;\n\n /**\n * Include stack trace or error path\n * Default: true\n */\n includePath?: boolean;\n\n /**\n * Maximum error message length (0 = unlimited)\n * Default: 0\n */\n maxMessageLength?: number;\n\n /**\n * Include links to documentation\n * Default: false\n */\n includeDocLinks?: boolean;\n\n /**\n * Terminal color support\n * Default: auto-detected\n */\n colorSupport?: boolean;\n}\n\n/**\n * Get default configuration\n * Evaluates environment variables at call time, not module load time\n */\nfunction getDefaultConfig(): Required<ErrorFormatterConfig> {\n return {\n includeEmojis: !isCI(),\n verbosity: 'normal',\n includeSuggestions: true,\n includePath: true,\n maxMessageLength: 0,\n includeDocLinks: false,\n colorSupport: hasColorSupport(),\n };\n}\n\n/**\n * Default configuration (for backward compatibility)\n */\nexport const DEFAULT_ERROR_CONFIG: Required<ErrorFormatterConfig> =\n getDefaultConfig();\n\n/**\n * Error message templates\n */\nexport const ERROR_TEMPLATES = {\n UNION_NO_MATCH: 'Value doesn\\'t match any of the expected formats',\n TYPE_MISMATCH: 'Expected {expected} but got {actual}',\n MISSING_REQUIRED: 'Missing required field \\'{field}\\'',\n UNKNOWN_PROPERTY: 'Unknown property \\'{property}\\'',\n INVALID_FORMAT: 'Invalid {type} format',\n PATTERN_MISMATCH: 'Value doesn\\'t match the required pattern',\n} as const;\n\n/**\n * Emoji indicators for different error types\n */\nexport const ERROR_EMOJIS = {\n ERROR: '❌',\n WARNING: '⚠️',\n INFO: 'ℹ️',\n SUGGESTION: '💡',\n FIX: '🔧',\n LINK: '🔗',\n} as const;\n\n/**\n * Documentation links for common errors\n */\nexport const DOC_LINKS = {\n MODULE_TYPES: 'https://docs.json-to-docx.com/modules',\n THEME_CONFIG: 'https://docs.json-to-docx.com/themes',\n VALIDATION: 'https://docs.json-to-docx.com/validation',\n} as const;\n\n/**\n * Detect if running in CI environment\n */\nfunction isCI(): boolean {\n // Check if we're in a Node environment\n if (typeof process === 'undefined' || !process.env) {\n return false;\n }\n\n return !!(\n process.env.CI ||\n process.env.CONTINUOUS_INTEGRATION ||\n process.env.GITHUB_ACTIONS ||\n process.env.GITLAB_CI ||\n process.env.CIRCLECI ||\n process.env.TRAVIS ||\n process.env.JENKINS_URL\n );\n}\n\n/**\n * Detect terminal color support\n */\nfunction hasColorSupport(): boolean {\n // Check if we're in a Node environment\n if (typeof process === 'undefined') {\n return false;\n }\n\n // Check for explicit NO_COLOR env var\n if (process.env?.NO_COLOR) {\n return false;\n }\n\n // Check for explicit FORCE_COLOR env var\n if (process.env?.FORCE_COLOR) {\n return true;\n }\n\n // Check if stdout is a TTY\n if (process.stdout?.isTTY) {\n return true;\n }\n\n // Default to no color in CI environments\n return !isCI();\n}\n\n/**\n * Create a configuration with defaults\n */\nexport function createErrorConfig(\n config?: ErrorFormatterConfig\n): Required<ErrorFormatterConfig> {\n // Get fresh defaults that evaluate environment at call time\n const defaults = getDefaultConfig();\n return {\n ...defaults,\n ...config,\n };\n}\n\n/**\n * Format an error message based on configuration\n */\nexport function formatErrorMessage(\n message: string,\n config: ErrorFormatterConfig = {}\n): string {\n const finalConfig = createErrorConfig(config);\n\n let formatted = message;\n\n // Remove emojis if not wanted\n if (!finalConfig.includeEmojis) {\n Object.values(ERROR_EMOJIS).forEach((emoji) => {\n formatted = formatted.replace(new RegExp(emoji, 'g'), '');\n });\n // Clean up extra spaces\n formatted = formatted.replace(/\\s+/g, ' ').trim();\n }\n\n // Truncate if needed\n if (\n finalConfig.maxMessageLength > 0 &&\n formatted.length > finalConfig.maxMessageLength\n ) {\n formatted =\n formatted.substring(0, finalConfig.maxMessageLength - 3) + '...';\n }\n\n return formatted;\n}\n","/**\n * Theme validation implementation\n * Single source of truth for all theme validation\n */\n\nimport type { Static } from '@sinclair/typebox';\nimport { ThemeConfigSchema } from '../../schemas/theme';\nimport type { ValidationOptions } from './types';\nimport { validateAgainstSchema, validateJson } from './base-validator';\n\n// Re-export ThemeValidationResult type\nexport type { ThemeValidationResult } from './types';\nimport type { ThemeValidationResult } from './types';\n\n/**\n * Validate a theme configuration object\n */\nexport function validateTheme(\n data: unknown,\n options?: ValidationOptions\n): ThemeValidationResult {\n // Handle string input (theme name)\n if (typeof data === 'string') {\n // This is just a theme name, not a theme config\n // It will be resolved later by the theme resolver\n return {\n valid: true,\n themeName: data,\n };\n }\n\n const result = validateAgainstSchema(ThemeConfigSchema, data, options);\n\n // Add theme-specific metadata\n const themeResult: ThemeValidationResult = {\n ...result,\n };\n\n // Extract theme name if present\n if (result.valid && result.data) {\n const theme = result.data as any;\n if (theme.name) {\n themeResult.themeName = theme.name;\n }\n }\n\n return themeResult;\n}\n\n/**\n * Validate a theme JSON string or object\n * This replaces all three validateThemeJson implementations\n */\nexport function validateThemeJson(\n jsonInput: string | object,\n options?: ValidationOptions\n): ThemeValidationResult {\n const result = validateJson(ThemeConfigSchema, jsonInput, options);\n\n // Add theme-specific metadata\n const themeResult: ThemeValidationResult = {\n ...result,\n };\n\n // Extract theme name if present\n if (result.valid && result.data) {\n const theme = result.data as any;\n\n // Inject default $schema if missing and it's an object\n if (typeof theme === 'object' && !theme.$schema) {\n theme.$schema = './json-schemas/theme.schema.json';\n }\n\n if (theme.name) {\n themeResult.themeName = theme.name;\n }\n }\n\n return themeResult;\n}\n\n/**\n * Validate theme with enhanced error messages\n */\nexport function validateThemeWithEnhancement(\n data: unknown,\n options?: ValidationOptions\n): ThemeValidationResult {\n const result = validateTheme(data, options);\n\n // Enhance errors with theme-specific suggestions\n if (!result.valid && result.errors) {\n result.errors = result.errors.map((error) => {\n // Add specific suggestions for common theme errors\n if (error.path.includes('colors') && !error.suggestion) {\n error.suggestion = 'Colors must be valid hex, rgb, or named colors';\n }\n if (error.path.includes('fonts') && !error.suggestion) {\n error.suggestion = 'Fonts must include size and family properties';\n }\n if (error.path.includes('headings') && !error.suggestion) {\n error.suggestion = 'Headings must be an array of 6 style definitions';\n }\n return error;\n });\n }\n\n return result;\n}\n\n/**\n * Type guard for valid theme result\n */\nexport function isValidTheme(\n result: ThemeValidationResult\n): result is ThemeValidationResult & {\n valid: true;\n data: Static<typeof ThemeConfigSchema>;\n} {\n return result.valid === true && result.data !== undefined;\n}\n\n/**\n * Create a theme validator with default options\n */\nexport function createThemeValidator(defaultOptions?: ValidationOptions) {\n return {\n validate: (data: unknown, options?: ValidationOptions) =>\n validateTheme(data, { ...defaultOptions, ...options }),\n validateJson: (jsonInput: string | object, options?: ValidationOptions) =>\n validateThemeJson(jsonInput, { ...defaultOptions, ...options }),\n validateWithEnhancement: (data: unknown, options?: ValidationOptions) =>\n validateThemeWithEnhancement(data, { ...defaultOptions, ...options }),\n };\n}\n\n// Export convenient validators with common configurations\nexport const themeValidator = createThemeValidator({\n clean: true,\n applyDefaults: true,\n});\n\nexport const strictThemeValidator = createThemeValidator({\n clean: false,\n applyDefaults: false,\n maxErrors: 10,\n});\n\n/**\n * Get theme name from data\n */\nexport function getThemeName(data: unknown): string | undefined {\n if (typeof data === 'string') {\n return data;\n }\n\n if (typeof data === 'object' && data !== null && 'name' in data) {\n const theme = data as any;\n if (typeof theme.name === 'string') {\n return theme.name;\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if theme config is valid (basic check without full validation)\n */\nexport function isThemeConfig(data: unknown): boolean {\n if (!data || typeof data !== 'object') {\n return false;\n }\n\n const theme = data as any;\n return !!(theme.colors && theme.fonts);\n}\n","/**\n * Component validation implementation\n * Single source of truth for all component validation\n */\n\nimport { Value } from '@sinclair/typebox/value';\nimport type { Static, TSchema } from '@sinclair/typebox';\nimport {\n ReportPropsSchema,\n SectionPropsSchema,\n HeadingPropsSchema,\n ParagraphPropsSchema,\n ColumnsPropsSchema,\n ImagePropsSchema,\n StatisticPropsSchema,\n TablePropsSchema,\n HeaderPropsSchema,\n FooterPropsSchema,\n ListPropsSchema,\n ComponentDefinitionSchema,\n} from '../../schemas/components';\nimport { CustomComponentDefinitionSchema } from '../../schemas/custom-components';\nimport type { ComponentValidationResult, ValidationOptions } from './types';\nimport { validateAgainstSchema } from './base-validator';\n\n// Map of standard component names to their schemas\nconst COMPONENT_SCHEMA_MAP = {\n report: ReportPropsSchema,\n section: SectionPropsSchema,\n heading: HeadingPropsSchema,\n paragraph: ParagraphPropsSchema,\n columns: ColumnsPropsSchema,\n image: ImagePropsSchema,\n statistic: StatisticPropsSchema,\n table: TablePropsSchema,\n header: HeaderPropsSchema,\n footer: FooterPropsSchema,\n list: ListPropsSchema,\n custom: CustomComponentDefinitionSchema,\n} as const;\n\nexport type StandardComponentName = keyof typeof COMPONENT_SCHEMA_MAP;\n\n/**\n * Validate a component configuration by type\n */\nexport function validateComponent<T extends StandardComponentName>(\n name: T,\n props: unknown,\n options?: ValidationOptions\n): ComponentValidationResult<any> {\n const schema = COMPONENT_SCHEMA_MAP[name];\n\n if (!schema) {\n // Unknown component type, try custom component schema\n const customResult = validateAgainstSchema(\n CustomComponentDefinitionSchema,\n props,\n options\n );\n\n return {\n ...customResult,\n success: customResult.valid, // Add success for backward compatibility\n componentName: name,\n isCustomComponent: true,\n };\n }\n\n const result = validateAgainstSchema(schema, props, options);\n\n return {\n ...result,\n success: result.valid, // Add success for backward compatibility\n componentName: name,\n isCustomComponent: name === 'custom',\n };\n}\n\n/**\n * Validate a complete component definition (including nested children)\n */\nexport function validateComponentDefinition(\n component: unknown,\n options?: ValidationOptions\n): ComponentValidationResult {\n const result = validateAgainstSchema(\n ComponentDefinitionSchema,\n component,\n options\n );\n\n // Add component-specific metadata\n const componentResult: ComponentValidationResult = {\n ...result,\n };\n\n if (result.valid && result.data) {\n const comp = result.data as any;\n componentResult.componentName = comp.name;\n componentResult.isCustomComponent = !isStandardComponentName(comp.name);\n }\n\n return componentResult;\n}\n\n/**\n * Validate a custom component configuration with a custom schema\n * This is for plugin components that have their own TypeBox schema\n */\nexport function validateCustomComponentProps<T>(\n componentSchema: TSchema,\n config: unknown,\n options?: ValidationOptions\n): ComponentValidationResult<T> {\n try {\n // Use the custom schema for validation\n const result = validateAgainstSchema(componentSchema, config, {\n ...options,\n clean: options?.clean ?? true,\n applyDefaults: options?.applyDefaults ?? true,\n });\n\n return {\n ...result,\n success: result.valid, // Add success for backward compatibility\n data: result.data as T, // Cast to generic type T\n componentName: 'custom',\n isCustomComponent: true,\n };\n } catch (error) {\n return {\n valid: false,\n success: false, // Add success for backward compatibility\n errors: [\n {\n path: 'props',\n message:\n error instanceof Error ? error.message : 'Unknown validation error',\n code: 'validation_exception',\n },\n ],\n componentName: 'custom',\n isCustomComponent: true,\n };\n }\n}\n\n/**\n * Batch validate multiple components\n */\nexport function validateComponents(\n components: Array<{ name: string; props: unknown }>,\n options?: ValidationOptions\n): ComponentValidationResult[] {\n return components.map(({ name, props }) => {\n if (isStandardComponentName(name)) {\n return validateComponent(name, props, options);\n }\n return validateComponent('custom', props, options);\n });\n}\n\n/**\n * Type guards for component names\n */\nexport function isStandardComponentName(\n name: string\n): name is StandardComponentName {\n return name in COMPONENT_SCHEMA_MAP;\n}\n\nexport function isReportProps(\n config: unknown\n): config is Static<typeof ReportPropsSchema> {\n return Value.Check(ReportPropsSchema, config);\n}\n\nexport function isSectionProps(\n config: unknown\n): config is Static<typeof SectionPropsSchema> {\n return Value.Check(SectionPropsSchema, config);\n}\n\nexport function isHeadingProps(\n config: unknown\n): config is Static<typeof HeadingPropsSchema> {\n return Value.Check(HeadingPropsSchema, config);\n}\n\nexport function isParagraphProps(\n config: unknown\n): config is Static<typeof ParagraphPropsSchema> {\n return Value.Check(ParagraphPropsSchema, config);\n}\n\nexport function isColumnsProps(\n config: unknown\n): config is Static<typeof ColumnsPropsSchema> {\n return Value.Check(ColumnsPropsSchema, config);\n}\n\nexport function isImageProps(\n config: unknown\n): config is Static<typeof ImagePropsSchema> {\n return Value.Check(ImagePropsSchema, config);\n}\n\nexport function isStatisticProps(\n config: unknown\n): config is Static<typeof StatisticPropsSchema> {\n return Value.Check(StatisticPropsSchema, config);\n}\n\nexport function isTableProps(\n config: unknown\n): config is Static<typeof TablePropsSchema> {\n return Value.Check(TablePropsSchema, config);\n}\n\nexport function isHeaderProps(\n config: unknown\n): config is Static<typeof HeaderPropsSchema> {\n return Value.Check(HeaderPropsSchema, config);\n}\n\nexport function isFooterProps(\n config: unknown\n): config is Static<typeof FooterPropsSchema> {\n return Value.Check(FooterPropsSchema, config);\n}\n\nexport function isListProps(\n config: unknown\n): config is Static<typeof ListPropsSchema> {\n return Value.Check(ListPropsSchema, config);\n}\n\nexport function isCustomComponentProps(\n config: unknown\n): config is Static<typeof CustomComponentDefinitionSchema> {\n return Value.Check(CustomComponentDefinitionSchema, config);\n}\n\n/**\n * Create a component validator with default options\n */\nexport function createComponentValidator(defaultOptions?: ValidationOptions) {\n return {\n validate: (name: string, props: unknown, options?: ValidationOptions) => {\n if (isStandardComponentName(name)) {\n return validateComponent(name, props, {\n ...defaultOptions,\n ...options,\n });\n }\n return validateComponent('custom', props, {\n ...defaultOptions,\n ...options,\n });\n },\n validateDefinition: (component: unknown, options?: ValidationOptions) =>\n validateComponentDefinition(component, { ...defaultOptions, ...options }),\n validateCustom: <T>(\n schema: TSchema,\n config: unknown,\n options?: ValidationOptions\n ) =>\n validateCustomComponentProps<T>(schema, config, {\n ...defaultOptions,\n ...options,\n }),\n };\n}\n\n// Export convenient validators with common configurations\nexport const componentValidator = createComponentValidator({\n clean: true,\n applyDefaults: true,\n});\n\nexport const strictComponentValidator = createComponentValidator({\n clean: false,\n applyDefaults: false,\n maxErrors: 10,\n});\n"],"mappings":"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","names":["DEFAULT_ERROR_CONFIG"]}
|
|
1
|
+
{"version":3,"sources":["../src/validation/unified/index.ts","../src/validation/unified/error-formatter-config.ts","../src/validation/unified/theme-validator.ts","../src/validation/unified/component-validator.ts"],"sourcesContent":["/**\n * Unified validation facade\n * Simple, clean API for all validation needs\n */\n\n// Format-agnostic types re-exported from @json-to-office/shared\nexport type { ValidationError, ValidationResult } from '@json-to-office/shared';\n\n// Docx-specific extended types (local)\nexport type {\n ValidationOptions,\n JsonValidationResult,\n ThemeValidationResult,\n DocumentValidationResult,\n ComponentValidationResult,\n EnhancedValueError,\n} from './types';\n\n// Format-agnostic error utilities re-exported from @json-to-office/shared\nexport {\n transformValueError,\n transformValueErrors,\n calculatePosition,\n formatErrorSummary,\n groupErrorsByPath,\n createJsonParseError,\n} from '@json-to-office/shared';\n\n// Docx-specific error transformer (local, extends shared with docx-specific messages)\nexport {\n transformValueError as transformDocxValueError,\n transformValueErrors as transformDocxValueErrors,\n} from './error-transformer';\n\n// Export deep validation utilities (docx-specific)\nexport {\n deepValidateDocument,\n comprehensiveValidateDocument,\n} from './deep-validator';\n\n// Format-agnostic schema utilities re-exported from @json-to-office/shared\nexport {\n isUnionSchema,\n isObjectSchema,\n isLiteralSchema,\n getObjectSchemaPropertyNames,\n getLiteralValue,\n extractStandardComponentNames,\n clearComponentNamesCache,\n getSchemaMetadata,\n} from '@json-to-office/shared';\n\n// Format-agnostic error formatter config re-exported from @json-to-office/shared\nexport {\n type ErrorFormatterConfig,\n DEFAULT_ERROR_CONFIG,\n ERROR_EMOJIS,\n createErrorConfig,\n formatErrorMessage,\n} from '@json-to-office/shared';\n\n// Docx-specific error formatter extras (local)\nexport { ERROR_TEMPLATES, DOC_LINKS } from './error-formatter-config';\n\n// Export base validator utilities\nexport {\n validateAgainstSchema,\n validateJson,\n validateBatch,\n validateWithEnhancement,\n createValidator,\n createJsonValidator,\n isValidationSuccess,\n getValidationSummary,\n} from './base-validator';\n\n// Export document validation\nexport {\n validateDocument,\n validateJsonDocument,\n isValidDocument,\n createDocumentValidator,\n documentValidator,\n strictDocumentValidator,\n // Legacy compatibility\n validateJsonComponent,\n validateDocumentWithSchema,\n} from './document-validator';\n\n// Export theme validation\nexport {\n validateTheme,\n validateThemeJson,\n validateThemeWithEnhancement,\n isValidTheme,\n createThemeValidator,\n themeValidator,\n strictThemeValidator,\n getThemeName,\n isThemeConfig,\n} from './theme-validator';\n\n// Export component validation\nexport {\n validateComponent,\n validateComponentDefinition,\n validateCustomComponentProps,\n validateComponents,\n isStandardComponentName,\n createComponentValidator,\n componentValidator,\n strictComponentValidator,\n // Type guards\n isReportProps,\n isSectionProps,\n isHeadingProps,\n isParagraphProps,\n isColumnsProps,\n isImageProps,\n isStatisticProps,\n isTableProps,\n isHeaderProps,\n isFooterProps,\n isListProps,\n isCustomComponentProps,\n // Types\n type StandardComponentName,\n} from './component-validator';\n\n// Import the validators we need\nimport {\n documentValidator,\n strictDocumentValidator,\n} from './document-validator';\nimport { themeValidator, strictThemeValidator } from './theme-validator';\nimport {\n componentValidator,\n strictComponentValidator,\n} from './component-validator';\n\n/**\n * Simple validation API\n * The main entry point for most validation needs\n */\nexport const validate = {\n // Document validation\n document: (data: unknown) => documentValidator.validate(data),\n jsonDocument: (jsonInput: string | object) =>\n documentValidator.validateJson(jsonInput),\n\n // Theme validation\n theme: (data: unknown) => themeValidator.validate(data),\n jsonTheme: (jsonInput: string | object) =>\n themeValidator.validateJson(jsonInput),\n\n // Component validation\n component: (name: string, props: unknown) =>\n componentValidator.validate(name, props),\n componentDefinition: (component: unknown) =>\n componentValidator.validateDefinition(component),\n\n // Batch operations\n components: (components: Array<{ name: string; props: unknown }>) =>\n components.map((c) => componentValidator.validate(c.name, c.props)),\n\n // Type checking (non-throwing)\n isDocument: (data: unknown) => {\n const result = documentValidator.validate(data);\n return result.valid;\n },\n isTheme: (data: unknown) => {\n const result = themeValidator.validate(data);\n return result.valid;\n },\n isComponent: (name: string, props: unknown) => {\n const result = componentValidator.validate(name, props);\n return result.valid;\n },\n};\n\n/**\n * Strict validation API\n * For cases where you want no cleaning or defaults\n */\nexport const validateStrict = {\n document: (data: unknown) => strictDocumentValidator.validate(data),\n jsonDocument: (jsonInput: string | object) =>\n strictDocumentValidator.validateJson(jsonInput),\n theme: (data: unknown) => strictThemeValidator.validate(data),\n jsonTheme: (jsonInput: string | object) =>\n strictThemeValidator.validateJson(jsonInput),\n component: (name: string, props: unknown) =>\n strictComponentValidator.validate(name, props),\n componentDefinition: (component: unknown) =>\n strictComponentValidator.validateDefinition(component),\n};\n","/**\n * Error Formatter Configuration\n * Configurable error message formatting options\n */\n\n/**\n * Error formatter configuration options\n */\nexport interface ErrorFormatterConfig {\n /**\n * Include emoji indicators in error messages\n * Default: true (false in CI environments)\n */\n includeEmojis?: boolean;\n\n /**\n * Verbosity level for error messages\n * - minimal: Just the error message\n * - normal: Error message with path\n * - detailed: Full error with suggestions and context\n * Default: 'normal'\n */\n verbosity?: 'minimal' | 'normal' | 'detailed';\n\n /**\n * Include suggestions for fixing errors\n * Default: true\n */\n includeSuggestions?: boolean;\n\n /**\n * Include stack trace or error path\n * Default: true\n */\n includePath?: boolean;\n\n /**\n * Maximum error message length (0 = unlimited)\n * Default: 0\n */\n maxMessageLength?: number;\n\n /**\n * Include links to documentation\n * Default: false\n */\n includeDocLinks?: boolean;\n\n /**\n * Terminal color support\n * Default: auto-detected\n */\n colorSupport?: boolean;\n}\n\n/**\n * Get default configuration\n * Evaluates environment variables at call time, not module load time\n */\nfunction getDefaultConfig(): Required<ErrorFormatterConfig> {\n return {\n includeEmojis: !isCI(),\n verbosity: 'normal',\n includeSuggestions: true,\n includePath: true,\n maxMessageLength: 0,\n includeDocLinks: false,\n colorSupport: hasColorSupport(),\n };\n}\n\n/**\n * Default configuration (for backward compatibility)\n */\nexport const DEFAULT_ERROR_CONFIG: Required<ErrorFormatterConfig> =\n getDefaultConfig();\n\n/**\n * Error message templates\n */\nexport const ERROR_TEMPLATES = {\n UNION_NO_MATCH: 'Value doesn\\'t match any of the expected formats',\n TYPE_MISMATCH: 'Expected {expected} but got {actual}',\n MISSING_REQUIRED: 'Missing required field \\'{field}\\'',\n UNKNOWN_PROPERTY: 'Unknown property \\'{property}\\'',\n INVALID_FORMAT: 'Invalid {type} format',\n PATTERN_MISMATCH: 'Value doesn\\'t match the required pattern',\n} as const;\n\n/**\n * Emoji indicators for different error types\n */\nexport const ERROR_EMOJIS = {\n ERROR: '❌',\n WARNING: '⚠️',\n INFO: 'ℹ️',\n SUGGESTION: '💡',\n FIX: '🔧',\n LINK: '🔗',\n} as const;\n\n/**\n * Documentation links for common errors\n */\nexport const DOC_LINKS = {\n MODULE_TYPES: 'https://docs.json-to-docx.com/modules',\n THEME_CONFIG: 'https://docs.json-to-docx.com/themes',\n VALIDATION: 'https://docs.json-to-docx.com/validation',\n} as const;\n\n/**\n * Detect if running in CI environment\n */\nfunction isCI(): boolean {\n // Check if we're in a Node environment\n if (typeof process === 'undefined' || !process.env) {\n return false;\n }\n\n return !!(\n process.env.CI ||\n process.env.CONTINUOUS_INTEGRATION ||\n process.env.GITHUB_ACTIONS ||\n process.env.GITLAB_CI ||\n process.env.CIRCLECI ||\n process.env.TRAVIS ||\n process.env.JENKINS_URL\n );\n}\n\n/**\n * Detect terminal color support\n */\nfunction hasColorSupport(): boolean {\n // Check if we're in a Node environment\n if (typeof process === 'undefined') {\n return false;\n }\n\n // Check for explicit NO_COLOR env var\n if (process.env?.NO_COLOR) {\n return false;\n }\n\n // Check for explicit FORCE_COLOR env var\n if (process.env?.FORCE_COLOR) {\n return true;\n }\n\n // Check if stdout is a TTY\n if (process.stdout?.isTTY) {\n return true;\n }\n\n // Default to no color in CI environments\n return !isCI();\n}\n\n/**\n * Create a configuration with defaults\n */\nexport function createErrorConfig(\n config?: ErrorFormatterConfig\n): Required<ErrorFormatterConfig> {\n // Get fresh defaults that evaluate environment at call time\n const defaults = getDefaultConfig();\n return {\n ...defaults,\n ...config,\n };\n}\n\n/**\n * Format an error message based on configuration\n */\nexport function formatErrorMessage(\n message: string,\n config: ErrorFormatterConfig = {}\n): string {\n const finalConfig = createErrorConfig(config);\n\n let formatted = message;\n\n // Remove emojis if not wanted\n if (!finalConfig.includeEmojis) {\n Object.values(ERROR_EMOJIS).forEach((emoji) => {\n formatted = formatted.replace(new RegExp(emoji, 'g'), '');\n });\n // Clean up extra spaces\n formatted = formatted.replace(/\\s+/g, ' ').trim();\n }\n\n // Truncate if needed\n if (\n finalConfig.maxMessageLength > 0 &&\n formatted.length > finalConfig.maxMessageLength\n ) {\n formatted =\n formatted.substring(0, finalConfig.maxMessageLength - 3) + '...';\n }\n\n return formatted;\n}\n","/**\n * Theme validation implementation\n * Single source of truth for all theme validation\n */\n\nimport type { Static } from '@sinclair/typebox';\nimport { ThemeConfigSchema } from '../../schemas/theme';\nimport type { ValidationOptions } from './types';\nimport { validateAgainstSchema, validateJson } from './base-validator';\n\n// Re-export ThemeValidationResult type\nexport type { ThemeValidationResult } from './types';\nimport type { ThemeValidationResult } from './types';\n\n/**\n * Validate a theme configuration object\n */\nexport function validateTheme(\n data: unknown,\n options?: ValidationOptions\n): ThemeValidationResult {\n // Handle string input (theme name)\n if (typeof data === 'string') {\n // This is just a theme name, not a theme config\n // It will be resolved later by the theme resolver\n return {\n valid: true,\n themeName: data,\n };\n }\n\n const result = validateAgainstSchema(ThemeConfigSchema, data, options);\n\n // Add theme-specific metadata\n const themeResult: ThemeValidationResult = {\n ...result,\n };\n\n // Extract theme name if present\n if (result.valid && result.data) {\n const theme = result.data as any;\n if (theme.name) {\n themeResult.themeName = theme.name;\n }\n }\n\n return themeResult;\n}\n\n/**\n * Validate a theme JSON string or object\n * This replaces all three validateThemeJson implementations\n */\nexport function validateThemeJson(\n jsonInput: string | object,\n options?: ValidationOptions\n): ThemeValidationResult {\n const result = validateJson(ThemeConfigSchema, jsonInput, options);\n\n // Add theme-specific metadata\n const themeResult: ThemeValidationResult = {\n ...result,\n };\n\n // Extract theme name if present\n if (result.valid && result.data) {\n const theme = result.data as any;\n\n // Inject default $schema if missing and it's an object\n if (typeof theme === 'object' && !theme.$schema) {\n theme.$schema = './json-schemas/theme.schema.json';\n }\n\n if (theme.name) {\n themeResult.themeName = theme.name;\n }\n }\n\n return themeResult;\n}\n\n/**\n * Validate theme with enhanced error messages\n */\nexport function validateThemeWithEnhancement(\n data: unknown,\n options?: ValidationOptions\n): ThemeValidationResult {\n const result = validateTheme(data, options);\n\n // Enhance errors with theme-specific suggestions\n if (!result.valid && result.errors) {\n result.errors = result.errors.map((error) => {\n // Add specific suggestions for common theme errors\n if (error.path.includes('colors') && !error.suggestion) {\n error.suggestion = 'Colors must be valid hex, rgb, or named colors';\n }\n if (error.path.includes('fonts') && !error.suggestion) {\n error.suggestion = 'Fonts must include size and family properties';\n }\n if (error.path.includes('headings') && !error.suggestion) {\n error.suggestion = 'Headings must be an array of 6 style definitions';\n }\n return error;\n });\n }\n\n return result;\n}\n\n/**\n * Type guard for valid theme result\n */\nexport function isValidTheme(\n result: ThemeValidationResult\n): result is ThemeValidationResult & {\n valid: true;\n data: Static<typeof ThemeConfigSchema>;\n} {\n return result.valid === true && result.data !== undefined;\n}\n\n/**\n * Create a theme validator with default options\n */\nexport function createThemeValidator(defaultOptions?: ValidationOptions) {\n return {\n validate: (data: unknown, options?: ValidationOptions) =>\n validateTheme(data, { ...defaultOptions, ...options }),\n validateJson: (jsonInput: string | object, options?: ValidationOptions) =>\n validateThemeJson(jsonInput, { ...defaultOptions, ...options }),\n validateWithEnhancement: (data: unknown, options?: ValidationOptions) =>\n validateThemeWithEnhancement(data, { ...defaultOptions, ...options }),\n };\n}\n\n// Export convenient validators with common configurations\nexport const themeValidator = createThemeValidator({\n clean: true,\n applyDefaults: true,\n});\n\nexport const strictThemeValidator = createThemeValidator({\n clean: false,\n applyDefaults: false,\n maxErrors: 10,\n});\n\n/**\n * Get theme name from data\n */\nexport function getThemeName(data: unknown): string | undefined {\n if (typeof data === 'string') {\n return data;\n }\n\n if (typeof data === 'object' && data !== null && 'name' in data) {\n const theme = data as any;\n if (typeof theme.name === 'string') {\n return theme.name;\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if theme config is valid (basic check without full validation)\n */\nexport function isThemeConfig(data: unknown): boolean {\n if (!data || typeof data !== 'object') {\n return false;\n }\n\n const theme = data as any;\n return !!(theme.colors && theme.fonts);\n}\n","/**\n * Component validation implementation\n * Single source of truth for all component validation\n */\n\nimport { Value } from '@sinclair/typebox/value';\nimport type { Static, TSchema } from '@sinclair/typebox';\nimport { validateCustomComponentProps as sharedValidateCustomComponentProps } from '@json-to-office/shared/plugin';\nimport {\n ReportPropsSchema,\n SectionPropsSchema,\n HeadingPropsSchema,\n ParagraphPropsSchema,\n ColumnsPropsSchema,\n ImagePropsSchema,\n StatisticPropsSchema,\n TablePropsSchema,\n HeaderPropsSchema,\n FooterPropsSchema,\n ListPropsSchema,\n ComponentDefinitionSchema,\n} from '../../schemas/components';\nimport { CustomComponentDefinitionSchema } from '../../schemas/custom-components';\nimport type { ComponentValidationResult, ValidationOptions } from './types';\nimport { validateAgainstSchema } from './base-validator';\n\n// Map of standard component names to their schemas\nconst COMPONENT_SCHEMA_MAP = {\n report: ReportPropsSchema,\n section: SectionPropsSchema,\n heading: HeadingPropsSchema,\n paragraph: ParagraphPropsSchema,\n columns: ColumnsPropsSchema,\n image: ImagePropsSchema,\n statistic: StatisticPropsSchema,\n table: TablePropsSchema,\n header: HeaderPropsSchema,\n footer: FooterPropsSchema,\n list: ListPropsSchema,\n custom: CustomComponentDefinitionSchema,\n} as const;\n\nexport type StandardComponentName = keyof typeof COMPONENT_SCHEMA_MAP;\n\n/**\n * Validate a component configuration by type\n */\nexport function validateComponent<T extends StandardComponentName>(\n name: T,\n props: unknown,\n options?: ValidationOptions\n): ComponentValidationResult<any> {\n const schema = COMPONENT_SCHEMA_MAP[name];\n\n if (!schema) {\n // Unknown component type, try custom component schema\n const customResult = validateAgainstSchema(\n CustomComponentDefinitionSchema,\n props,\n options\n );\n\n return {\n ...customResult,\n success: customResult.valid, // Add success for backward compatibility\n componentName: name,\n isCustomComponent: true,\n };\n }\n\n const result = validateAgainstSchema(schema, props, options);\n\n return {\n ...result,\n success: result.valid, // Add success for backward compatibility\n componentName: name,\n isCustomComponent: name === 'custom',\n };\n}\n\n/**\n * Validate a complete component definition (including nested children)\n */\nexport function validateComponentDefinition(\n component: unknown,\n options?: ValidationOptions\n): ComponentValidationResult {\n const result = validateAgainstSchema(\n ComponentDefinitionSchema,\n component,\n options\n );\n\n // Add component-specific metadata\n const componentResult: ComponentValidationResult = {\n ...result,\n };\n\n if (result.valid && result.data) {\n const comp = result.data as any;\n componentResult.componentName = comp.name;\n componentResult.isCustomComponent = !isStandardComponentName(comp.name);\n }\n\n return componentResult;\n}\n\n/**\n * Validate a custom component configuration with a custom schema.\n * Delegates to @json-to-office/shared/plugin to avoid duplication.\n */\nexport function validateCustomComponentProps<T>(\n componentSchema: TSchema,\n config: unknown,\n options?: ValidationOptions\n): ComponentValidationResult<T> {\n return sharedValidateCustomComponentProps<T>(\n componentSchema,\n config,\n options\n );\n}\n\n/**\n * Batch validate multiple components\n */\nexport function validateComponents(\n components: Array<{ name: string; props: unknown }>,\n options?: ValidationOptions\n): ComponentValidationResult[] {\n return components.map(({ name, props }) => {\n if (isStandardComponentName(name)) {\n return validateComponent(name, props, options);\n }\n return validateComponent('custom', props, options);\n });\n}\n\n/**\n * Type guards for component names\n */\nexport function isStandardComponentName(\n name: string\n): name is StandardComponentName {\n return name in COMPONENT_SCHEMA_MAP;\n}\n\nexport function isReportProps(\n config: unknown\n): config is Static<typeof ReportPropsSchema> {\n return Value.Check(ReportPropsSchema, config);\n}\n\nexport function isSectionProps(\n config: unknown\n): config is Static<typeof SectionPropsSchema> {\n return Value.Check(SectionPropsSchema, config);\n}\n\nexport function isHeadingProps(\n config: unknown\n): config is Static<typeof HeadingPropsSchema> {\n return Value.Check(HeadingPropsSchema, config);\n}\n\nexport function isParagraphProps(\n config: unknown\n): config is Static<typeof ParagraphPropsSchema> {\n return Value.Check(ParagraphPropsSchema, config);\n}\n\nexport function isColumnsProps(\n config: unknown\n): config is Static<typeof ColumnsPropsSchema> {\n return Value.Check(ColumnsPropsSchema, config);\n}\n\nexport function isImageProps(\n config: unknown\n): config is Static<typeof ImagePropsSchema> {\n return Value.Check(ImagePropsSchema, config);\n}\n\nexport function isStatisticProps(\n config: unknown\n): config is Static<typeof StatisticPropsSchema> {\n return Value.Check(StatisticPropsSchema, config);\n}\n\nexport function isTableProps(\n config: unknown\n): config is Static<typeof TablePropsSchema> {\n return Value.Check(TablePropsSchema, config);\n}\n\nexport function isHeaderProps(\n config: unknown\n): config is Static<typeof HeaderPropsSchema> {\n return Value.Check(HeaderPropsSchema, config);\n}\n\nexport function isFooterProps(\n config: unknown\n): config is Static<typeof FooterPropsSchema> {\n return Value.Check(FooterPropsSchema, config);\n}\n\nexport function isListProps(\n config: unknown\n): config is Static<typeof ListPropsSchema> {\n return Value.Check(ListPropsSchema, config);\n}\n\nexport function isCustomComponentProps(\n config: unknown\n): config is Static<typeof CustomComponentDefinitionSchema> {\n return Value.Check(CustomComponentDefinitionSchema, config);\n}\n\n/**\n * Create a component validator with default options\n */\nexport function createComponentValidator(defaultOptions?: ValidationOptions) {\n return {\n validate: (name: string, props: unknown, options?: ValidationOptions) => {\n if (isStandardComponentName(name)) {\n return validateComponent(name, props, {\n ...defaultOptions,\n ...options,\n });\n }\n return validateComponent('custom', props, {\n ...defaultOptions,\n ...options,\n });\n },\n validateDefinition: (component: unknown, options?: ValidationOptions) =>\n validateComponentDefinition(component, { ...defaultOptions, ...options }),\n validateCustom: <T>(\n schema: TSchema,\n config: unknown,\n options?: ValidationOptions\n ) =>\n validateCustomComponentProps<T>(schema, config, {\n ...defaultOptions,\n ...options,\n }),\n };\n}\n\n// Export convenient validators with common configurations\nexport const componentValidator = createComponentValidator({\n clean: true,\n applyDefaults: true,\n});\n\nexport const strictComponentValidator = createComponentValidator({\n clean: false,\n applyDefaults: false,\n maxErrors: 10,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP;AAAA,EAEE,wBAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACAP,SAAS,mBAAmD;AAC1D,SAAO;AAAA,IACL,eAAe,CAAC,KAAK;AAAA,IACrB,WAAW;AAAA,IACX,oBAAoB;AAAA,IACpB,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,IACjB,cAAc,gBAAgB;AAAA,EAChC;AACF;AAKO,IAAM,uBACX,iBAAiB;AAKZ,IAAM,kBAAkB;AAAA,EAC7B,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,kBAAkB;AACpB;AAiBO,IAAM,YAAY;AAAA,EACvB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,YAAY;AACd;AAKA,SAAS,OAAgB;AAEvB,MAAI,OAAO,YAAY,eAAe,CAAC,QAAQ,KAAK;AAClD,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,EACN,QAAQ,IAAI,MACZ,QAAQ,IAAI,0BACZ,QAAQ,IAAI,kBACZ,QAAQ,IAAI,aACZ,QAAQ,IAAI,YACZ,QAAQ,IAAI,UACZ,QAAQ,IAAI;AAEhB;AAKA,SAAS,kBAA2B;AAElC,MAAI,OAAO,YAAY,aAAa;AAClC,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,KAAK,UAAU;AACzB,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,KAAK,aAAa;AAC5B,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,QAAQ,OAAO;AACzB,WAAO;AAAA,EACT;AAGA,SAAO,CAAC,KAAK;AACf;;;AC3IO,SAAS,cACd,MACA,SACuB;AAEvB,MAAI,OAAO,SAAS,UAAU;AAG5B,WAAO;AAAA,MACL,OAAO;AAAA,MACP,WAAW;AAAA,IACb;AAAA,EACF;AAEA,QAAM,SAAS,sBAAsB,mBAAmB,MAAM,OAAO;AAGrE,QAAM,cAAqC;AAAA,IACzC,GAAG;AAAA,EACL;AAGA,MAAI,OAAO,SAAS,OAAO,MAAM;AAC/B,UAAM,QAAQ,OAAO;AACrB,QAAI,MAAM,MAAM;AACd,kBAAY,YAAY,MAAM;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AACT;AAMO,SAAS,kBACd,WACA,SACuB;AACvB,QAAM,SAAS,aAAa,mBAAmB,WAAW,OAAO;AAGjE,QAAM,cAAqC;AAAA,IACzC,GAAG;AAAA,EACL;AAGA,MAAI,OAAO,SAAS,OAAO,MAAM;AAC/B,UAAM,QAAQ,OAAO;AAGrB,QAAI,OAAO,UAAU,YAAY,CAAC,MAAM,SAAS;AAC/C,YAAM,UAAU;AAAA,IAClB;AAEA,QAAI,MAAM,MAAM;AACd,kBAAY,YAAY,MAAM;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,6BACd,MACA,SACuB;AACvB,QAAM,SAAS,cAAc,MAAM,OAAO;AAG1C,MAAI,CAAC,OAAO,SAAS,OAAO,QAAQ;AAClC,WAAO,SAAS,OAAO,OAAO,IAAI,CAAC,UAAU;AAE3C,UAAI,MAAM,KAAK,SAAS,QAAQ,KAAK,CAAC,MAAM,YAAY;AACtD,cAAM,aAAa;AAAA,MACrB;AACA,UAAI,MAAM,KAAK,SAAS,OAAO,KAAK,CAAC,MAAM,YAAY;AACrD,cAAM,aAAa;AAAA,MACrB;AACA,UAAI,MAAM,KAAK,SAAS,UAAU,KAAK,CAAC,MAAM,YAAY;AACxD,cAAM,aAAa;AAAA,MACrB;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAKO,SAAS,aACd,QAIA;AACA,SAAO,OAAO,UAAU,QAAQ,OAAO,SAAS;AAClD;AAKO,SAAS,qBAAqB,gBAAoC;AACvE,SAAO;AAAA,IACL,UAAU,CAAC,MAAe,YACxB,cAAc,MAAM,EAAE,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAAA,IACvD,cAAc,CAAC,WAA4B,YACzC,kBAAkB,WAAW,EAAE,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAAA,IAChE,yBAAyB,CAAC,MAAe,YACvC,6BAA6B,MAAM,EAAE,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAAA,EACxE;AACF;AAGO,IAAM,iBAAiB,qBAAqB;AAAA,EACjD,OAAO;AAAA,EACP,eAAe;AACjB,CAAC;AAEM,IAAM,uBAAuB,qBAAqB;AAAA,EACvD,OAAO;AAAA,EACP,eAAe;AAAA,EACf,WAAW;AACb,CAAC;AAKM,SAAS,aAAa,MAAmC;AAC9D,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,UAAU,MAAM;AAC/D,UAAM,QAAQ;AACd,QAAI,OAAO,MAAM,SAAS,UAAU;AAClC,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,cAAc,MAAwB;AACpD,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ;AACd,SAAO,CAAC,EAAE,MAAM,UAAU,MAAM;AAClC;;;AC3KA,SAAS,aAAa;AAEtB,SAAS,gCAAgC,0CAA0C;AAoBnF,IAAM,uBAAuB;AAAA,EAC3B,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AAAA,EACP,WAAW;AAAA,EACX,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AACV;AAOO,SAAS,kBACd,MACA,OACA,SACgC;AAChC,QAAM,SAAS,qBAAqB,IAAI;AAExC,MAAI,CAAC,QAAQ;AAEX,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS,aAAa;AAAA;AAAA,MACtB,eAAe;AAAA,MACf,mBAAmB;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,SAAS,sBAAsB,QAAQ,OAAO,OAAO;AAE3D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SAAS,OAAO;AAAA;AAAA,IAChB,eAAe;AAAA,IACf,mBAAmB,SAAS;AAAA,EAC9B;AACF;AAKO,SAAS,4BACd,WACA,SAC2B;AAC3B,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,kBAA6C;AAAA,IACjD,GAAG;AAAA,EACL;AAEA,MAAI,OAAO,SAAS,OAAO,MAAM;AAC/B,UAAM,OAAO,OAAO;AACpB,oBAAgB,gBAAgB,KAAK;AACrC,oBAAgB,oBAAoB,CAAC,wBAAwB,KAAK,IAAI;AAAA,EACxE;AAEA,SAAO;AACT;AAMO,SAAS,6BACd,iBACA,QACA,SAC8B;AAC9B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAKO,SAAS,mBACd,YACA,SAC6B;AAC7B,SAAO,WAAW,IAAI,CAAC,EAAE,MAAM,MAAM,MAAM;AACzC,QAAI,wBAAwB,IAAI,GAAG;AACjC,aAAO,kBAAkB,MAAM,OAAO,OAAO;AAAA,IAC/C;AACA,WAAO,kBAAkB,UAAU,OAAO,OAAO;AAAA,EACnD,CAAC;AACH;AAKO,SAAS,wBACd,MAC+B;AAC/B,SAAO,QAAQ;AACjB;AAEO,SAAS,cACd,QAC4C;AAC5C,SAAO,MAAM,MAAM,mBAAmB,MAAM;AAC9C;AAEO,SAAS,eACd,QAC6C;AAC7C,SAAO,MAAM,MAAM,oBAAoB,MAAM;AAC/C;AAEO,SAAS,eACd,QAC6C;AAC7C,SAAO,MAAM,MAAM,oBAAoB,MAAM;AAC/C;AAEO,SAAS,iBACd,QAC+C;AAC/C,SAAO,MAAM,MAAM,sBAAsB,MAAM;AACjD;AAEO,SAAS,eACd,QAC6C;AAC7C,SAAO,MAAM,MAAM,oBAAoB,MAAM;AAC/C;AAEO,SAAS,aACd,QAC2C;AAC3C,SAAO,MAAM,MAAM,kBAAkB,MAAM;AAC7C;AAEO,SAAS,iBACd,QAC+C;AAC/C,SAAO,MAAM,MAAM,sBAAsB,MAAM;AACjD;AAEO,SAAS,aACd,QAC2C;AAC3C,SAAO,MAAM,MAAM,kBAAkB,MAAM;AAC7C;AAEO,SAAS,cACd,QAC4C;AAC5C,SAAO,MAAM,MAAM,mBAAmB,MAAM;AAC9C;AAEO,SAAS,cACd,QAC4C;AAC5C,SAAO,MAAM,MAAM,mBAAmB,MAAM;AAC9C;AAEO,SAAS,YACd,QAC0C;AAC1C,SAAO,MAAM,MAAM,iBAAiB,MAAM;AAC5C;AAEO,SAAS,uBACd,QAC0D;AAC1D,SAAO,MAAM,MAAM,iCAAiC,MAAM;AAC5D;AAKO,SAAS,yBAAyB,gBAAoC;AAC3E,SAAO;AAAA,IACL,UAAU,CAAC,MAAc,OAAgB,YAAgC;AACvE,UAAI,wBAAwB,IAAI,GAAG;AACjC,eAAO,kBAAkB,MAAM,OAAO;AAAA,UACpC,GAAG;AAAA,UACH,GAAG;AAAA,QACL,CAAC;AAAA,MACH;AACA,aAAO,kBAAkB,UAAU,OAAO;AAAA,QACxC,GAAG;AAAA,QACH,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAAA,IACA,oBAAoB,CAAC,WAAoB,YACvC,4BAA4B,WAAW,EAAE,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAAA,IAC1E,gBAAgB,CACd,QACA,QACA,YAEA,6BAAgC,QAAQ,QAAQ;AAAA,MAC9C,GAAG;AAAA,MACH,GAAG;AAAA,IACL,CAAC;AAAA,EACL;AACF;AAGO,IAAM,qBAAqB,yBAAyB;AAAA,EACzD,OAAO;AAAA,EACP,eAAe;AACjB,CAAC;AAEM,IAAM,2BAA2B,yBAAyB;AAAA,EAC/D,OAAO;AAAA,EACP,eAAe;AAAA,EACf,WAAW;AACb,CAAC;;;AHpHM,IAAM,WAAW;AAAA;AAAA,EAEtB,UAAU,CAAC,SAAkB,kBAAkB,SAAS,IAAI;AAAA,EAC5D,cAAc,CAAC,cACb,kBAAkB,aAAa,SAAS;AAAA;AAAA,EAG1C,OAAO,CAAC,SAAkB,eAAe,SAAS,IAAI;AAAA,EACtD,WAAW,CAAC,cACV,eAAe,aAAa,SAAS;AAAA;AAAA,EAGvC,WAAW,CAAC,MAAc,UACxB,mBAAmB,SAAS,MAAM,KAAK;AAAA,EACzC,qBAAqB,CAAC,cACpB,mBAAmB,mBAAmB,SAAS;AAAA;AAAA,EAGjD,YAAY,CAAC,eACX,WAAW,IAAI,CAAC,MAAM,mBAAmB,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC;AAAA;AAAA,EAGpE,YAAY,CAAC,SAAkB;AAC7B,UAAM,SAAS,kBAAkB,SAAS,IAAI;AAC9C,WAAO,OAAO;AAAA,EAChB;AAAA,EACA,SAAS,CAAC,SAAkB;AAC1B,UAAM,SAAS,eAAe,SAAS,IAAI;AAC3C,WAAO,OAAO;AAAA,EAChB;AAAA,EACA,aAAa,CAAC,MAAc,UAAmB;AAC7C,UAAM,SAAS,mBAAmB,SAAS,MAAM,KAAK;AACtD,WAAO,OAAO;AAAA,EAChB;AACF;AAMO,IAAM,iBAAiB;AAAA,EAC5B,UAAU,CAAC,SAAkB,wBAAwB,SAAS,IAAI;AAAA,EAClE,cAAc,CAAC,cACb,wBAAwB,aAAa,SAAS;AAAA,EAChD,OAAO,CAAC,SAAkB,qBAAqB,SAAS,IAAI;AAAA,EAC5D,WAAW,CAAC,cACV,qBAAqB,aAAa,SAAS;AAAA,EAC7C,WAAW,CAAC,MAAc,UACxB,yBAAyB,SAAS,MAAM,KAAK;AAAA,EAC/C,qBAAqB,CAAC,cACpB,yBAAyB,mBAAmB,SAAS;AACzD;","names":["DEFAULT_ERROR_CONFIG"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ComponentDefinitionSchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CVI7GFWX.js";
|
|
4
4
|
|
|
5
5
|
// src/schemas/document.ts
|
|
6
6
|
var JsonComponentDefinitionSchema = ComponentDefinitionSchema;
|
|
@@ -31,4 +31,4 @@ export {
|
|
|
31
31
|
JsonComponentDefinitionSchema,
|
|
32
32
|
JSON_SCHEMA_URLS
|
|
33
33
|
};
|
|
34
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-S4EFGCIC.js.map
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
createComponentSchemaObject,
|
|
2
|
+
createAllComponentSchemasNarrowed,
|
|
4
3
|
getStandardComponent
|
|
5
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3D6HY6AC.js";
|
|
6
5
|
|
|
7
6
|
// src/schemas/generator.ts
|
|
8
7
|
import { Type } from "@sinclair/typebox";
|
|
@@ -14,14 +13,11 @@ function generateUnifiedDocumentSchema(options = {}) {
|
|
|
14
13
|
title = "JSON Report Definition",
|
|
15
14
|
description = "JSON report definition with TypeBox schemas"
|
|
16
15
|
} = options;
|
|
16
|
+
let capturedSectionSchema;
|
|
17
|
+
let capturedPluginSchemas = [];
|
|
17
18
|
const ComponentDefinition = Type.Recursive(
|
|
18
19
|
(This) => {
|
|
19
|
-
const
|
|
20
|
-
if (includeStandardComponents) {
|
|
21
|
-
for (const component of STANDARD_COMPONENTS_REGISTRY) {
|
|
22
|
-
componentSchemas.push(createComponentSchemaObject(component, This));
|
|
23
|
-
}
|
|
24
|
-
}
|
|
20
|
+
const pluginSchemas = [];
|
|
25
21
|
for (const customComponent of customComponents) {
|
|
26
22
|
if (customComponent.versionedProps && customComponent.versionedProps.length > 0) {
|
|
27
23
|
const versionEntries = customComponent.versionedProps;
|
|
@@ -40,7 +36,7 @@ function generateUnifiedDocumentSchema(options = {}) {
|
|
|
40
36
|
schema.children = Type.Optional(Type.Array(This));
|
|
41
37
|
}
|
|
42
38
|
const versionDesc = entry.description ? `${customComponent.name} v${entry.version} \u2014 ${entry.description}` : customComponent.description ? `${customComponent.name} v${entry.version} \u2014 ${customComponent.description}` : `${customComponent.name} v${entry.version}`;
|
|
43
|
-
|
|
39
|
+
pluginSchemas.push(
|
|
44
40
|
Type.Object(schema, {
|
|
45
41
|
additionalProperties: false,
|
|
46
42
|
description: versionDesc
|
|
@@ -57,7 +53,7 @@ function generateUnifiedDocumentSchema(options = {}) {
|
|
|
57
53
|
fallbackSchema.children = Type.Optional(Type.Array(This));
|
|
58
54
|
}
|
|
59
55
|
const fallbackDesc = latestEntry.description ? `${customComponent.name} (latest: v${latest}) \u2014 ${latestEntry.description}` : customComponent.description ? `${customComponent.name} (latest: v${latest}) \u2014 ${customComponent.description}` : `${customComponent.name} (latest: v${latest})`;
|
|
60
|
-
|
|
56
|
+
pluginSchemas.push(
|
|
61
57
|
Type.Object(fallbackSchema, {
|
|
62
58
|
additionalProperties: false,
|
|
63
59
|
description: fallbackDesc
|
|
@@ -73,7 +69,7 @@ function generateUnifiedDocumentSchema(options = {}) {
|
|
|
73
69
|
if (hasChildren) {
|
|
74
70
|
schema.children = Type.Optional(Type.Array(This));
|
|
75
71
|
}
|
|
76
|
-
|
|
72
|
+
pluginSchemas.push(
|
|
77
73
|
Type.Object(schema, {
|
|
78
74
|
additionalProperties: false,
|
|
79
75
|
...customComponent.description ? { description: customComponent.description } : {}
|
|
@@ -81,6 +77,10 @@ function generateUnifiedDocumentSchema(options = {}) {
|
|
|
81
77
|
);
|
|
82
78
|
}
|
|
83
79
|
}
|
|
80
|
+
const { schemas: standardSchemas, byName } = includeStandardComponents ? createAllComponentSchemasNarrowed(This, pluginSchemas) : { schemas: [], byName: /* @__PURE__ */ new Map() };
|
|
81
|
+
capturedSectionSchema = byName.get("section");
|
|
82
|
+
capturedPluginSchemas = pluginSchemas;
|
|
83
|
+
const componentSchemas = [...standardSchemas, ...pluginSchemas];
|
|
84
84
|
if (componentSchemas.length === 0) {
|
|
85
85
|
return Type.Any();
|
|
86
86
|
} else if (componentSchemas.length === 1) {
|
|
@@ -99,18 +99,28 @@ function generateUnifiedDocumentSchema(options = {}) {
|
|
|
99
99
|
if (!reportComponent) {
|
|
100
100
|
throw new Error("Docx root component not found in registry");
|
|
101
101
|
}
|
|
102
|
+
if (!capturedSectionSchema) {
|
|
103
|
+
throw new Error("Section schema not found in narrowed standard schemas");
|
|
104
|
+
}
|
|
102
105
|
return Type.Object(
|
|
103
106
|
{
|
|
104
107
|
name: Type.Literal("docx"),
|
|
105
108
|
id: Type.Optional(Type.String()),
|
|
106
109
|
$schema: Type.Optional(Type.String({ format: "uri" })),
|
|
107
110
|
props: reportComponent.propsSchema,
|
|
108
|
-
children: Type.Optional(
|
|
111
|
+
children: Type.Optional(
|
|
112
|
+
Type.Array(
|
|
113
|
+
capturedPluginSchemas.length > 0 ? Type.Union([capturedSectionSchema, ...capturedPluginSchemas]) : capturedSectionSchema
|
|
114
|
+
)
|
|
115
|
+
)
|
|
109
116
|
},
|
|
110
117
|
{
|
|
111
118
|
additionalProperties: false,
|
|
112
119
|
title,
|
|
113
|
-
description
|
|
120
|
+
description,
|
|
121
|
+
// Embed ComponentDefinition so convertToJsonSchema extracts it to
|
|
122
|
+
// definitions and bare $ref: "ComponentDefinition" values resolve.
|
|
123
|
+
definitions: { ComponentDefinition }
|
|
114
124
|
}
|
|
115
125
|
);
|
|
116
126
|
}
|
|
@@ -118,4 +128,4 @@ function generateUnifiedDocumentSchema(options = {}) {
|
|
|
118
128
|
export {
|
|
119
129
|
generateUnifiedDocumentSchema
|
|
120
130
|
};
|
|
121
|
-
//# sourceMappingURL=chunk-
|
|
131
|
+
//# sourceMappingURL=chunk-WJA5TGNI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/generator.ts"],"sourcesContent":["/**\n * Unified Document Schema Generator - SHARED UTILITY\n *\n * This is the SHARED implementation for generating document schemas.\n * It's used by MULTIPLE CONSUMERS with different requirements:\n *\n * 1. BUILD-TIME: generate-schemas.mjs uses this to create static .schema.json files\n * - Only standard components (no custom components available at build time)\n * - Outputs to filesystem for IDE autocomplete\n *\n * 2. RUNTIME PLUGIN: plugin/schema.ts uses this for plugin-enhanced schemas\n * - Includes custom components registered at runtime\n * - Cannot be generated at build time (components must be instantiated)\n *\n * 3. WEB APP: Monaco editor may use this for in-browser validation\n * - Optimized for browser environment\n * - No filesystem access\n *\n * This separation is ARCHITECTURAL, not accidental:\n * - Build-time vs runtime constraints are incompatible\n * - Custom components require runtime instantiation\n * - Different consumers need different output formats\n *\n * IMPORTANT: Standard components are defined in component-registry.ts (SINGLE SOURCE OF TRUTH).\n * This generator consumes that registry to ensure consistency across all schema generation.\n */\n\nimport { Type, TSchema } from '@sinclair/typebox';\nimport {\n createAllComponentSchemasNarrowed,\n getStandardComponent,\n} from './component-registry';\nimport { latestVersion } from '@json-to-office/shared';\n\n/**\n * Per-version props schema entry\n */\nexport interface VersionedPropsEntry {\n version: string;\n propsSchema: TSchema;\n hasChildren?: boolean;\n description?: string;\n}\n\n/**\n * Custom component interface for plugins\n */\nexport interface CustomComponentInfo {\n name: string;\n propsSchema: TSchema;\n /** When true, the component includes an optional `children` array */\n hasChildren?: boolean;\n /** Human-readable description shown in autocomplete */\n description?: string;\n /**\n * Per-version props schemas for version-discriminated validation.\n * When provided, separate schema variants are generated per version,\n * each pairing its version literal with its specific props schema.\n * A \"no version\" fallback variant uses the latest version's props.\n */\n versionedProps?: VersionedPropsEntry[];\n}\n\n/**\n * Options for generating document schema\n */\nexport interface GenerateDocumentSchemaOptions {\n includeStandardComponents?: boolean;\n includeTheme?: boolean;\n customComponents?: CustomComponentInfo[];\n title?: string;\n description?: string;\n}\n\n/**\n * Generate a complete document schema with all components\n *\n * This is the SHARED IMPLEMENTATION used by:\n * - Build-time schema generation (standard components only)\n * - Runtime plugin schema generation (with custom components)\n * - Web app schema generation (optimized for browser)\n *\n * @param options Configuration for what to include in the schema\n * @returns TypeBox schema that can be converted to JSON Schema\n */\nexport function generateUnifiedDocumentSchema(\n options: GenerateDocumentSchemaOptions = {}\n): TSchema {\n const {\n includeStandardComponents = true,\n customComponents = [],\n title = 'JSON Report Definition',\n description = 'JSON report definition with TypeBox schemas',\n } = options;\n\n // Captured from inside the recursive callback for the root's children.\n let capturedSectionSchema: TSchema | undefined;\n let capturedPluginSchemas: TSchema[] = [];\n\n // Create a recursive component definition schema\n const ComponentDefinition = Type.Recursive(\n (This) => {\n // ── Phase 1: Build plugin schemas (plugins get Self for arbitrary nesting) ──\n const pluginSchemas: TSchema[] = [];\n\n for (const customComponent of customComponents) {\n if (\n customComponent.versionedProps &&\n customComponent.versionedProps.length > 0\n ) {\n // Version-discriminated: one variant per version + one \"no version\" fallback\n const versionEntries = customComponent.versionedProps;\n const latest = latestVersion(versionEntries.map((e) => e.version));\n\n // Per-version variants: version is required, props are version-specific\n for (const entry of versionEntries) {\n const versionLiteralDesc =\n entry.description || customComponent.description;\n const schema: Record<string, TSchema> = {\n name: Type.Literal(customComponent.name),\n id: Type.Optional(Type.String()),\n version: versionLiteralDesc\n ? Type.Literal(entry.version, {\n description: versionLiteralDesc,\n })\n : Type.Literal(entry.version),\n props: entry.propsSchema,\n };\n if (entry.hasChildren) {\n schema.children = Type.Optional(Type.Array(This));\n }\n const versionDesc = entry.description\n ? `${customComponent.name} v${entry.version} — ${entry.description}`\n : customComponent.description\n ? `${customComponent.name} v${entry.version} — ${customComponent.description}`\n : `${customComponent.name} v${entry.version}`;\n pluginSchemas.push(\n Type.Object(schema, {\n additionalProperties: false,\n description: versionDesc,\n })\n );\n }\n\n // \"No version\" fallback: version is NOT allowed, uses latest props\n const latestEntry = versionEntries.find((e) => e.version === latest)!;\n const fallbackSchema: Record<string, TSchema> = {\n name: Type.Literal(customComponent.name),\n id: Type.Optional(Type.String()),\n props: latestEntry.propsSchema,\n };\n if (latestEntry.hasChildren) {\n fallbackSchema.children = Type.Optional(Type.Array(This));\n }\n const fallbackDesc = latestEntry.description\n ? `${customComponent.name} (latest: v${latest}) — ${latestEntry.description}`\n : customComponent.description\n ? `${customComponent.name} (latest: v${latest}) — ${customComponent.description}`\n : `${customComponent.name} (latest: v${latest})`;\n pluginSchemas.push(\n Type.Object(fallbackSchema, {\n additionalProperties: false,\n description: fallbackDesc,\n })\n );\n } else {\n // Non-versioned component: single variant\n const hasChildren = !!customComponent.hasChildren;\n const schema: Record<string, TSchema> = {\n name: Type.Literal(customComponent.name),\n id: Type.Optional(Type.String()),\n props: customComponent.propsSchema,\n };\n if (hasChildren) {\n schema.children = Type.Optional(Type.Array(This));\n }\n pluginSchemas.push(\n Type.Object(schema, {\n additionalProperties: false,\n ...(customComponent.description\n ? { description: customComponent.description }\n : {}),\n })\n );\n }\n }\n\n // ── Phase 2: Build standard components with narrowed children ──\n const { schemas: standardSchemas, byName } = includeStandardComponents\n ? createAllComponentSchemasNarrowed(This, pluginSchemas)\n : { schemas: [] as TSchema[], byName: new Map<string, TSchema>() };\n\n // Capture the narrowed section schema + plugins for the root's children.\n // Must happen inside the callback while standardSchemas is available.\n capturedSectionSchema = byName.get('section');\n capturedPluginSchemas = pluginSchemas;\n\n const componentSchemas = [...standardSchemas, ...pluginSchemas];\n\n // Create the union based on the number of schemas\n if (componentSchemas.length === 0) {\n return Type.Any();\n } else if (componentSchemas.length === 1) {\n return componentSchemas[0];\n } else {\n const componentDescription =\n customComponents.length > 0\n ? 'Component definition with discriminated union including custom components'\n : 'Component definition with discriminated union';\n\n return Type.Union(componentSchemas, {\n discriminator: { propertyName: 'name' },\n description: componentDescription,\n });\n }\n },\n { $id: 'ComponentDefinition' }\n );\n\n // Build root docx schema with narrowed children (section only).\n // ComponentDefinition is embedded in `definitions` so that $refs inside\n // section header/footer and table cell content resolve correctly.\n const reportComponent = getStandardComponent('docx');\n if (!reportComponent) {\n throw new Error('Docx root component not found in registry');\n }\n\n if (!capturedSectionSchema) {\n throw new Error('Section schema not found in narrowed standard schemas');\n }\n\n return Type.Object(\n {\n name: Type.Literal('docx'),\n id: Type.Optional(Type.String()),\n $schema: Type.Optional(Type.String({ format: 'uri' })),\n props: reportComponent.propsSchema,\n children: Type.Optional(\n Type.Array(\n capturedPluginSchemas.length > 0\n ? Type.Union([capturedSectionSchema, ...capturedPluginSchemas])\n : capturedSectionSchema\n )\n ),\n },\n {\n additionalProperties: false,\n title,\n description,\n // Embed ComponentDefinition so convertToJsonSchema extracts it to\n // definitions and bare $ref: \"ComponentDefinition\" values resolve.\n definitions: { ComponentDefinition },\n } as Record<string, unknown>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ComponentDefinitionSchema,
|
|
3
3
|
StandardComponentDefinitionSchema
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CVI7GFWX.js";
|
|
5
|
+
import {
|
|
6
|
+
CustomComponentDefinitionSchema
|
|
7
|
+
} from "./chunk-VP3X6DBP.js";
|
|
5
8
|
import {
|
|
6
9
|
ColumnsPropsSchema,
|
|
7
10
|
FooterPropsSchema,
|
|
@@ -14,10 +17,7 @@ import {
|
|
|
14
17
|
SectionPropsSchema,
|
|
15
18
|
StatisticPropsSchema,
|
|
16
19
|
TablePropsSchema
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import {
|
|
19
|
-
CustomComponentDefinitionSchema
|
|
20
|
-
} from "./chunk-VP3X6DBP.js";
|
|
20
|
+
} from "./chunk-3D6HY6AC.js";
|
|
21
21
|
|
|
22
22
|
// src/validation/unified/error-transformer.ts
|
|
23
23
|
import {
|
|
@@ -747,4 +747,4 @@ export {
|
|
|
747
747
|
validateJsonComponent,
|
|
748
748
|
validateDocumentWithSchema
|
|
749
749
|
};
|
|
750
|
-
//# sourceMappingURL=chunk-
|
|
750
|
+
//# sourceMappingURL=chunk-YNBTESFN.js.map
|