@duongthiu/onex-core 0.1.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/README.md +428 -0
- package/THEME_API.md +681 -0
- package/dist/api-vuL1Eg5L.d.mts +2961 -0
- package/dist/api-vuL1Eg5L.d.ts +2961 -0
- package/dist/chunk-3SZX6LHT.js +244 -0
- package/dist/chunk-3SZX6LHT.js.map +1 -0
- package/dist/chunk-7EON6Q4L.mjs +8149 -0
- package/dist/chunk-7EON6Q4L.mjs.map +1 -0
- package/dist/chunk-WDY773GJ.js +8308 -0
- package/dist/chunk-WDY773GJ.js.map +1 -0
- package/dist/chunk-XE4EOKS4.mjs +239 -0
- package/dist/chunk-XE4EOKS4.mjs.map +1 -0
- package/dist/client.d.mts +1461 -0
- package/dist/client.d.ts +1461 -0
- package/dist/client.js +542 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +5 -0
- package/dist/client.mjs.map +1 -0
- package/dist/index.d.mts +125 -0
- package/dist/index.d.ts +125 -0
- package/dist/index.js +601 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +61 -0
- package/dist/index.mjs.map +1 -0
- package/dist/server.d.mts +70 -0
- package/dist/server.d.ts +70 -0
- package/dist/server.js +196 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +188 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +113 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/theme-manifest.schema.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Zod schemas for ThemeManifest validation\n * Used for runtime validation of uploaded theme bundles\n */\n\nimport { z } from \"zod\";\n\n/**\n * Author information schema\n */\nexport const authorSchema = z.object({\n name: z.string().min(1, \"Author name is required\"),\n email: z.string().email({ message: \"Invalid email address\" }).optional(),\n url: z.string().url({ message: \"Invalid URL\" }).optional(),\n});\n\n/**\n * Peer dependencies schema\n */\nexport const peerDependenciesSchema = z.object({\n react: z.string().min(1, \"React version is required\"),\n \"react-dom\": z.string().min(1, \"React DOM version is required\"),\n \"@onex/core\": z.string().optional(),\n});\n\n/**\n * Theme preview schema\n */\nexport const previewSchema = z.object({\n thumbnail: z.string().url({ message: \"Thumbnail must be a valid URL\" }).optional(),\n screenshots: z.array(z.string().url({ message: \"Screenshot URL is invalid\" })).optional(),\n});\n\n/**\n * Export paths schema\n */\nexport const exportsSchema = z.object({\n main: z.string().min(1, \"Main export path is required\"),\n types: z.string().optional(),\n});\n\n/**\n * Theme manifest schema\n * Validates the manifest.json file in theme bundles\n */\nexport const themeManifestSchema = z.object({\n // Required fields\n id: z\n .string()\n .min(3, \"Theme ID must be at least 3 characters\")\n .max(50, \"Theme ID must be at most 50 characters\")\n .regex(\n /^[a-z0-9-]+$/,\n \"Theme ID must be lowercase letters, numbers, and hyphens only\"\n ),\n\n name: z\n .string()\n .min(1, \"Theme name is required\")\n .max(100, \"Theme name must be at most 100 characters\"),\n\n version: z\n .string()\n .regex(\n /^\\d+\\.\\d+\\.\\d+(-[a-z0-9.]+)?$/,\n \"Version must follow semver format (e.g., 1.0.0)\"\n ),\n\n author: authorSchema,\n\n engine: z\n .string()\n .min(1, \"Engine version is required\")\n .regex(\n /^[\\^~>=<]*\\d+\\.\\d+\\.\\d+/,\n \"Engine must be a valid semver range (e.g., ^1.0.0)\"\n ),\n\n peerDependencies: peerDependenciesSchema,\n\n sections: z\n .array(z.string().min(1))\n .min(1, \"At least one section is required\"),\n\n config: z.record(z.string(), z.any()), // ThemeConfig validation done separately\n\n exports: exportsSchema,\n\n // Optional fields\n description: z.string().max(500).optional(),\n\n preview: previewSchema.optional(),\n\n license: z.string().optional(),\n\n repository: z.string().url({ message: \"Repository must be a valid URL\" }).optional(),\n\n tags: z.array(z.string()).optional(),\n});\n\n/**\n * Type inference from schema\n */\nexport type ThemeManifestValidation = z.infer<typeof themeManifestSchema>;\n\n/**\n * Validate theme manifest\n *\n * @param manifest - The manifest object to validate\n * @returns Validation result with typed data or errors\n */\nexport function validateThemeManifest(manifest: unknown) {\n return themeManifestSchema.safeParse(manifest);\n}\n\n/**\n * Validate theme manifest and throw on error\n *\n * @param manifest - The manifest object to validate\n * @throws ZodError if validation fails\n */\nexport function assertValidThemeManifest(manifest: unknown): asserts manifest is ThemeManifestValidation {\n themeManifestSchema.parse(manifest);\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { aA as SectionRegistry, H as SectionComponentProps, z as SectionSchema } from './api-vuL1Eg5L.mjs';
|
|
2
|
+
export { bb as ActiveHotlineConnections, ba as ActiveSocialConnections, bc as ActiveTrackingAnalytics, a as AnimationEasing, c as AnimationSettings, b as AnimationTrigger, A as AnimationType, bJ as ApiListResponse, bN as ApiPriceGroup, bO as ApiProductRaw, bG as ApiResponse, $ as ApplyScope, a0 as ApplyScopeResult, o as ArticleFieldDefinition, B as BaseEntity, f as BaseFieldDefinition, x as BlockComponentProps, u as BlockDefinition, v as BlockInstance, ax as BlockRegisteredPayload, w as BlockRegistration, aB as BlockRegistry, ay as BlockUnregisteredPayload, by as Blog, bs as BlogCategory, bv as BlogCategoryData, bA as BlogDetailData, n as BlogFieldDefinition, bz as BlogFilters, bQ as BlogFiltersParams, bt as BlogImage, bB as BlogListData, bC as BlogListItem, bw as BlogMetaData, bu as BlogUser, h as BooleanFieldDefinition, ag as BorderRadius, Z as Breakpoint, ah as Breakpoints, a1 as COMPONENT_CATEGORIES, a2 as COMPONENT_TYPES, bF as CartContextType, bD as CartItem, bE as CartSummary, i as CheckboxFieldDefinition, m as CollectionFieldDefinition, C as ColorFieldDefinition, ad as ColorPalette, b7 as CompanyInfo, M as ComponentCategory, O as ComponentDefinition, Q as ComponentInstance, ab as ComponentPageDefinition, X as ComponentProps, W as ComponentRegistration, L as ComponentType, b6 as ContactEmail, a_ as DEFAULT_INSPECTOR_CONFIG, ac as DesignToken, aE as DetectedElement, aC as DetectedSection, aU as DetectionPriority, aW as DetectionResult, aV as DetectionStrategy, aQ as DragDropContext, aF as EditableElementRegistry, aM as EditorActions, aN as EditorContextValue, aI as EditorMode, aL as EditorState, aT as ElementMetadata, aD as ElementRegistry, aS as ElementType, b9 as EnabledItems, t as FIELD_TYPES, q as FieldDefinition, F as FieldType, l as FontFieldDefinition, aP as HistoryEntry, b3 as HotlineConnection, b2 as HotlineType, I as ImageFieldDefinition, aY as InlineEditorProps, aX as InlineEditorState, aZ as InspectorConfig, aO as InspectorOverlayState, aR as KeyboardShortcut, bK as ListQueryParams, bL as Location, bM as LocationListResponse, N as NumberFieldDefinition, a5 as PageConfig, p as PageFieldDefinition, a7 as PageListItem, a8 as PageNavItem, aG as PageRegistration, a9 as PageRenderMode, a4 as PageSEO, a6 as PageTemplate, aH as PageTemplateRegistration, a3 as PageType, bH as PaginatedResponse, bf as PriceRange, bo as Product, br as ProductCardProps, bd as ProductCategory, P as ProductFieldDefinition, bp as ProductFilters, bP as ProductFiltersParams, bq as ProductListItem, bk as ProductMeasurements, bm as ProductOption, bj as ProductPrice, bi as ProductPriceGroup, bh as ProductSize, bl as ProductSpecs, be as ProductTag, bn as ProductVariant, j as RadioFieldDefinition, R as RangeFieldDefinition, ar as RegistryConfig, at as RegistryEvent, az as RegistryEventHandler, as as RegistryEventType, bx as ResponseMetaData, _ as ResponsiveStyles, k as RichTextFieldDefinition, K as SECTION_CATEGORIES, J as SectionCategory, E as SectionComponentInstance, D as SectionInstance, au as SectionRegisteredPayload, G as SectionRegistration, av as SectionUnregisteredPayload, S as SelectFieldDefinition, aK as SelectedElement, aJ as SelectedElementType, bI as ServerFetcherResponse, r as SettingValue, s as Settings, a$ as SettingsIcon, b1 as SocialConnection, b0 as SocialPlatform, bg as SortOption, af as Spacing, Y as StyleSettings, y as TemplateDefinition, aw as TemplateRegisteredPayload, T as TextFieldDefinition, g as TextareaFieldDefinition, ai as ThemeConfig, ak as ThemeExport, aa as ThemeLayoutConfig, al as ThemeManifest, am as ThemeModule, aj as ThemePreset, an as ThemeUpload, ap as ThemeValidationError, ao as ThemeValidationResult, aq as ThemeValidationWarning, b5 as TrackingAnalytics, b4 as TrackingPlatform, ae as Typography, U as UrlFieldDefinition, V as VideoFieldDefinition, b8 as WebsiteSettings, d as animationFieldDefinitions, e as defaultAnimationSettings } from './api-vuL1Eg5L.mjs';
|
|
3
|
+
import 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Theme Registry Manager
|
|
7
|
+
* Manages theme-specific section registries with auto-discovery
|
|
8
|
+
*
|
|
9
|
+
* SERVER-ONLY: Uses filesystem operations, cannot run in browser
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Theme Registry Manager
|
|
14
|
+
* Auto-discovers and manages theme-specific section registries
|
|
15
|
+
*/
|
|
16
|
+
declare class ThemeRegistryManager {
|
|
17
|
+
private registries;
|
|
18
|
+
private initialized;
|
|
19
|
+
private debug;
|
|
20
|
+
constructor(debug?: boolean);
|
|
21
|
+
/**
|
|
22
|
+
* Auto-discover sections from theme directory
|
|
23
|
+
* Reads filesystem to find all section directories
|
|
24
|
+
*/
|
|
25
|
+
discoverThemeSections(themeId: string): Promise<string[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Initialize a theme's sections
|
|
28
|
+
* Auto-discovers and registers all sections for a theme
|
|
29
|
+
*/
|
|
30
|
+
initializeTheme(themeId: string): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Get or create theme-specific registry
|
|
33
|
+
*/
|
|
34
|
+
getThemeRegistry(themeId: string): SectionRegistry;
|
|
35
|
+
/**
|
|
36
|
+
* Check if theme has been initialized
|
|
37
|
+
*/
|
|
38
|
+
isThemeInitialized(themeId: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a section component for a specific theme
|
|
41
|
+
* Returns null if not found (no fallback - strict validation)
|
|
42
|
+
*/
|
|
43
|
+
resolveSection(themeId: string, sectionType: string, templateId?: string): React.ComponentType<SectionComponentProps> | null;
|
|
44
|
+
/**
|
|
45
|
+
* Get section schema for a specific theme
|
|
46
|
+
*/
|
|
47
|
+
getSectionSchema(themeId: string, sectionType: string): SectionSchema | null;
|
|
48
|
+
/**
|
|
49
|
+
* Get all available themes
|
|
50
|
+
*/
|
|
51
|
+
getAvailableThemes(): string[];
|
|
52
|
+
/**
|
|
53
|
+
* Get all section types for a theme
|
|
54
|
+
*/
|
|
55
|
+
getThemeSections(themeId: string): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Clear a specific theme's registry
|
|
58
|
+
*/
|
|
59
|
+
clearTheme(themeId: string): void;
|
|
60
|
+
/**
|
|
61
|
+
* Clear all theme registries
|
|
62
|
+
*/
|
|
63
|
+
clearAll(): void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Global theme registry manager instance
|
|
67
|
+
*/
|
|
68
|
+
declare const themeRegistryManager: ThemeRegistryManager;
|
|
69
|
+
|
|
70
|
+
export { SectionComponentProps, SectionRegistry, SectionSchema, ThemeRegistryManager, themeRegistryManager };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { aA as SectionRegistry, H as SectionComponentProps, z as SectionSchema } from './api-vuL1Eg5L.js';
|
|
2
|
+
export { bb as ActiveHotlineConnections, ba as ActiveSocialConnections, bc as ActiveTrackingAnalytics, a as AnimationEasing, c as AnimationSettings, b as AnimationTrigger, A as AnimationType, bJ as ApiListResponse, bN as ApiPriceGroup, bO as ApiProductRaw, bG as ApiResponse, $ as ApplyScope, a0 as ApplyScopeResult, o as ArticleFieldDefinition, B as BaseEntity, f as BaseFieldDefinition, x as BlockComponentProps, u as BlockDefinition, v as BlockInstance, ax as BlockRegisteredPayload, w as BlockRegistration, aB as BlockRegistry, ay as BlockUnregisteredPayload, by as Blog, bs as BlogCategory, bv as BlogCategoryData, bA as BlogDetailData, n as BlogFieldDefinition, bz as BlogFilters, bQ as BlogFiltersParams, bt as BlogImage, bB as BlogListData, bC as BlogListItem, bw as BlogMetaData, bu as BlogUser, h as BooleanFieldDefinition, ag as BorderRadius, Z as Breakpoint, ah as Breakpoints, a1 as COMPONENT_CATEGORIES, a2 as COMPONENT_TYPES, bF as CartContextType, bD as CartItem, bE as CartSummary, i as CheckboxFieldDefinition, m as CollectionFieldDefinition, C as ColorFieldDefinition, ad as ColorPalette, b7 as CompanyInfo, M as ComponentCategory, O as ComponentDefinition, Q as ComponentInstance, ab as ComponentPageDefinition, X as ComponentProps, W as ComponentRegistration, L as ComponentType, b6 as ContactEmail, a_ as DEFAULT_INSPECTOR_CONFIG, ac as DesignToken, aE as DetectedElement, aC as DetectedSection, aU as DetectionPriority, aW as DetectionResult, aV as DetectionStrategy, aQ as DragDropContext, aF as EditableElementRegistry, aM as EditorActions, aN as EditorContextValue, aI as EditorMode, aL as EditorState, aT as ElementMetadata, aD as ElementRegistry, aS as ElementType, b9 as EnabledItems, t as FIELD_TYPES, q as FieldDefinition, F as FieldType, l as FontFieldDefinition, aP as HistoryEntry, b3 as HotlineConnection, b2 as HotlineType, I as ImageFieldDefinition, aY as InlineEditorProps, aX as InlineEditorState, aZ as InspectorConfig, aO as InspectorOverlayState, aR as KeyboardShortcut, bK as ListQueryParams, bL as Location, bM as LocationListResponse, N as NumberFieldDefinition, a5 as PageConfig, p as PageFieldDefinition, a7 as PageListItem, a8 as PageNavItem, aG as PageRegistration, a9 as PageRenderMode, a4 as PageSEO, a6 as PageTemplate, aH as PageTemplateRegistration, a3 as PageType, bH as PaginatedResponse, bf as PriceRange, bo as Product, br as ProductCardProps, bd as ProductCategory, P as ProductFieldDefinition, bp as ProductFilters, bP as ProductFiltersParams, bq as ProductListItem, bk as ProductMeasurements, bm as ProductOption, bj as ProductPrice, bi as ProductPriceGroup, bh as ProductSize, bl as ProductSpecs, be as ProductTag, bn as ProductVariant, j as RadioFieldDefinition, R as RangeFieldDefinition, ar as RegistryConfig, at as RegistryEvent, az as RegistryEventHandler, as as RegistryEventType, bx as ResponseMetaData, _ as ResponsiveStyles, k as RichTextFieldDefinition, K as SECTION_CATEGORIES, J as SectionCategory, E as SectionComponentInstance, D as SectionInstance, au as SectionRegisteredPayload, G as SectionRegistration, av as SectionUnregisteredPayload, S as SelectFieldDefinition, aK as SelectedElement, aJ as SelectedElementType, bI as ServerFetcherResponse, r as SettingValue, s as Settings, a$ as SettingsIcon, b1 as SocialConnection, b0 as SocialPlatform, bg as SortOption, af as Spacing, Y as StyleSettings, y as TemplateDefinition, aw as TemplateRegisteredPayload, T as TextFieldDefinition, g as TextareaFieldDefinition, ai as ThemeConfig, ak as ThemeExport, aa as ThemeLayoutConfig, al as ThemeManifest, am as ThemeModule, aj as ThemePreset, an as ThemeUpload, ap as ThemeValidationError, ao as ThemeValidationResult, aq as ThemeValidationWarning, b5 as TrackingAnalytics, b4 as TrackingPlatform, ae as Typography, U as UrlFieldDefinition, V as VideoFieldDefinition, b8 as WebsiteSettings, d as animationFieldDefinitions, e as defaultAnimationSettings } from './api-vuL1Eg5L.js';
|
|
3
|
+
import 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Theme Registry Manager
|
|
7
|
+
* Manages theme-specific section registries with auto-discovery
|
|
8
|
+
*
|
|
9
|
+
* SERVER-ONLY: Uses filesystem operations, cannot run in browser
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Theme Registry Manager
|
|
14
|
+
* Auto-discovers and manages theme-specific section registries
|
|
15
|
+
*/
|
|
16
|
+
declare class ThemeRegistryManager {
|
|
17
|
+
private registries;
|
|
18
|
+
private initialized;
|
|
19
|
+
private debug;
|
|
20
|
+
constructor(debug?: boolean);
|
|
21
|
+
/**
|
|
22
|
+
* Auto-discover sections from theme directory
|
|
23
|
+
* Reads filesystem to find all section directories
|
|
24
|
+
*/
|
|
25
|
+
discoverThemeSections(themeId: string): Promise<string[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Initialize a theme's sections
|
|
28
|
+
* Auto-discovers and registers all sections for a theme
|
|
29
|
+
*/
|
|
30
|
+
initializeTheme(themeId: string): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Get or create theme-specific registry
|
|
33
|
+
*/
|
|
34
|
+
getThemeRegistry(themeId: string): SectionRegistry;
|
|
35
|
+
/**
|
|
36
|
+
* Check if theme has been initialized
|
|
37
|
+
*/
|
|
38
|
+
isThemeInitialized(themeId: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a section component for a specific theme
|
|
41
|
+
* Returns null if not found (no fallback - strict validation)
|
|
42
|
+
*/
|
|
43
|
+
resolveSection(themeId: string, sectionType: string, templateId?: string): React.ComponentType<SectionComponentProps> | null;
|
|
44
|
+
/**
|
|
45
|
+
* Get section schema for a specific theme
|
|
46
|
+
*/
|
|
47
|
+
getSectionSchema(themeId: string, sectionType: string): SectionSchema | null;
|
|
48
|
+
/**
|
|
49
|
+
* Get all available themes
|
|
50
|
+
*/
|
|
51
|
+
getAvailableThemes(): string[];
|
|
52
|
+
/**
|
|
53
|
+
* Get all section types for a theme
|
|
54
|
+
*/
|
|
55
|
+
getThemeSections(themeId: string): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Clear a specific theme's registry
|
|
58
|
+
*/
|
|
59
|
+
clearTheme(themeId: string): void;
|
|
60
|
+
/**
|
|
61
|
+
* Clear all theme registries
|
|
62
|
+
*/
|
|
63
|
+
clearAll(): void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Global theme registry manager instance
|
|
67
|
+
*/
|
|
68
|
+
declare const themeRegistryManager: ThemeRegistryManager;
|
|
69
|
+
|
|
70
|
+
export { SectionComponentProps, SectionRegistry, SectionSchema, ThemeRegistryManager, themeRegistryManager };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk3SZX6LHT_js = require('./chunk-3SZX6LHT.js');
|
|
4
|
+
require('server-only');
|
|
5
|
+
var fs = require('fs/promises');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
11
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
12
|
+
|
|
13
|
+
function toCamelCase(str) {
|
|
14
|
+
return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
15
|
+
}
|
|
16
|
+
var ThemeRegistryManager = class {
|
|
17
|
+
constructor(debug = process.env.NODE_ENV === "development") {
|
|
18
|
+
this.registries = /* @__PURE__ */ new Map();
|
|
19
|
+
this.initialized = /* @__PURE__ */ new Set();
|
|
20
|
+
this.debug = debug;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Auto-discover sections from theme directory
|
|
24
|
+
* Reads filesystem to find all section directories
|
|
25
|
+
*/
|
|
26
|
+
async discoverThemeSections(themeId) {
|
|
27
|
+
const sectionsPath = path__default.default.join(
|
|
28
|
+
process.cwd(),
|
|
29
|
+
`src/themes/${themeId}/sections`
|
|
30
|
+
);
|
|
31
|
+
try {
|
|
32
|
+
const entries = await fs__default.default.readdir(sectionsPath, { withFileTypes: true });
|
|
33
|
+
const sectionNames = entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
34
|
+
if (this.debug) {
|
|
35
|
+
}
|
|
36
|
+
return sectionNames;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (this.debug) {
|
|
39
|
+
console.warn(
|
|
40
|
+
`[ThemeRegistry] No sections found for theme "${themeId}" at ${sectionsPath}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Initialize a theme's sections
|
|
48
|
+
* Auto-discovers and registers all sections for a theme
|
|
49
|
+
*/
|
|
50
|
+
async initializeTheme(themeId) {
|
|
51
|
+
var _a, _b;
|
|
52
|
+
if (this.initialized.has(themeId)) {
|
|
53
|
+
if (this.debug) ;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const registry = this.getThemeRegistry(themeId);
|
|
57
|
+
const sectionNames = await this.discoverThemeSections(themeId);
|
|
58
|
+
if (sectionNames.length === 0) {
|
|
59
|
+
console.warn(`[ThemeRegistry] No sections found for theme "${themeId}"`);
|
|
60
|
+
this.initialized.add(themeId);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
let successCount = 0;
|
|
64
|
+
let failureCount = 0;
|
|
65
|
+
for (const sectionName of sectionNames) {
|
|
66
|
+
try {
|
|
67
|
+
const sectionModule = await import(`@/themes/${themeId}/sections/${sectionName}`);
|
|
68
|
+
const camelName = toCamelCase(sectionName);
|
|
69
|
+
const schema = sectionModule[`${camelName}Schema`] || ((_a = sectionModule.default) == null ? void 0 : _a.schema) || sectionModule.schema;
|
|
70
|
+
const components = sectionModule[`${camelName}Components`] || ((_b = sectionModule.default) == null ? void 0 : _b.components) || sectionModule.components;
|
|
71
|
+
if (!schema || !components) {
|
|
72
|
+
console.error(
|
|
73
|
+
`[ThemeRegistry] Section "${sectionName}" in theme "${themeId}" missing schema or components export.`,
|
|
74
|
+
`Expected: "${camelName}Schema" and "${camelName}Components"`
|
|
75
|
+
);
|
|
76
|
+
failureCount++;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const defaultComponent = components.default || Object.values(components)[0];
|
|
80
|
+
if (!defaultComponent) {
|
|
81
|
+
console.error(
|
|
82
|
+
`[ThemeRegistry] Section "${sectionName}" has no default component`
|
|
83
|
+
);
|
|
84
|
+
failureCount++;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const templates = Object.entries(components).map(
|
|
88
|
+
([templateId, component]) => ({
|
|
89
|
+
definition: schema.templates.find((t) => t.id === templateId) || {
|
|
90
|
+
id: templateId,
|
|
91
|
+
name: templateId,
|
|
92
|
+
description: `${templateId} template`,
|
|
93
|
+
isDefault: templateId === "default",
|
|
94
|
+
settings: schema.settings,
|
|
95
|
+
defaults: schema.defaults
|
|
96
|
+
},
|
|
97
|
+
component
|
|
98
|
+
})
|
|
99
|
+
);
|
|
100
|
+
registry.register(schema.type, schema, defaultComponent, {
|
|
101
|
+
templates,
|
|
102
|
+
category: schema.category,
|
|
103
|
+
tags: schema.tags
|
|
104
|
+
});
|
|
105
|
+
successCount++;
|
|
106
|
+
if (this.debug) {
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error(
|
|
110
|
+
`[ThemeRegistry] Failed to load section "${themeId}/${sectionName}":`,
|
|
111
|
+
error
|
|
112
|
+
);
|
|
113
|
+
failureCount++;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
this.initialized.add(themeId);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get or create theme-specific registry
|
|
120
|
+
*/
|
|
121
|
+
getThemeRegistry(themeId) {
|
|
122
|
+
if (!this.registries.has(themeId)) {
|
|
123
|
+
const registry = chunk3SZX6LHT_js.createSectionRegistry({
|
|
124
|
+
debug: this.debug,
|
|
125
|
+
allowOverride: this.debug
|
|
126
|
+
});
|
|
127
|
+
this.registries.set(themeId, registry);
|
|
128
|
+
if (this.debug) ;
|
|
129
|
+
}
|
|
130
|
+
return this.registries.get(themeId);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if theme has been initialized
|
|
134
|
+
*/
|
|
135
|
+
isThemeInitialized(themeId) {
|
|
136
|
+
return this.initialized.has(themeId);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Resolve a section component for a specific theme
|
|
140
|
+
* Returns null if not found (no fallback - strict validation)
|
|
141
|
+
*/
|
|
142
|
+
resolveSection(themeId, sectionType, templateId = "default") {
|
|
143
|
+
const registry = this.getThemeRegistry(themeId);
|
|
144
|
+
return registry.getTemplateComponent(sectionType, templateId) || null;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get section schema for a specific theme
|
|
148
|
+
*/
|
|
149
|
+
getSectionSchema(themeId, sectionType) {
|
|
150
|
+
const registry = this.getThemeRegistry(themeId);
|
|
151
|
+
return registry.getSchema(sectionType) || null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Get all available themes
|
|
155
|
+
*/
|
|
156
|
+
getAvailableThemes() {
|
|
157
|
+
return Array.from(this.registries.keys());
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get all section types for a theme
|
|
161
|
+
*/
|
|
162
|
+
getThemeSections(themeId) {
|
|
163
|
+
const registry = this.registries.get(themeId);
|
|
164
|
+
if (!registry) {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
const all = registry.getAll();
|
|
168
|
+
return Array.from(all.keys());
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Clear a specific theme's registry
|
|
172
|
+
*/
|
|
173
|
+
clearTheme(themeId) {
|
|
174
|
+
const registry = this.registries.get(themeId);
|
|
175
|
+
if (registry) {
|
|
176
|
+
registry.clear();
|
|
177
|
+
this.initialized.delete(themeId);
|
|
178
|
+
if (this.debug) ;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Clear all theme registries
|
|
183
|
+
*/
|
|
184
|
+
clearAll() {
|
|
185
|
+
this.registries.forEach((registry) => registry.clear());
|
|
186
|
+
this.registries.clear();
|
|
187
|
+
this.initialized.clear();
|
|
188
|
+
if (this.debug) ;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
var themeRegistryManager = new ThemeRegistryManager();
|
|
192
|
+
|
|
193
|
+
exports.ThemeRegistryManager = ThemeRegistryManager;
|
|
194
|
+
exports.themeRegistryManager = themeRegistryManager;
|
|
195
|
+
//# sourceMappingURL=server.js.map
|
|
196
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/registry/theme-registry-manager.ts"],"names":["path","fs","createSectionRegistry"],"mappings":"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","file":"server.js","sourcesContent":["/**\n * Theme Registry Manager\n * Manages theme-specific section registries with auto-discovery\n *\n * SERVER-ONLY: Uses filesystem operations, cannot run in browser\n */\n\nimport \"server-only\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport type { SectionRegistry } from \"../types/registry\";\nimport type { SectionSchema, SectionComponentProps } from \"../types/section\";\nimport { createSectionRegistry } from \"./section-registry\";\n\n/**\n * Convert kebab-case to camelCase\n */\nfunction toCamelCase(str: string): string {\n return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n}\n\n/**\n * Theme Registry Manager\n * Auto-discovers and manages theme-specific section registries\n */\nexport class ThemeRegistryManager {\n private registries: Map<string, SectionRegistry>;\n private initialized: Set<string>;\n private debug: boolean;\n\n constructor(debug: boolean = process.env.NODE_ENV === \"development\") {\n this.registries = new Map();\n this.initialized = new Set();\n this.debug = debug;\n }\n\n /**\n * Auto-discover sections from theme directory\n * Reads filesystem to find all section directories\n */\n async discoverThemeSections(themeId: string): Promise<string[]> {\n const sectionsPath = path.join(\n process.cwd(),\n `src/themes/${themeId}/sections`\n );\n\n try {\n const entries = await fs.readdir(sectionsPath, { withFileTypes: true });\n\n // Return only directories (each directory = one section)\n const sectionNames = entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n\n if (this.debug) {\n }\n\n return sectionNames;\n } catch (error) {\n if (this.debug) {\n console.warn(\n `[ThemeRegistry] No sections found for theme \"${themeId}\" at ${sectionsPath}`\n );\n }\n return [];\n }\n }\n\n /**\n * Initialize a theme's sections\n * Auto-discovers and registers all sections for a theme\n */\n async initializeTheme(themeId: string): Promise<void> {\n // Check if already initialized\n if (this.initialized.has(themeId)) {\n if (this.debug) {\n }\n return;\n }\n\n // Get or create registry for this theme\n const registry = this.getThemeRegistry(themeId);\n\n // Discover sections\n const sectionNames = await this.discoverThemeSections(themeId);\n\n if (sectionNames.length === 0) {\n console.warn(`[ThemeRegistry] No sections found for theme \"${themeId}\"`);\n this.initialized.add(themeId);\n return;\n }\n\n // Import and register each section\n let successCount = 0;\n let failureCount = 0;\n\n for (const sectionName of sectionNames) {\n try {\n // Dynamic import of section module\n const sectionModule = await import(\n `@/themes/${themeId}/sections/${sectionName}`\n );\n\n // Extract schema and components from module\n // Try different naming conventions\n const camelName = toCamelCase(sectionName);\n const schema: SectionSchema =\n sectionModule[`${camelName}Schema`] ||\n sectionModule.default?.schema ||\n sectionModule.schema;\n\n const components: Record<\n string,\n React.ComponentType<SectionComponentProps>\n > = sectionModule[`${camelName}Components`] ||\n sectionModule.default?.components ||\n sectionModule.components;\n\n if (!schema || !components) {\n console.error(\n `[ThemeRegistry] Section \"${sectionName}\" in theme \"${themeId}\" missing schema or components export.`,\n `Expected: \"${camelName}Schema\" and \"${camelName}Components\"`\n );\n failureCount++;\n continue;\n }\n\n // Register section to theme-specific registry\n // Get the default component for backward compatibility\n const defaultComponent =\n components.default || Object.values(components)[0];\n\n if (!defaultComponent) {\n console.error(\n `[ThemeRegistry] Section \"${sectionName}\" has no default component`\n );\n failureCount++;\n continue;\n }\n\n // Register with templates\n const templates = Object.entries(components).map(\n ([templateId, component]) => ({\n definition: schema.templates.find((t) => t.id === templateId) || {\n id: templateId,\n name: templateId,\n description: `${templateId} template`,\n isDefault: templateId === \"default\",\n settings: schema.settings,\n defaults: schema.defaults,\n },\n component,\n })\n );\n\n registry.register(schema.type, schema, defaultComponent, {\n templates,\n category: schema.category,\n tags: schema.tags,\n });\n\n successCount++;\n\n if (this.debug) {\n }\n } catch (error) {\n console.error(\n `[ThemeRegistry] Failed to load section \"${themeId}/${sectionName}\":`,\n error\n );\n failureCount++;\n }\n }\n\n // Mark as initialized\n this.initialized.add(themeId);\n }\n\n /**\n * Get or create theme-specific registry\n */\n getThemeRegistry(themeId: string): SectionRegistry {\n if (!this.registries.has(themeId)) {\n // Create new registry for this theme\n const registry = createSectionRegistry({\n debug: this.debug,\n allowOverride: this.debug,\n });\n\n this.registries.set(themeId, registry);\n\n if (this.debug) {\n }\n }\n\n return this.registries.get(themeId)!;\n }\n\n /**\n * Check if theme has been initialized\n */\n isThemeInitialized(themeId: string): boolean {\n return this.initialized.has(themeId);\n }\n\n /**\n * Resolve a section component for a specific theme\n * Returns null if not found (no fallback - strict validation)\n */\n resolveSection(\n themeId: string,\n sectionType: string,\n templateId: string = \"default\"\n ): React.ComponentType<SectionComponentProps> | null {\n const registry = this.getThemeRegistry(themeId);\n return registry.getTemplateComponent(sectionType, templateId) || null;\n }\n\n /**\n * Get section schema for a specific theme\n */\n getSectionSchema(themeId: string, sectionType: string): SectionSchema | null {\n const registry = this.getThemeRegistry(themeId);\n return registry.getSchema(sectionType) || null;\n }\n\n /**\n * Get all available themes\n */\n getAvailableThemes(): string[] {\n return Array.from(this.registries.keys());\n }\n\n /**\n * Get all section types for a theme\n */\n getThemeSections(themeId: string): string[] {\n const registry = this.registries.get(themeId);\n if (!registry) {\n return [];\n }\n\n const all = registry.getAll();\n return Array.from(all.keys());\n }\n\n /**\n * Clear a specific theme's registry\n */\n clearTheme(themeId: string): void {\n const registry = this.registries.get(themeId);\n if (registry) {\n registry.clear();\n this.initialized.delete(themeId);\n\n if (this.debug) {\n }\n }\n }\n\n /**\n * Clear all theme registries\n */\n clearAll(): void {\n this.registries.forEach((registry) => registry.clear());\n this.registries.clear();\n this.initialized.clear();\n\n if (this.debug) {\n }\n }\n}\n\n/**\n * Global theme registry manager instance\n */\nexport const themeRegistryManager = new ThemeRegistryManager();\n"]}
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { createSectionRegistry } from './chunk-XE4EOKS4.mjs';
|
|
2
|
+
import 'server-only';
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
|
|
6
|
+
function toCamelCase(str) {
|
|
7
|
+
return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
8
|
+
}
|
|
9
|
+
var ThemeRegistryManager = class {
|
|
10
|
+
constructor(debug = process.env.NODE_ENV === "development") {
|
|
11
|
+
this.registries = /* @__PURE__ */ new Map();
|
|
12
|
+
this.initialized = /* @__PURE__ */ new Set();
|
|
13
|
+
this.debug = debug;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Auto-discover sections from theme directory
|
|
17
|
+
* Reads filesystem to find all section directories
|
|
18
|
+
*/
|
|
19
|
+
async discoverThemeSections(themeId) {
|
|
20
|
+
const sectionsPath = path.join(
|
|
21
|
+
process.cwd(),
|
|
22
|
+
`src/themes/${themeId}/sections`
|
|
23
|
+
);
|
|
24
|
+
try {
|
|
25
|
+
const entries = await fs.readdir(sectionsPath, { withFileTypes: true });
|
|
26
|
+
const sectionNames = entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
27
|
+
if (this.debug) {
|
|
28
|
+
}
|
|
29
|
+
return sectionNames;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (this.debug) {
|
|
32
|
+
console.warn(
|
|
33
|
+
`[ThemeRegistry] No sections found for theme "${themeId}" at ${sectionsPath}`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Initialize a theme's sections
|
|
41
|
+
* Auto-discovers and registers all sections for a theme
|
|
42
|
+
*/
|
|
43
|
+
async initializeTheme(themeId) {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
if (this.initialized.has(themeId)) {
|
|
46
|
+
if (this.debug) ;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const registry = this.getThemeRegistry(themeId);
|
|
50
|
+
const sectionNames = await this.discoverThemeSections(themeId);
|
|
51
|
+
if (sectionNames.length === 0) {
|
|
52
|
+
console.warn(`[ThemeRegistry] No sections found for theme "${themeId}"`);
|
|
53
|
+
this.initialized.add(themeId);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
let successCount = 0;
|
|
57
|
+
let failureCount = 0;
|
|
58
|
+
for (const sectionName of sectionNames) {
|
|
59
|
+
try {
|
|
60
|
+
const sectionModule = await import(`@/themes/${themeId}/sections/${sectionName}`);
|
|
61
|
+
const camelName = toCamelCase(sectionName);
|
|
62
|
+
const schema = sectionModule[`${camelName}Schema`] || ((_a = sectionModule.default) == null ? void 0 : _a.schema) || sectionModule.schema;
|
|
63
|
+
const components = sectionModule[`${camelName}Components`] || ((_b = sectionModule.default) == null ? void 0 : _b.components) || sectionModule.components;
|
|
64
|
+
if (!schema || !components) {
|
|
65
|
+
console.error(
|
|
66
|
+
`[ThemeRegistry] Section "${sectionName}" in theme "${themeId}" missing schema or components export.`,
|
|
67
|
+
`Expected: "${camelName}Schema" and "${camelName}Components"`
|
|
68
|
+
);
|
|
69
|
+
failureCount++;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const defaultComponent = components.default || Object.values(components)[0];
|
|
73
|
+
if (!defaultComponent) {
|
|
74
|
+
console.error(
|
|
75
|
+
`[ThemeRegistry] Section "${sectionName}" has no default component`
|
|
76
|
+
);
|
|
77
|
+
failureCount++;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const templates = Object.entries(components).map(
|
|
81
|
+
([templateId, component]) => ({
|
|
82
|
+
definition: schema.templates.find((t) => t.id === templateId) || {
|
|
83
|
+
id: templateId,
|
|
84
|
+
name: templateId,
|
|
85
|
+
description: `${templateId} template`,
|
|
86
|
+
isDefault: templateId === "default",
|
|
87
|
+
settings: schema.settings,
|
|
88
|
+
defaults: schema.defaults
|
|
89
|
+
},
|
|
90
|
+
component
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
registry.register(schema.type, schema, defaultComponent, {
|
|
94
|
+
templates,
|
|
95
|
+
category: schema.category,
|
|
96
|
+
tags: schema.tags
|
|
97
|
+
});
|
|
98
|
+
successCount++;
|
|
99
|
+
if (this.debug) {
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error(
|
|
103
|
+
`[ThemeRegistry] Failed to load section "${themeId}/${sectionName}":`,
|
|
104
|
+
error
|
|
105
|
+
);
|
|
106
|
+
failureCount++;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
this.initialized.add(themeId);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get or create theme-specific registry
|
|
113
|
+
*/
|
|
114
|
+
getThemeRegistry(themeId) {
|
|
115
|
+
if (!this.registries.has(themeId)) {
|
|
116
|
+
const registry = createSectionRegistry({
|
|
117
|
+
debug: this.debug,
|
|
118
|
+
allowOverride: this.debug
|
|
119
|
+
});
|
|
120
|
+
this.registries.set(themeId, registry);
|
|
121
|
+
if (this.debug) ;
|
|
122
|
+
}
|
|
123
|
+
return this.registries.get(themeId);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Check if theme has been initialized
|
|
127
|
+
*/
|
|
128
|
+
isThemeInitialized(themeId) {
|
|
129
|
+
return this.initialized.has(themeId);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Resolve a section component for a specific theme
|
|
133
|
+
* Returns null if not found (no fallback - strict validation)
|
|
134
|
+
*/
|
|
135
|
+
resolveSection(themeId, sectionType, templateId = "default") {
|
|
136
|
+
const registry = this.getThemeRegistry(themeId);
|
|
137
|
+
return registry.getTemplateComponent(sectionType, templateId) || null;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get section schema for a specific theme
|
|
141
|
+
*/
|
|
142
|
+
getSectionSchema(themeId, sectionType) {
|
|
143
|
+
const registry = this.getThemeRegistry(themeId);
|
|
144
|
+
return registry.getSchema(sectionType) || null;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get all available themes
|
|
148
|
+
*/
|
|
149
|
+
getAvailableThemes() {
|
|
150
|
+
return Array.from(this.registries.keys());
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get all section types for a theme
|
|
154
|
+
*/
|
|
155
|
+
getThemeSections(themeId) {
|
|
156
|
+
const registry = this.registries.get(themeId);
|
|
157
|
+
if (!registry) {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
const all = registry.getAll();
|
|
161
|
+
return Array.from(all.keys());
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Clear a specific theme's registry
|
|
165
|
+
*/
|
|
166
|
+
clearTheme(themeId) {
|
|
167
|
+
const registry = this.registries.get(themeId);
|
|
168
|
+
if (registry) {
|
|
169
|
+
registry.clear();
|
|
170
|
+
this.initialized.delete(themeId);
|
|
171
|
+
if (this.debug) ;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Clear all theme registries
|
|
176
|
+
*/
|
|
177
|
+
clearAll() {
|
|
178
|
+
this.registries.forEach((registry) => registry.clear());
|
|
179
|
+
this.registries.clear();
|
|
180
|
+
this.initialized.clear();
|
|
181
|
+
if (this.debug) ;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
var themeRegistryManager = new ThemeRegistryManager();
|
|
185
|
+
|
|
186
|
+
export { ThemeRegistryManager, themeRegistryManager };
|
|
187
|
+
//# sourceMappingURL=server.mjs.map
|
|
188
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/registry/theme-registry-manager.ts"],"names":[],"mappings":"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","file":"server.mjs","sourcesContent":["/**\n * Theme Registry Manager\n * Manages theme-specific section registries with auto-discovery\n *\n * SERVER-ONLY: Uses filesystem operations, cannot run in browser\n */\n\nimport \"server-only\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport type { SectionRegistry } from \"../types/registry\";\nimport type { SectionSchema, SectionComponentProps } from \"../types/section\";\nimport { createSectionRegistry } from \"./section-registry\";\n\n/**\n * Convert kebab-case to camelCase\n */\nfunction toCamelCase(str: string): string {\n return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n}\n\n/**\n * Theme Registry Manager\n * Auto-discovers and manages theme-specific section registries\n */\nexport class ThemeRegistryManager {\n private registries: Map<string, SectionRegistry>;\n private initialized: Set<string>;\n private debug: boolean;\n\n constructor(debug: boolean = process.env.NODE_ENV === \"development\") {\n this.registries = new Map();\n this.initialized = new Set();\n this.debug = debug;\n }\n\n /**\n * Auto-discover sections from theme directory\n * Reads filesystem to find all section directories\n */\n async discoverThemeSections(themeId: string): Promise<string[]> {\n const sectionsPath = path.join(\n process.cwd(),\n `src/themes/${themeId}/sections`\n );\n\n try {\n const entries = await fs.readdir(sectionsPath, { withFileTypes: true });\n\n // Return only directories (each directory = one section)\n const sectionNames = entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n\n if (this.debug) {\n }\n\n return sectionNames;\n } catch (error) {\n if (this.debug) {\n console.warn(\n `[ThemeRegistry] No sections found for theme \"${themeId}\" at ${sectionsPath}`\n );\n }\n return [];\n }\n }\n\n /**\n * Initialize a theme's sections\n * Auto-discovers and registers all sections for a theme\n */\n async initializeTheme(themeId: string): Promise<void> {\n // Check if already initialized\n if (this.initialized.has(themeId)) {\n if (this.debug) {\n }\n return;\n }\n\n // Get or create registry for this theme\n const registry = this.getThemeRegistry(themeId);\n\n // Discover sections\n const sectionNames = await this.discoverThemeSections(themeId);\n\n if (sectionNames.length === 0) {\n console.warn(`[ThemeRegistry] No sections found for theme \"${themeId}\"`);\n this.initialized.add(themeId);\n return;\n }\n\n // Import and register each section\n let successCount = 0;\n let failureCount = 0;\n\n for (const sectionName of sectionNames) {\n try {\n // Dynamic import of section module\n const sectionModule = await import(\n `@/themes/${themeId}/sections/${sectionName}`\n );\n\n // Extract schema and components from module\n // Try different naming conventions\n const camelName = toCamelCase(sectionName);\n const schema: SectionSchema =\n sectionModule[`${camelName}Schema`] ||\n sectionModule.default?.schema ||\n sectionModule.schema;\n\n const components: Record<\n string,\n React.ComponentType<SectionComponentProps>\n > = sectionModule[`${camelName}Components`] ||\n sectionModule.default?.components ||\n sectionModule.components;\n\n if (!schema || !components) {\n console.error(\n `[ThemeRegistry] Section \"${sectionName}\" in theme \"${themeId}\" missing schema or components export.`,\n `Expected: \"${camelName}Schema\" and \"${camelName}Components\"`\n );\n failureCount++;\n continue;\n }\n\n // Register section to theme-specific registry\n // Get the default component for backward compatibility\n const defaultComponent =\n components.default || Object.values(components)[0];\n\n if (!defaultComponent) {\n console.error(\n `[ThemeRegistry] Section \"${sectionName}\" has no default component`\n );\n failureCount++;\n continue;\n }\n\n // Register with templates\n const templates = Object.entries(components).map(\n ([templateId, component]) => ({\n definition: schema.templates.find((t) => t.id === templateId) || {\n id: templateId,\n name: templateId,\n description: `${templateId} template`,\n isDefault: templateId === \"default\",\n settings: schema.settings,\n defaults: schema.defaults,\n },\n component,\n })\n );\n\n registry.register(schema.type, schema, defaultComponent, {\n templates,\n category: schema.category,\n tags: schema.tags,\n });\n\n successCount++;\n\n if (this.debug) {\n }\n } catch (error) {\n console.error(\n `[ThemeRegistry] Failed to load section \"${themeId}/${sectionName}\":`,\n error\n );\n failureCount++;\n }\n }\n\n // Mark as initialized\n this.initialized.add(themeId);\n }\n\n /**\n * Get or create theme-specific registry\n */\n getThemeRegistry(themeId: string): SectionRegistry {\n if (!this.registries.has(themeId)) {\n // Create new registry for this theme\n const registry = createSectionRegistry({\n debug: this.debug,\n allowOverride: this.debug,\n });\n\n this.registries.set(themeId, registry);\n\n if (this.debug) {\n }\n }\n\n return this.registries.get(themeId)!;\n }\n\n /**\n * Check if theme has been initialized\n */\n isThemeInitialized(themeId: string): boolean {\n return this.initialized.has(themeId);\n }\n\n /**\n * Resolve a section component for a specific theme\n * Returns null if not found (no fallback - strict validation)\n */\n resolveSection(\n themeId: string,\n sectionType: string,\n templateId: string = \"default\"\n ): React.ComponentType<SectionComponentProps> | null {\n const registry = this.getThemeRegistry(themeId);\n return registry.getTemplateComponent(sectionType, templateId) || null;\n }\n\n /**\n * Get section schema for a specific theme\n */\n getSectionSchema(themeId: string, sectionType: string): SectionSchema | null {\n const registry = this.getThemeRegistry(themeId);\n return registry.getSchema(sectionType) || null;\n }\n\n /**\n * Get all available themes\n */\n getAvailableThemes(): string[] {\n return Array.from(this.registries.keys());\n }\n\n /**\n * Get all section types for a theme\n */\n getThemeSections(themeId: string): string[] {\n const registry = this.registries.get(themeId);\n if (!registry) {\n return [];\n }\n\n const all = registry.getAll();\n return Array.from(all.keys());\n }\n\n /**\n * Clear a specific theme's registry\n */\n clearTheme(themeId: string): void {\n const registry = this.registries.get(themeId);\n if (registry) {\n registry.clear();\n this.initialized.delete(themeId);\n\n if (this.debug) {\n }\n }\n }\n\n /**\n * Clear all theme registries\n */\n clearAll(): void {\n this.registries.forEach((registry) => registry.clear());\n this.registries.clear();\n this.initialized.clear();\n\n if (this.debug) {\n }\n }\n}\n\n/**\n * Global theme registry manager instance\n */\nexport const themeRegistryManager = new ThemeRegistryManager();\n"]}
|