@qiu_qiu/vue-auto-component-framework 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Vue Auto Component Framework
2
+
3
+ A Vue3 TypeScript framework that provides automatic component registration and layout system functionality.
4
+
5
+ ## Features
6
+
7
+ - 🚀 Automatic component registration from `@/components` directory
8
+ - 🎨 Built-in layout system with responsive design
9
+ - 📦 TypeScript support with full type definitions
10
+ - 🔧 Compatible with Vue 3 Composition API
11
+ - 🛠️ Error handling and recovery mechanisms
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install vue-auto-component-framework
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```typescript
22
+ import { createApp } from 'vue-auto-component-framework'
23
+ import App from './App.vue'
24
+
25
+ const app = await createApp(App, {
26
+ componentsPath: '@/components', // optional, defaults to '@/components'
27
+ layoutConfig: {
28
+ header: true,
29
+ sidebar: true,
30
+ footer: true,
31
+ responsive: true
32
+ }
33
+ })
34
+
35
+ app.mount('#app')
36
+ ```
37
+
38
+ ## Development
39
+
40
+ ```bash
41
+ # Install dependencies
42
+ npm install
43
+
44
+ # Build the project
45
+ npm run build
46
+
47
+ # Run tests
48
+ npm test
49
+
50
+ # Run tests in watch mode
51
+ npm run test:watch
52
+
53
+ # Type checking
54
+ npm run type-check
55
+
56
+ # Linting
57
+ npm run lint
58
+ ```
59
+
60
+ ## Project Structure
61
+
62
+ ```
63
+ src/
64
+ ├── core/ # Core framework classes
65
+ ├── layout/ # Layout components
66
+ ├── types/ # TypeScript type definitions
67
+ └── index.ts # Main entry point
68
+ ```
69
+
70
+ ## License
71
+
72
+ MIT
@@ -0,0 +1,33 @@
1
+ import { type App, type Component } from 'vue';
2
+ import type { FrameworkOptions, LayoutConfig } from '@/types';
3
+ import { LayoutManager } from '@/layout/LayoutManager';
4
+ /**
5
+ * App creator implementation
6
+ * Handles Vue app creation with framework features
7
+ */
8
+ export declare class AppCreator {
9
+ private componentScanner;
10
+ private layoutManager;
11
+ constructor();
12
+ /**
13
+ * Create Vue app with framework features and error recovery
14
+ */
15
+ createApp(rootComponent?: Component, options?: FrameworkOptions): Promise<App>;
16
+ /**
17
+ * Get current layout configuration
18
+ */
19
+ getLayoutConfig(): Required<LayoutConfig>;
20
+ /**
21
+ * Update layout configuration
22
+ */
23
+ updateLayoutConfig(config: LayoutConfig): void;
24
+ /**
25
+ * Register a custom layout component
26
+ */
27
+ registerLayout(name: string, component: Component): void;
28
+ /**
29
+ * Get layout manager instance
30
+ */
31
+ getLayoutManager(): LayoutManager;
32
+ }
33
+ //# sourceMappingURL=AppCreator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppCreator.d.ts","sourceRoot":"","sources":["../../src/core/AppCreator.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,KAAK,CAAA;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAEtD;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,gBAAgB,CAAkB;IAC1C,OAAO,CAAC,aAAa,CAAe;;IAOpC;;OAEG;IACG,SAAS,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC;IAmFxF;;OAEG;IACH,eAAe,IAAI,QAAQ,CAAC,YAAY,CAAC;IAIzC;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI9C;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAIxD;;OAEG;IACH,gBAAgB,IAAI,aAAa;CAGlC"}
@@ -0,0 +1,100 @@
1
+ import { createApp as vueCreateApp } from 'vue';
2
+ import { ComponentScanner } from './ComponentScanner';
3
+ import { ErrorHandler } from './ErrorHandler';
4
+ import { LayoutManager } from '@/layout/LayoutManager';
5
+ /**
6
+ * App creator implementation
7
+ * Handles Vue app creation with framework features
8
+ */
9
+ export class AppCreator {
10
+ constructor() {
11
+ this.componentScanner = new ComponentScanner();
12
+ this.layoutManager = new LayoutManager();
13
+ }
14
+ /**
15
+ * Create Vue app with framework features and error recovery
16
+ */
17
+ async createApp(rootComponent, options = {}) {
18
+ try {
19
+ const app = vueCreateApp(rootComponent || {});
20
+ // Initialize layout system with custom configuration
21
+ if (options.layoutConfig) {
22
+ this.layoutManager.updateConfig(options.layoutConfig);
23
+ }
24
+ try {
25
+ this.layoutManager.initializeLayouts(app);
26
+ }
27
+ catch (error) {
28
+ const layoutError = ErrorHandler.createLayoutError('Failed to initialize layout system', { layoutConfig: options.layoutConfig }, error);
29
+ ErrorHandler.logError(layoutError);
30
+ // Continue without layout system - app can still function
31
+ }
32
+ // Install additional plugins with error handling
33
+ if (options.plugins) {
34
+ options.plugins.forEach((plugin, index) => {
35
+ try {
36
+ app.use(plugin);
37
+ }
38
+ catch (error) {
39
+ const pluginError = ErrorHandler.createAppError(`Failed to install plugin at index ${index}`, { pluginIndex: index }, error);
40
+ ErrorHandler.logError(pluginError);
41
+ // Continue with other plugins - partial functionality is better than none
42
+ }
43
+ });
44
+ }
45
+ // Scan and register components with comprehensive error handling
46
+ const componentsPath = options.componentsPath || '@/components';
47
+ try {
48
+ const components = await this.componentScanner.scanComponents(componentsPath);
49
+ this.componentScanner.registerComponents(app, components);
50
+ // Report any errors that occurred during scanning/registration
51
+ const scanErrors = this.componentScanner.getErrors();
52
+ if (scanErrors.length > 0) {
53
+ console.warn(`Component scanning completed with ${scanErrors.length} errors`);
54
+ // Log summary of errors for debugging
55
+ const errorSummary = ErrorHandler.formatErrorSummary(scanErrors);
56
+ console.warn(errorSummary);
57
+ }
58
+ }
59
+ catch (error) {
60
+ // Critical component scanning error - log but don't fail app creation
61
+ const criticalError = ErrorHandler.createAppError('Critical error during component scanning - app will continue without auto-registered components', { componentsPath }, error);
62
+ ErrorHandler.logError(criticalError);
63
+ // App can still function without auto-registered components
64
+ console.warn('Application created successfully but component auto-registration failed');
65
+ }
66
+ return app;
67
+ }
68
+ catch (error) {
69
+ // Critical app creation error
70
+ const appError = ErrorHandler.createAppError('Failed to create Vue application', { rootComponent: rootComponent?.name || 'anonymous', options }, error);
71
+ ErrorHandler.logError(appError);
72
+ // Re-throw critical errors as they prevent app from functioning
73
+ throw appError;
74
+ }
75
+ }
76
+ /**
77
+ * Get current layout configuration
78
+ */
79
+ getLayoutConfig() {
80
+ return this.layoutManager.getConfig();
81
+ }
82
+ /**
83
+ * Update layout configuration
84
+ */
85
+ updateLayoutConfig(config) {
86
+ this.layoutManager.updateConfig(config);
87
+ }
88
+ /**
89
+ * Register a custom layout component
90
+ */
91
+ registerLayout(name, component) {
92
+ this.layoutManager.registerLayout(name, component);
93
+ }
94
+ /**
95
+ * Get layout manager instance
96
+ */
97
+ getLayoutManager() {
98
+ return this.layoutManager;
99
+ }
100
+ }
@@ -0,0 +1,44 @@
1
+ import type { Component } from 'vue';
2
+ import type { ComponentRegistry as IComponentRegistry } from '@/types';
3
+ /**
4
+ * Component registry implementation
5
+ * Manages registration and retrieval of Vue components with conflict detection
6
+ */
7
+ export declare class ComponentRegistry implements IComponentRegistry {
8
+ private components;
9
+ private componentPaths;
10
+ /**
11
+ * Register a component with the given name
12
+ * Handles name conflicts by generating unique names using file paths
13
+ */
14
+ register(name: string, component: Component, filePath?: string): void;
15
+ /**
16
+ * Get a component by name
17
+ */
18
+ get(name: string): Component | undefined;
19
+ /**
20
+ * Get all registered components
21
+ */
22
+ getAll(): Map<string, Component>;
23
+ /**
24
+ * Check if a component is registered
25
+ */
26
+ has(name: string): boolean;
27
+ /**
28
+ * Get the file path for a registered component
29
+ */
30
+ getPath(name: string): string | undefined;
31
+ /**
32
+ * Get all component names
33
+ */
34
+ getNames(): string[];
35
+ /**
36
+ * Clear all registered components
37
+ */
38
+ clear(): void;
39
+ /**
40
+ * Resolve name conflicts by using file path information
41
+ */
42
+ private resolveNameConflict;
43
+ }
44
+ //# sourceMappingURL=ComponentRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComponentRegistry.d.ts","sourceRoot":"","sources":["../../src/core/ComponentRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AACpC,OAAO,KAAK,EAAE,iBAAiB,IAAI,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAGtE;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,cAAc,CAAiC;IAEvD;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAoDrE;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIxC;;OAEG;IACH,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC;IAIhC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIzC;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;IAIpB;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,OAAO,CAAC,mBAAmB;CA2B5B"}
@@ -0,0 +1,110 @@
1
+ import { ErrorHandler } from './ErrorHandler';
2
+ /**
3
+ * Component registry implementation
4
+ * Manages registration and retrieval of Vue components with conflict detection
5
+ */
6
+ export class ComponentRegistry {
7
+ constructor() {
8
+ this.components = new Map();
9
+ this.componentPaths = new Map();
10
+ }
11
+ /**
12
+ * Register a component with the given name
13
+ * Handles name conflicts by generating unique names using file paths
14
+ */
15
+ register(name, component, filePath) {
16
+ if (!name || typeof name !== 'string') {
17
+ throw ErrorHandler.createRegistrationError('Component name must be a non-empty string', name, filePath);
18
+ }
19
+ if (!component) {
20
+ throw ErrorHandler.createRegistrationError('Component cannot be null or undefined', name, filePath);
21
+ }
22
+ let finalName = name;
23
+ // Handle name conflicts by generating unique names
24
+ if (this.components.has(name)) {
25
+ const existingPath = this.componentPaths.get(name);
26
+ // Log the conflict for debugging
27
+ const conflictError = ErrorHandler.createNameConflictError(name, existingPath || 'unknown', filePath || 'unknown');
28
+ ErrorHandler.logError(conflictError);
29
+ // Resolve conflict by generating unique name
30
+ if (filePath) {
31
+ finalName = this.resolveNameConflict(name, filePath);
32
+ }
33
+ else {
34
+ // If no file path provided, append a counter
35
+ let counter = 1;
36
+ while (this.components.has(`${name}_${counter}`)) {
37
+ counter++;
38
+ }
39
+ finalName = `${name}_${counter}`;
40
+ }
41
+ console.info(`Resolved name conflict: ${name} -> ${finalName}`);
42
+ }
43
+ this.components.set(finalName, component);
44
+ if (filePath) {
45
+ this.componentPaths.set(finalName, filePath);
46
+ }
47
+ }
48
+ /**
49
+ * Get a component by name
50
+ */
51
+ get(name) {
52
+ return this.components.get(name);
53
+ }
54
+ /**
55
+ * Get all registered components
56
+ */
57
+ getAll() {
58
+ return new Map(this.components);
59
+ }
60
+ /**
61
+ * Check if a component is registered
62
+ */
63
+ has(name) {
64
+ return this.components.has(name);
65
+ }
66
+ /**
67
+ * Get the file path for a registered component
68
+ */
69
+ getPath(name) {
70
+ return this.componentPaths.get(name);
71
+ }
72
+ /**
73
+ * Get all component names
74
+ */
75
+ getNames() {
76
+ return Array.from(this.components.keys());
77
+ }
78
+ /**
79
+ * Clear all registered components
80
+ */
81
+ clear() {
82
+ this.components.clear();
83
+ this.componentPaths.clear();
84
+ }
85
+ /**
86
+ * Resolve name conflicts by using file path information
87
+ */
88
+ resolveNameConflict(baseName, filePath) {
89
+ // Extract directory structure to create unique suffix
90
+ const pathParts = filePath.split(/[/\\]/).filter(part => part && part !== '.' && part !== '..');
91
+ // Remove file extension and base name from path parts
92
+ const fileName = pathParts[pathParts.length - 1]?.replace(/\.(vue|ts|js)$/, '');
93
+ const dirParts = pathParts.slice(0, -1);
94
+ // Create suffix from directory structure
95
+ let suffix = '';
96
+ if (dirParts.length > 0) {
97
+ suffix = dirParts.join('_');
98
+ }
99
+ // Generate unique name
100
+ let uniqueName = suffix ? `${baseName}_${suffix}` : baseName;
101
+ // If still conflicts, add counter
102
+ let counter = 1;
103
+ const originalUniqueName = uniqueName;
104
+ while (this.components.has(uniqueName)) {
105
+ uniqueName = `${originalUniqueName}_${counter}`;
106
+ counter++;
107
+ }
108
+ return uniqueName;
109
+ }
110
+ }
@@ -0,0 +1,50 @@
1
+ import type { App } from 'vue';
2
+ import type { ComponentScanner as IComponentScanner, ComponentInfo, FrameworkError } from '@/types';
3
+ import { ComponentRegistry } from './ComponentRegistry';
4
+ /**
5
+ * Component scanner implementation
6
+ * Handles scanning and registering Vue components with error recovery
7
+ */
8
+ export declare class ComponentScanner implements IComponentScanner {
9
+ private _fileScanner;
10
+ private _registry;
11
+ private _errors;
12
+ constructor();
13
+ /**
14
+ * Get all errors encountered during scanning and registration
15
+ */
16
+ getErrors(): FrameworkError[];
17
+ /**
18
+ * Clear accumulated errors
19
+ */
20
+ clearErrors(): void;
21
+ /**
22
+ * Scan components in the specified base path with error recovery
23
+ */
24
+ scanComponents(basePath: string): Promise<ComponentInfo[]>;
25
+ /**
26
+ * Register components in the Vue app with conflict detection and error recovery
27
+ */
28
+ registerComponents(app: App, components: ComponentInfo[]): void;
29
+ /**
30
+ * Get the internal component registry
31
+ */
32
+ getRegistry(): ComponentRegistry;
33
+ /**
34
+ * Generate component name from file path
35
+ */
36
+ private _generateComponentName;
37
+ /**
38
+ * Convert string to PascalCase
39
+ */
40
+ private _toPascalCase;
41
+ /**
42
+ * Dynamically load a Vue component from file path with enhanced error handling
43
+ */
44
+ private _loadComponent;
45
+ /**
46
+ * Validate if an object is a valid Vue component
47
+ */
48
+ private _isValidVueComponent;
49
+ }
50
+ //# sourceMappingURL=ComponentScanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComponentScanner.d.ts","sourceRoot":"","sources":["../../src/core/ComponentScanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAC9B,OAAO,KAAK,EAAE,gBAAgB,IAAI,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAGvD;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,iBAAiB;IACxD,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,OAAO,CAAuB;;IAOtC;;OAEG;IACH,SAAS,IAAI,cAAc,EAAE;IAI7B;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAiEhE;;OAEG;IACH,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI;IA8D/D;;OAEG;IACH,WAAW,IAAI,iBAAiB;IAIhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAuB9B;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;OAEG;YACW,cAAc;IAkC5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAqB7B"}
@@ -0,0 +1,203 @@
1
+ import { FileScanner } from './FileScanner';
2
+ import { ComponentRegistry } from './ComponentRegistry';
3
+ import { ErrorHandler } from './ErrorHandler';
4
+ /**
5
+ * Component scanner implementation
6
+ * Handles scanning and registering Vue components with error recovery
7
+ */
8
+ export class ComponentScanner {
9
+ constructor() {
10
+ this._errors = [];
11
+ this._fileScanner = new FileScanner();
12
+ this._registry = new ComponentRegistry();
13
+ }
14
+ /**
15
+ * Get all errors encountered during scanning and registration
16
+ */
17
+ getErrors() {
18
+ return [...this._errors];
19
+ }
20
+ /**
21
+ * Clear accumulated errors
22
+ */
23
+ clearErrors() {
24
+ this._errors = [];
25
+ }
26
+ /**
27
+ * Scan components in the specified base path with error recovery
28
+ */
29
+ async scanComponents(basePath) {
30
+ this.clearErrors();
31
+ try {
32
+ const scanResult = await this._fileScanner.scanDirectory(basePath, ['.vue']);
33
+ const components = [];
34
+ // Handle file scanning errors
35
+ if (scanResult.errors.length > 0) {
36
+ scanResult.errors.forEach(error => {
37
+ const frameworkError = ErrorHandler.createScanError(`File scanning error: ${error.message}`, undefined, error);
38
+ this._errors.push(frameworkError);
39
+ ErrorHandler.logError(frameworkError);
40
+ });
41
+ }
42
+ // Process each found file with individual error handling
43
+ for (const filePath of scanResult.files) {
44
+ try {
45
+ // Generate component name from file path
46
+ const name = this._generateComponentName(filePath, basePath);
47
+ // Dynamically import the Vue component
48
+ const component = await this._loadComponent(filePath);
49
+ components.push({
50
+ name,
51
+ component,
52
+ path: filePath
53
+ });
54
+ }
55
+ catch (error) {
56
+ // Create detailed error but continue processing other components
57
+ const frameworkError = ErrorHandler.createScanError(`Failed to process component file: ${filePath}`, filePath, error);
58
+ this._errors.push(frameworkError);
59
+ ErrorHandler.logError(frameworkError);
60
+ // Continue with next component (error recovery)
61
+ continue;
62
+ }
63
+ }
64
+ return components;
65
+ }
66
+ catch (error) {
67
+ // Critical scanning error - still try to return what we have
68
+ const frameworkError = ErrorHandler.createScanError(`Critical error during component scanning: ${error.message}`, basePath, error);
69
+ this._errors.push(frameworkError);
70
+ ErrorHandler.logError(frameworkError);
71
+ // Return empty array but don't throw - allow app to continue
72
+ return [];
73
+ }
74
+ }
75
+ /**
76
+ * Register components in the Vue app with conflict detection and error recovery
77
+ */
78
+ registerComponents(app, components) {
79
+ // Clear registry for fresh registration
80
+ this._registry.clear();
81
+ let successCount = 0;
82
+ let errorCount = 0;
83
+ components.forEach(({ name, component, path }) => {
84
+ try {
85
+ // Validate component before registration
86
+ if (!this._isValidVueComponent(component)) {
87
+ const error = ErrorHandler.createInvalidComponentError(name, path, 'Component does not have required Vue component structure');
88
+ this._errors.push(error);
89
+ ErrorHandler.logError(error);
90
+ errorCount++;
91
+ return;
92
+ }
93
+ // Register in internal registry with conflict detection
94
+ this._registry.register(name, component, path);
95
+ // Get the final name (may be different due to conflict resolution)
96
+ const finalName = this._registry.getNames().find(registeredName => this._registry.get(registeredName) === component) || name;
97
+ // Register in Vue app
98
+ app.component(finalName, component);
99
+ successCount++;
100
+ }
101
+ catch (error) {
102
+ // Handle registration errors gracefully
103
+ const frameworkError = ErrorHandler.createRegistrationError(`Failed to register component: ${error.message}`, name, path, error);
104
+ this._errors.push(frameworkError);
105
+ ErrorHandler.logError(frameworkError);
106
+ errorCount++;
107
+ // Continue with next component (error recovery)
108
+ }
109
+ });
110
+ // Log summary of registration results
111
+ if (successCount > 0 || errorCount > 0) {
112
+ console.info(`Component registration completed: ${successCount} successful, ${errorCount} failed`);
113
+ }
114
+ // If we have errors but some components were registered successfully,
115
+ // the app can still continue (graceful degradation)
116
+ if (errorCount > 0 && successCount === 0) {
117
+ console.warn('No components were successfully registered, but application will continue');
118
+ }
119
+ }
120
+ /**
121
+ * Get the internal component registry
122
+ */
123
+ getRegistry() {
124
+ return this._registry;
125
+ }
126
+ /**
127
+ * Generate component name from file path
128
+ */
129
+ _generateComponentName(filePath, basePath) {
130
+ // Remove base path to get relative path
131
+ let relativePath = filePath.replace(basePath, '').replace(/^[/\\]/, '');
132
+ // Remove file extension
133
+ relativePath = relativePath.replace(/\.(vue|ts|js)$/, '');
134
+ // Handle special characters and path separators
135
+ // Replace path separators and special characters with dashes
136
+ let normalizedName = relativePath
137
+ .replace(/[/\\]/g, '-') // Replace path separators
138
+ .replace(/[^a-zA-Z0-9-_]/g, '-') // Replace special characters
139
+ .replace(/-+/g, '-') // Replace multiple dashes with single dash
140
+ .replace(/^-|-$/g, ''); // Remove leading/trailing dashes
141
+ // Convert to PascalCase
142
+ return normalizedName
143
+ .split('-')
144
+ .filter(part => part.length > 0) // Remove empty parts
145
+ .map(part => this._toPascalCase(part))
146
+ .join('');
147
+ }
148
+ /**
149
+ * Convert string to PascalCase
150
+ */
151
+ _toPascalCase(str) {
152
+ return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
153
+ }
154
+ /**
155
+ * Dynamically load a Vue component from file path with enhanced error handling
156
+ */
157
+ async _loadComponent(filePath) {
158
+ try {
159
+ // Dynamic import of the component module
160
+ const componentModule = await import(filePath);
161
+ // Handle different export patterns
162
+ let component = componentModule.default || componentModule;
163
+ // Validate that it's a valid Vue component
164
+ if (!component || (typeof component !== 'object' && typeof component !== 'function')) {
165
+ throw ErrorHandler.createInvalidComponentError(this._generateComponentName(filePath, ''), filePath, 'Invalid component export - must be object or function');
166
+ }
167
+ // For Vue SFC, ensure we have the component definition
168
+ if (component.__vccOpts) {
169
+ component = component.__vccOpts;
170
+ }
171
+ return component;
172
+ }
173
+ catch (error) {
174
+ // If it's already a FrameworkError, re-throw it
175
+ if (error instanceof Error && error.name === 'FrameworkError') {
176
+ throw error;
177
+ }
178
+ // Otherwise, wrap in import error
179
+ throw ErrorHandler.createImportError(filePath, error);
180
+ }
181
+ }
182
+ /**
183
+ * Validate if an object is a valid Vue component
184
+ */
185
+ _isValidVueComponent(component) {
186
+ if (!component)
187
+ return false;
188
+ // Check for function component
189
+ if (typeof component === 'function')
190
+ return true;
191
+ // Check for object component with render function or template
192
+ if (typeof component === 'object') {
193
+ return !!(component.render ||
194
+ component.template ||
195
+ component.setup ||
196
+ component.__vccOpts ||
197
+ component.components ||
198
+ component.data ||
199
+ component.methods);
200
+ }
201
+ return false;
202
+ }
203
+ }
@@ -0,0 +1,51 @@
1
+ import { FrameworkError } from '@/types';
2
+ /**
3
+ * Error handler utility class for creating and managing framework errors
4
+ */
5
+ export declare class ErrorHandler {
6
+ /**
7
+ * Create a component scan error
8
+ */
9
+ static createScanError(message: string, filePath?: string, cause?: Error): FrameworkError;
10
+ /**
11
+ * Create a component registration error
12
+ */
13
+ static createRegistrationError(message: string, componentName?: string, filePath?: string, cause?: Error): FrameworkError;
14
+ /**
15
+ * Create a layout initialization error
16
+ */
17
+ static createLayoutError(message: string, context?: Record<string, any>, cause?: Error): FrameworkError;
18
+ /**
19
+ * Create an app creation error
20
+ */
21
+ static createAppError(message: string, context?: Record<string, any>, cause?: Error): FrameworkError;
22
+ /**
23
+ * Create a file not found error
24
+ */
25
+ static createFileNotFoundError(filePath: string, cause?: Error): FrameworkError;
26
+ /**
27
+ * Create an invalid component error
28
+ */
29
+ static createInvalidComponentError(componentName: string, filePath: string, reason?: string, cause?: Error): FrameworkError;
30
+ /**
31
+ * Create a name conflict error
32
+ */
33
+ static createNameConflictError(componentName: string, existingPath: string, newPath: string): FrameworkError;
34
+ /**
35
+ * Create an import error
36
+ */
37
+ static createImportError(filePath: string, cause?: Error): FrameworkError;
38
+ /**
39
+ * Log error with appropriate level based on error type
40
+ */
41
+ static logError(error: FrameworkError, logger?: Console): void;
42
+ /**
43
+ * Check if an error is recoverable (app can continue running)
44
+ */
45
+ static isRecoverable(error: FrameworkError): boolean;
46
+ /**
47
+ * Collect and format multiple errors for reporting
48
+ */
49
+ static formatErrorSummary(errors: FrameworkError[]): string;
50
+ }
51
+ //# sourceMappingURL=ErrorHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorHandler.d.ts","sourceRoot":"","sources":["../../src/core/ErrorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAyC,MAAM,SAAS,CAAA;AAE/E;;GAEG;AACH,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,cAAc;IASzF;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAC5B,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,KAAK,GACZ,cAAc;IASjB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,cAAc;IASvG;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,cAAc;IASpG;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,cAAc;IAS/E;;OAEG;IACH,MAAM,CAAC,2BAA2B,CAChC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,KAAK,GACZ,cAAc;IAajB;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAC5B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,cAAc;IAcjB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,cAAc;IASzE;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,GAAE,OAAiB,GAAG,IAAI;IAuBvE;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO;IAapD;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM;CAuB5D"}