@omnitron-dev/prism 0.1.1

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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/bin/prism.js +13 -0
  4. package/dist/accessibility/index.d.ts +157 -0
  5. package/dist/accessibility/index.js +186 -0
  6. package/dist/accessibility/index.js.map +1 -0
  7. package/dist/blocks/index.d.ts +1239 -0
  8. package/dist/blocks/index.js +1712 -0
  9. package/dist/blocks/index.js.map +1 -0
  10. package/dist/chunk-77KIJLPP.js +37 -0
  11. package/dist/chunk-77KIJLPP.js.map +1 -0
  12. package/dist/chunk-BTIT7WYH.js +339 -0
  13. package/dist/chunk-BTIT7WYH.js.map +1 -0
  14. package/dist/chunk-BV32OJ2A.js +1409 -0
  15. package/dist/chunk-BV32OJ2A.js.map +1 -0
  16. package/dist/chunk-DDY7TLUI.js +139 -0
  17. package/dist/chunk-DDY7TLUI.js.map +1 -0
  18. package/dist/chunk-DXXZ3ITR.js +4227 -0
  19. package/dist/chunk-DXXZ3ITR.js.map +1 -0
  20. package/dist/chunk-E3XANPTO.js +2319 -0
  21. package/dist/chunk-E3XANPTO.js.map +1 -0
  22. package/dist/chunk-FU52GL2E.js +3 -0
  23. package/dist/chunk-FU52GL2E.js.map +1 -0
  24. package/dist/chunk-GYDT5EKX.js +16505 -0
  25. package/dist/chunk-GYDT5EKX.js.map +1 -0
  26. package/dist/chunk-HO2GKTWJ.js +28 -0
  27. package/dist/chunk-HO2GKTWJ.js.map +1 -0
  28. package/dist/chunk-JDTC2SBY.js +140 -0
  29. package/dist/chunk-JDTC2SBY.js.map +1 -0
  30. package/dist/chunk-JNU4QHJK.js +6 -0
  31. package/dist/chunk-JNU4QHJK.js.map +1 -0
  32. package/dist/chunk-LAEY5USO.js +2621 -0
  33. package/dist/chunk-LAEY5USO.js.map +1 -0
  34. package/dist/chunk-UR6X3W5I.js +530 -0
  35. package/dist/chunk-UR6X3W5I.js.map +1 -0
  36. package/dist/chunk-WC2WM2JD.js +883 -0
  37. package/dist/chunk-WC2WM2JD.js.map +1 -0
  38. package/dist/chunk-XWL6J6IO.js +40 -0
  39. package/dist/chunk-XWL6J6IO.js.map +1 -0
  40. package/dist/cli/index.js +2695 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/config-BA6IeTq9.d.ts +100 -0
  43. package/dist/core/index.d.ts +454 -0
  44. package/dist/core/index.js +9 -0
  45. package/dist/core/index.js.map +1 -0
  46. package/dist/forms/index.d.ts +562 -0
  47. package/dist/forms/index.js +545 -0
  48. package/dist/forms/index.js.map +1 -0
  49. package/dist/hooks/index.d.ts +7 -0
  50. package/dist/hooks/index.js +10 -0
  51. package/dist/hooks/index.js.map +1 -0
  52. package/dist/http/index.d.ts +233 -0
  53. package/dist/http/index.js +282 -0
  54. package/dist/http/index.js.map +1 -0
  55. package/dist/index-odhPSv9I.d.ts +2491 -0
  56. package/dist/index.css +131 -0
  57. package/dist/index.css.map +1 -0
  58. package/dist/index.d.ts +9109 -0
  59. package/dist/index.js +13280 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/layouts/index.d.ts +854 -0
  62. package/dist/layouts/index.js +6 -0
  63. package/dist/layouts/index.js.map +1 -0
  64. package/dist/netron/index.d.ts +4 -0
  65. package/dist/netron/index.js +4 -0
  66. package/dist/netron/index.js.map +1 -0
  67. package/dist/registry/index.d.ts +352 -0
  68. package/dist/registry/index.js +4 -0
  69. package/dist/registry/index.js.map +1 -0
  70. package/dist/registry-BrDNftd5.d.ts +574 -0
  71. package/dist/settings-plpR26Xk.d.ts +455 -0
  72. package/dist/state/index.d.ts +981 -0
  73. package/dist/state/index.js +5 -0
  74. package/dist/state/index.js.map +1 -0
  75. package/dist/theme/index.d.ts +1049 -0
  76. package/dist/theme/index.js +5 -0
  77. package/dist/theme/index.js.map +1 -0
  78. package/dist/theme-CrXLfP1c.d.ts +389 -0
  79. package/dist/types/index.d.ts +146 -0
  80. package/dist/types/index.js +5 -0
  81. package/dist/types/index.js.map +1 -0
  82. package/dist/use-timeout-D7U3EAtH.d.ts +808 -0
  83. package/package.json +194 -0
@@ -0,0 +1,1409 @@
1
+ import { promises } from 'fs';
2
+ import * as path from 'path';
3
+
4
+ // src/registry/manager.ts
5
+ var RegistryManager = class {
6
+ options;
7
+ registries = /* @__PURE__ */ new Map();
8
+ cache = /* @__PURE__ */ new Map();
9
+ loaders = /* @__PURE__ */ new Map();
10
+ constructor(options = {}) {
11
+ this.options = {
12
+ baseDir: options.baseDir ?? (typeof process !== "undefined" && process.cwd ? process.cwd() : "/"),
13
+ defaultRegistry: options.defaultRegistry ?? "prism",
14
+ config: options.config ?? { default: "prism", registries: {} },
15
+ cacheTtl: options.cacheTtl ?? 5 * 60 * 1e3
16
+ // 5 minutes
17
+ };
18
+ }
19
+ // ===========================================================================
20
+ // REGISTRY LOADING
21
+ // ===========================================================================
22
+ /**
23
+ * Register a custom loader for a registry.
24
+ */
25
+ registerLoader(name, loader) {
26
+ this.loaders.set(name, loader);
27
+ }
28
+ /**
29
+ * Load a registry by name.
30
+ */
31
+ async loadRegistry(name) {
32
+ const cached = this.cache.get(name);
33
+ if (cached && Date.now() - cached.timestamp < this.options.cacheTtl) {
34
+ return cached.data;
35
+ }
36
+ const existing = this.registries.get(name);
37
+ if (existing && !cached) {
38
+ return existing;
39
+ }
40
+ const customLoader = this.loaders.get(name);
41
+ if (customLoader) {
42
+ const registry3 = await customLoader();
43
+ this.cacheRegistry(name, registry3);
44
+ return registry3;
45
+ }
46
+ const config = this.options.config.registries[name];
47
+ if (!config) {
48
+ throw new Error(`Registry "${name}" not found in configuration`);
49
+ }
50
+ const registry2 = typeof config === "string" ? await this.loadFromPath(config) : await this.loadFromRemote(config);
51
+ if (registry2.extends) {
52
+ const baseRegistry = await this.loadRegistry(registry2.extends);
53
+ const merged = this.mergeRegistries(baseRegistry, registry2);
54
+ this.cacheRegistry(name, merged);
55
+ return merged;
56
+ }
57
+ this.cacheRegistry(name, registry2);
58
+ return registry2;
59
+ }
60
+ /**
61
+ * Load registry from local file path.
62
+ * Uses dynamic import for ESM compatibility across environments.
63
+ *
64
+ * @param path - Relative or absolute path to registry JSON
65
+ * @returns Loaded registry schema
66
+ */
67
+ async loadFromPath(path2) {
68
+ const fullPath = path2.startsWith("/") ? path2 : `${this.options.baseDir}/${path2}`;
69
+ if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
70
+ const fs2 = await import('fs/promises');
71
+ const content = await fs2.readFile(fullPath, "utf-8");
72
+ return JSON.parse(content);
73
+ }
74
+ if (path2.startsWith("http://") || path2.startsWith("https://")) {
75
+ const response = await fetch(path2);
76
+ if (!response.ok) {
77
+ throw new Error(`Failed to load registry from ${path2}: ${response.statusText}`);
78
+ }
79
+ return response.json();
80
+ }
81
+ throw new Error(
82
+ `Cannot load local file "${fullPath}" in browser environment. Register a custom loader with manager.registerLoader() or use a remote URL.`
83
+ );
84
+ }
85
+ /**
86
+ * Load registry from remote URL.
87
+ */
88
+ async loadFromRemote(config) {
89
+ const response = await fetch(config.url, {
90
+ headers: config.headers
91
+ });
92
+ if (!response.ok) {
93
+ throw new Error(`Failed to load registry from ${config.url}: ${response.statusText}`);
94
+ }
95
+ return response.json();
96
+ }
97
+ /**
98
+ * Cache a loaded registry.
99
+ */
100
+ cacheRegistry(name, registry2) {
101
+ this.registries.set(name, registry2);
102
+ this.cache.set(name, {
103
+ data: registry2,
104
+ timestamp: Date.now()
105
+ });
106
+ }
107
+ /**
108
+ * Merge two registries (base + extension).
109
+ */
110
+ mergeRegistries(base, extension) {
111
+ return {
112
+ ...base,
113
+ ...extension,
114
+ components: { ...base.components, ...extension.components },
115
+ blocks: { ...base.blocks, ...extension.blocks },
116
+ themes: { ...base.themes, ...extension.themes }
117
+ };
118
+ }
119
+ /**
120
+ * Clear registry cache.
121
+ */
122
+ clearCache(name) {
123
+ if (name) {
124
+ this.cache.delete(name);
125
+ } else {
126
+ this.cache.clear();
127
+ }
128
+ }
129
+ // ===========================================================================
130
+ // COMPONENT OPERATIONS
131
+ // ===========================================================================
132
+ /**
133
+ * Get a component definition by name.
134
+ */
135
+ async getComponent(name, registryName) {
136
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
137
+ return registry2.components[name] ?? null;
138
+ }
139
+ /**
140
+ * Get all components from a registry.
141
+ */
142
+ async getComponents(registryName) {
143
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
144
+ return registry2.components;
145
+ }
146
+ /**
147
+ * Search for components.
148
+ */
149
+ async searchComponents(options, registryName) {
150
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
151
+ let results = Object.values(registry2.components);
152
+ if (options.category) {
153
+ results = results.filter((c) => c.category === options.category);
154
+ }
155
+ if (options.query) {
156
+ const query = options.query.toLowerCase();
157
+ results = results.filter(
158
+ (c) => c.name.toLowerCase().includes(query) || c.displayName?.toLowerCase().includes(query) || c.description?.toLowerCase().includes(query)
159
+ );
160
+ }
161
+ if (options.limit && options.limit > 0) {
162
+ results = results.slice(0, options.limit);
163
+ }
164
+ return results;
165
+ }
166
+ /**
167
+ * Get component categories.
168
+ */
169
+ async getComponentCategories(registryName) {
170
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
171
+ const categories = /* @__PURE__ */ new Set();
172
+ for (const component of Object.values(registry2.components)) {
173
+ categories.add(component.category);
174
+ }
175
+ return Array.from(categories).sort();
176
+ }
177
+ // ===========================================================================
178
+ // BLOCK OPERATIONS
179
+ // ===========================================================================
180
+ /**
181
+ * Get a block definition by name.
182
+ */
183
+ async getBlock(name, registryName) {
184
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
185
+ return registry2.blocks[name] ?? null;
186
+ }
187
+ /**
188
+ * Get all blocks from a registry.
189
+ */
190
+ async getBlocks(registryName) {
191
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
192
+ return registry2.blocks;
193
+ }
194
+ /**
195
+ * Search for blocks.
196
+ */
197
+ async searchBlocks(options, registryName) {
198
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
199
+ let results = Object.values(registry2.blocks);
200
+ if (options.category) {
201
+ results = results.filter((b) => b.category === options.category);
202
+ }
203
+ if (options.query) {
204
+ const query = options.query.toLowerCase();
205
+ results = results.filter(
206
+ (b) => b.name.toLowerCase().includes(query) || b.displayName?.toLowerCase().includes(query) || b.description?.toLowerCase().includes(query)
207
+ );
208
+ }
209
+ if (options.limit && options.limit > 0) {
210
+ results = results.slice(0, options.limit);
211
+ }
212
+ return results;
213
+ }
214
+ /**
215
+ * Get block categories.
216
+ */
217
+ async getBlockCategories(registryName) {
218
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
219
+ const categories = /* @__PURE__ */ new Set();
220
+ for (const block of Object.values(registry2.blocks)) {
221
+ categories.add(block.category);
222
+ }
223
+ return Array.from(categories).sort();
224
+ }
225
+ // ===========================================================================
226
+ // DEPENDENCY RESOLUTION
227
+ // ===========================================================================
228
+ /**
229
+ * Resolve all dependencies for a component.
230
+ */
231
+ async resolveComponentDependencies(name, registryName) {
232
+ const registry2 = registryName ?? this.options.defaultRegistry;
233
+ const component = await this.getComponent(name, registry2);
234
+ if (!component) {
235
+ throw new Error(`Component "${name}" not found in registry "${registry2}"`);
236
+ }
237
+ const dependencies = [];
238
+ for (const depName of component.dependencies.components) {
239
+ const resolved = await this.resolveComponentDependencies(depName, registry2);
240
+ dependencies.push(resolved);
241
+ }
242
+ return {
243
+ definition: component,
244
+ registry: registry2,
245
+ dependencies
246
+ };
247
+ }
248
+ /**
249
+ * Resolve all dependencies for a block.
250
+ */
251
+ async resolveBlockDependencies(name, registryName) {
252
+ const registry2 = registryName ?? this.options.defaultRegistry;
253
+ const block = await this.getBlock(name, registry2);
254
+ if (!block) {
255
+ throw new Error(`Block "${name}" not found in registry "${registry2}"`);
256
+ }
257
+ const dependencies = [];
258
+ for (const compName of block.dependencies.components) {
259
+ const resolved = await this.resolveComponentDependencies(compName, registry2);
260
+ dependencies.push(resolved);
261
+ }
262
+ for (const blockName of block.dependencies.blocks) {
263
+ const resolved = await this.resolveBlockDependencies(blockName, registry2);
264
+ dependencies.push(resolved);
265
+ }
266
+ return {
267
+ definition: block,
268
+ registry: registry2,
269
+ dependencies
270
+ };
271
+ }
272
+ /**
273
+ * Get flat list of all npm dependencies for resolved items.
274
+ */
275
+ getNpmDependencies(resolved) {
276
+ const deps = /* @__PURE__ */ new Set();
277
+ function collectDeps(item) {
278
+ const definition = item.definition;
279
+ if ("dependencies" in definition) {
280
+ for (const dep of definition.dependencies.npm) {
281
+ deps.add(dep);
282
+ }
283
+ }
284
+ for (const child of item.dependencies) {
285
+ collectDeps(child);
286
+ }
287
+ }
288
+ collectDeps(resolved);
289
+ return Array.from(deps).sort();
290
+ }
291
+ /**
292
+ * Get flat list of all file paths for resolved items.
293
+ */
294
+ getFilePaths(resolved) {
295
+ const paths = /* @__PURE__ */ new Set();
296
+ function collectPaths(item) {
297
+ const definition = item.definition;
298
+ for (const file of definition.files) {
299
+ paths.add(file.path);
300
+ }
301
+ for (const child of item.dependencies) {
302
+ collectPaths(child);
303
+ }
304
+ }
305
+ collectPaths(resolved);
306
+ return Array.from(paths).sort();
307
+ }
308
+ // ===========================================================================
309
+ // VERSION CHECKING
310
+ // ===========================================================================
311
+ /**
312
+ * Check if a component version is compatible.
313
+ */
314
+ async checkComponentVersion(name, requiredVersion, registryName) {
315
+ const component = await this.getComponent(name, registryName);
316
+ if (!component) return false;
317
+ return this.isVersionCompatible(component.version, requiredVersion);
318
+ }
319
+ /**
320
+ * Check semver version compatibility.
321
+ * Simple implementation - considers major.minor compatibility.
322
+ */
323
+ isVersionCompatible(actual, required) {
324
+ const [actualMajor, actualMinor] = actual.split(".").map(Number);
325
+ const [requiredMajor, requiredMinor] = required.split(".").map(Number);
326
+ if (actualMajor !== requiredMajor) return false;
327
+ return actualMinor >= requiredMinor;
328
+ }
329
+ // ===========================================================================
330
+ // REGISTRY INFO
331
+ // ===========================================================================
332
+ /**
333
+ * Get registry metadata.
334
+ */
335
+ async getRegistryInfo(registryName) {
336
+ const registry2 = await this.loadRegistry(registryName ?? this.options.defaultRegistry);
337
+ return {
338
+ name: registry2.name,
339
+ version: registry2.version,
340
+ description: registry2.description,
341
+ componentCount: Object.keys(registry2.components).length,
342
+ blockCount: Object.keys(registry2.blocks).length,
343
+ themeCount: Object.keys(registry2.themes).length
344
+ };
345
+ }
346
+ /**
347
+ * Get list of loaded registries.
348
+ */
349
+ getLoadedRegistries() {
350
+ return Array.from(this.registries.keys());
351
+ }
352
+ };
353
+ var registry = new RegistryManager();
354
+ function createRegistryManager(options) {
355
+ return new RegistryManager(options);
356
+ }
357
+ var PrismInstaller = class {
358
+ options;
359
+ registryManager;
360
+ lockfile = null;
361
+ lockfilePath;
362
+ constructor(registryManager, options = {}) {
363
+ this.registryManager = registryManager;
364
+ this.options = {
365
+ componentsDir: options.componentsDir ?? "src/components/prism",
366
+ blocksDir: options.blocksDir ?? "src/blocks",
367
+ hooksDir: options.hooksDir ?? "src/hooks",
368
+ overwrite: options.overwrite ?? false,
369
+ dryRun: options.dryRun ?? false,
370
+ skipDependencies: options.skipDependencies ?? false,
371
+ templateVars: options.templateVars ?? {}
372
+ };
373
+ this.lockfilePath = path.join(process.cwd(), "prism.lock.json");
374
+ }
375
+ // ===========================================================================
376
+ // COMPONENT INSTALLATION
377
+ // ===========================================================================
378
+ /**
379
+ * Install a component and its dependencies.
380
+ */
381
+ async installComponent(name, registryName) {
382
+ const result = {
383
+ success: false,
384
+ files: [],
385
+ npmDependencies: [],
386
+ errors: [],
387
+ warnings: []
388
+ };
389
+ try {
390
+ const resolved = await this.registryManager.resolveComponentDependencies(name, registryName);
391
+ const itemsToInstall = this.options.skipDependencies ? [resolved] : this.flattenDependencies(resolved);
392
+ await this.loadLockfile();
393
+ const existingComponents = new Set(Object.keys(this.lockfile?.components ?? {}));
394
+ const filteredItems = this.options.overwrite ? itemsToInstall : itemsToInstall.filter((item) => {
395
+ const def = item.definition;
396
+ if (existingComponents.has(def.name)) {
397
+ result.warnings.push(
398
+ `Component "${def.name}" is already installed, skipping (use --overwrite to replace)`
399
+ );
400
+ return false;
401
+ }
402
+ return true;
403
+ });
404
+ const operations = [];
405
+ const installedComponents = [];
406
+ for (const item of filteredItems) {
407
+ const component = item.definition;
408
+ const componentOps = await this.prepareComponentFiles(component, item.registry);
409
+ operations.push(...componentOps);
410
+ installedComponents.push({
411
+ name: component.name,
412
+ version: component.version,
413
+ registry: item.registry,
414
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
415
+ files: componentOps.filter((op) => op.type === "write").map((op) => op.path)
416
+ });
417
+ }
418
+ result.npmDependencies = this.registryManager.getNpmDependencies(resolved);
419
+ if (this.options.dryRun) {
420
+ result.files = operations.filter((op) => op.type === "write").map((op) => op.path);
421
+ result.success = true;
422
+ } else {
423
+ await this.executeOperations(operations);
424
+ result.files = operations.filter((op) => op.type === "write").map((op) => op.path);
425
+ for (const component of installedComponents) {
426
+ this.lockfile.components[component.name] = component;
427
+ }
428
+ await this.saveLockfile();
429
+ result.success = true;
430
+ }
431
+ } catch (error) {
432
+ result.errors.push(error instanceof Error ? error.message : String(error));
433
+ }
434
+ return result;
435
+ }
436
+ /**
437
+ * Prepare file operations for a component.
438
+ */
439
+ async prepareComponentFiles(component, _registry) {
440
+ const operations = [];
441
+ const componentDir = path.join(this.options.componentsDir, component.name);
442
+ operations.push({ type: "mkdir", path: componentDir });
443
+ for (const file of component.files) {
444
+ const targetPath = path.join(componentDir, path.basename(file.path));
445
+ const content = await this.fetchFileContent(file.path);
446
+ const processedContent = this.processTemplate(content);
447
+ operations.push({
448
+ type: "write",
449
+ path: targetPath,
450
+ content: processedContent
451
+ });
452
+ }
453
+ return operations;
454
+ }
455
+ // ===========================================================================
456
+ // BLOCK INSTALLATION
457
+ // ===========================================================================
458
+ /**
459
+ * Install a block and its dependencies.
460
+ */
461
+ async installBlock(name, registryName) {
462
+ const result = {
463
+ success: false,
464
+ files: [],
465
+ npmDependencies: [],
466
+ errors: [],
467
+ warnings: []
468
+ };
469
+ try {
470
+ const resolved = await this.registryManager.resolveBlockDependencies(name, registryName);
471
+ const allItems = this.options.skipDependencies ? [resolved] : this.flattenDependencies(resolved);
472
+ const blocks = allItems.filter((item) => {
473
+ const def = item.definition;
474
+ return "defaultConfig" in def && "dependencies" in def && "blocks" in def.dependencies;
475
+ });
476
+ const components = allItems.filter((item) => !blocks.includes(item));
477
+ await this.loadLockfile();
478
+ for (const item of components) {
479
+ const component = item.definition;
480
+ const existingComponent = this.lockfile?.components[component.name];
481
+ if (existingComponent && !this.options.overwrite) {
482
+ result.warnings.push(`Component "${component.name}" is already installed, skipping`);
483
+ continue;
484
+ }
485
+ const componentResult = await this.installComponent(component.name, item.registry);
486
+ result.files.push(...componentResult.files);
487
+ result.errors.push(...componentResult.errors);
488
+ result.warnings.push(...componentResult.warnings);
489
+ }
490
+ const operations = [];
491
+ const installedBlocks = [];
492
+ for (const item of blocks) {
493
+ const block = item.definition;
494
+ const existingBlock = this.lockfile?.blocks[block.name];
495
+ if (existingBlock && !this.options.overwrite) {
496
+ result.warnings.push(`Block "${block.name}" is already installed, skipping`);
497
+ continue;
498
+ }
499
+ const blockOps = await this.prepareBlockFiles(block, item.registry);
500
+ operations.push(...blockOps);
501
+ installedBlocks.push({
502
+ name: block.name,
503
+ version: block.version,
504
+ registry: item.registry,
505
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
506
+ files: blockOps.filter((op) => op.type === "write").map((op) => op.path),
507
+ config: block.defaultConfig
508
+ });
509
+ }
510
+ result.npmDependencies = this.registryManager.getNpmDependencies(resolved);
511
+ if (this.options.dryRun) {
512
+ result.files.push(...operations.filter((op) => op.type === "write").map((op) => op.path));
513
+ result.success = true;
514
+ } else {
515
+ await this.executeOperations(operations);
516
+ result.files.push(...operations.filter((op) => op.type === "write").map((op) => op.path));
517
+ for (const block of installedBlocks) {
518
+ this.lockfile.blocks[block.name] = block;
519
+ }
520
+ await this.saveLockfile();
521
+ result.success = true;
522
+ }
523
+ } catch (error) {
524
+ result.errors.push(error instanceof Error ? error.message : String(error));
525
+ }
526
+ return result;
527
+ }
528
+ /**
529
+ * Prepare file operations for a block.
530
+ */
531
+ async prepareBlockFiles(block, _registry) {
532
+ const operations = [];
533
+ const blockDir = path.join(this.options.blocksDir, block.name);
534
+ operations.push({ type: "mkdir", path: blockDir });
535
+ for (const file of block.files) {
536
+ const targetPath = path.join(blockDir, file.path);
537
+ const targetDir = path.dirname(targetPath);
538
+ if (targetDir !== blockDir) {
539
+ operations.push({ type: "mkdir", path: targetDir });
540
+ }
541
+ const content = await this.fetchFileContent(file.path);
542
+ const processedContent = this.processTemplate(content);
543
+ operations.push({
544
+ type: "write",
545
+ path: targetPath,
546
+ content: processedContent
547
+ });
548
+ }
549
+ return operations;
550
+ }
551
+ // ===========================================================================
552
+ // UNINSTALLATION
553
+ // ===========================================================================
554
+ /**
555
+ * Uninstall a component.
556
+ */
557
+ async uninstallComponent(name) {
558
+ const result = {
559
+ success: false,
560
+ files: [],
561
+ npmDependencies: [],
562
+ errors: [],
563
+ warnings: []
564
+ };
565
+ try {
566
+ await this.loadLockfile();
567
+ const installed = this.lockfile?.components[name];
568
+ if (!installed) {
569
+ result.errors.push(`Component "${name}" is not installed`);
570
+ return result;
571
+ }
572
+ const dependents = await this.findDependents(name, "component");
573
+ if (dependents.length > 0) {
574
+ result.errors.push(`Cannot uninstall "${name}" because it is used by: ${dependents.join(", ")}`);
575
+ return result;
576
+ }
577
+ if (!this.options.dryRun) {
578
+ for (const filePath of installed.files) {
579
+ await promises.unlink(filePath).catch(() => {
580
+ result.warnings.push(`Could not delete file: ${filePath}`);
581
+ });
582
+ }
583
+ const componentDir = path.dirname(installed.files[0]);
584
+ await promises.rmdir(componentDir).catch(() => {
585
+ });
586
+ delete this.lockfile.components[name];
587
+ await this.saveLockfile();
588
+ }
589
+ result.files = installed.files;
590
+ result.success = true;
591
+ } catch (error) {
592
+ result.errors.push(error instanceof Error ? error.message : String(error));
593
+ }
594
+ return result;
595
+ }
596
+ /**
597
+ * Uninstall a block.
598
+ */
599
+ async uninstallBlock(name) {
600
+ const result = {
601
+ success: false,
602
+ files: [],
603
+ npmDependencies: [],
604
+ errors: [],
605
+ warnings: []
606
+ };
607
+ try {
608
+ await this.loadLockfile();
609
+ const installed = this.lockfile?.blocks[name];
610
+ if (!installed) {
611
+ result.errors.push(`Block "${name}" is not installed`);
612
+ return result;
613
+ }
614
+ const dependents = await this.findDependents(name, "block");
615
+ if (dependents.length > 0) {
616
+ result.errors.push(`Cannot uninstall "${name}" because it is used by: ${dependents.join(", ")}`);
617
+ return result;
618
+ }
619
+ if (!this.options.dryRun) {
620
+ for (const filePath of installed.files) {
621
+ await promises.unlink(filePath).catch(() => {
622
+ result.warnings.push(`Could not delete file: ${filePath}`);
623
+ });
624
+ }
625
+ const blockDir = path.dirname(installed.files[0]);
626
+ await promises.rm(blockDir, { recursive: true }).catch(() => {
627
+ result.warnings.push(`Could not remove directory: ${blockDir}`);
628
+ });
629
+ delete this.lockfile.blocks[name];
630
+ await this.saveLockfile();
631
+ }
632
+ result.files = installed.files;
633
+ result.success = true;
634
+ } catch (error) {
635
+ result.errors.push(error instanceof Error ? error.message : String(error));
636
+ }
637
+ return result;
638
+ }
639
+ // ===========================================================================
640
+ // HELPERS
641
+ // ===========================================================================
642
+ /**
643
+ * Flatten dependency tree into unique list.
644
+ */
645
+ flattenDependencies(resolved) {
646
+ const seen = /* @__PURE__ */ new Set();
647
+ const result = [];
648
+ function traverse(item) {
649
+ const key = `${item.registry}:${item.definition.name}`;
650
+ if (seen.has(key)) return;
651
+ seen.add(key);
652
+ for (const dep of item.dependencies) {
653
+ traverse(dep);
654
+ }
655
+ result.push(item);
656
+ }
657
+ traverse(resolved);
658
+ return result;
659
+ }
660
+ /**
661
+ * Fetch file content from registry.
662
+ * Supports local files (prefixed with file:// or absolute paths) and remote URLs.
663
+ */
664
+ async fetchFileContent(filePath) {
665
+ if (filePath.startsWith("file://") || filePath.startsWith("/") || /^[a-zA-Z]:/.test(filePath)) {
666
+ const actualPath = filePath.replace("file://", "");
667
+ try {
668
+ const content = await promises.readFile(actualPath, "utf-8");
669
+ return content;
670
+ } catch (error) {
671
+ throw new Error(
672
+ `Failed to read local file "${actualPath}": ${error instanceof Error ? error.message : String(error)}`,
673
+ { cause: error }
674
+ );
675
+ }
676
+ }
677
+ if (!filePath.startsWith("http://") && !filePath.startsWith("https://")) {
678
+ const resolvedPath = path.resolve(process.cwd(), filePath);
679
+ try {
680
+ const content = await promises.readFile(resolvedPath, "utf-8");
681
+ return content;
682
+ } catch (error) {
683
+ throw new Error(
684
+ `Failed to read file "${resolvedPath}": ${error instanceof Error ? error.message : String(error)}`,
685
+ { cause: error }
686
+ );
687
+ }
688
+ }
689
+ try {
690
+ const response = await fetch(filePath);
691
+ if (!response.ok) {
692
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
693
+ }
694
+ return await response.text();
695
+ } catch (error) {
696
+ throw new Error(
697
+ `Failed to fetch remote file "${filePath}": ${error instanceof Error ? error.message : String(error)}`,
698
+ { cause: error }
699
+ );
700
+ }
701
+ }
702
+ /**
703
+ * Process template variables in content.
704
+ */
705
+ processTemplate(content) {
706
+ let result = content;
707
+ for (const [key, value] of Object.entries(this.options.templateVars)) {
708
+ result = result.replace(new RegExp(`{{${key}}}`, "g"), value);
709
+ }
710
+ return result;
711
+ }
712
+ /**
713
+ * Execute file operations.
714
+ */
715
+ async executeOperations(operations) {
716
+ const sorted = [...operations].sort((a, b) => {
717
+ if (a.type === "mkdir" && b.type !== "mkdir") return -1;
718
+ if (a.type !== "mkdir" && b.type === "mkdir") return 1;
719
+ return 0;
720
+ });
721
+ for (const op of sorted) {
722
+ if (op.type === "mkdir") {
723
+ await promises.mkdir(op.path, { recursive: true });
724
+ } else if (op.type === "write" && op.content !== void 0) {
725
+ if (!this.options.overwrite) {
726
+ try {
727
+ await promises.access(op.path);
728
+ continue;
729
+ } catch {
730
+ }
731
+ }
732
+ await promises.writeFile(op.path, op.content, "utf-8");
733
+ }
734
+ }
735
+ }
736
+ /**
737
+ * Find items that depend on a given component/block.
738
+ */
739
+ async findDependents(name, type) {
740
+ const dependents = [];
741
+ if (!this.lockfile) return dependents;
742
+ for (const [blockName, _block] of Object.entries(this.lockfile.blocks)) {
743
+ const blockDef = await this.registryManager.getBlock(blockName);
744
+ if (!blockDef) continue;
745
+ if (type === "component" && blockDef.dependencies.components.includes(name)) {
746
+ dependents.push(blockName);
747
+ }
748
+ if (type === "block" && blockDef.dependencies.blocks.includes(name)) {
749
+ dependents.push(blockName);
750
+ }
751
+ }
752
+ if (type === "component") {
753
+ for (const [compName, _comp] of Object.entries(this.lockfile.components)) {
754
+ const compDef = await this.registryManager.getComponent(compName);
755
+ if (!compDef) continue;
756
+ if (compDef.dependencies.components.includes(name)) {
757
+ dependents.push(compName);
758
+ }
759
+ }
760
+ }
761
+ return dependents;
762
+ }
763
+ // ===========================================================================
764
+ // LOCKFILE MANAGEMENT
765
+ // ===========================================================================
766
+ /**
767
+ * Load lockfile from disk.
768
+ */
769
+ async loadLockfile() {
770
+ if (this.lockfile) return;
771
+ try {
772
+ const content = await promises.readFile(this.lockfilePath, "utf-8");
773
+ this.lockfile = JSON.parse(content);
774
+ } catch {
775
+ this.lockfile = {
776
+ version: "1.0.0",
777
+ components: {},
778
+ blocks: {},
779
+ themes: []
780
+ };
781
+ }
782
+ }
783
+ /**
784
+ * Save lockfile to disk.
785
+ */
786
+ async saveLockfile() {
787
+ if (!this.lockfile) return;
788
+ await promises.writeFile(this.lockfilePath, JSON.stringify(this.lockfile, null, 2), "utf-8");
789
+ }
790
+ /**
791
+ * Get current lockfile.
792
+ */
793
+ async getLockfile() {
794
+ await this.loadLockfile();
795
+ return this.lockfile;
796
+ }
797
+ /**
798
+ * List installed components.
799
+ */
800
+ async listInstalled() {
801
+ await this.loadLockfile();
802
+ return {
803
+ components: Object.values(this.lockfile.components),
804
+ blocks: Object.values(this.lockfile.blocks)
805
+ };
806
+ }
807
+ };
808
+ function createInstaller(registryManager, options) {
809
+ return new PrismInstaller(registryManager, options);
810
+ }
811
+
812
+ // src/registry/index.ts
813
+ var defaultRegistrySchema = {
814
+ $schema: "https://prism.omnitron.dev/registry/v1/schema.json",
815
+ name: "prism",
816
+ version: "1.0.0",
817
+ description: "Official Prism Design System Registry",
818
+ baseUrl: "https://registry.prism.omnitron.dev",
819
+ components: {
820
+ // Input Components
821
+ button: {
822
+ name: "button",
823
+ version: "1.0.0",
824
+ category: "inputs",
825
+ displayName: "Button",
826
+ description: "Primary action button with multiple variants",
827
+ files: [
828
+ { path: "Button.tsx", type: "component" },
829
+ { path: "Button.types.ts", type: "types" },
830
+ { path: "index.ts", type: "barrel" }
831
+ ],
832
+ dependencies: {
833
+ npm: ["@mui/material"],
834
+ components: []
835
+ },
836
+ hasVariants: true,
837
+ docs: "https://docs.prism.omnitron.dev/components/button"
838
+ },
839
+ "icon-button": {
840
+ name: "icon-button",
841
+ version: "1.0.0",
842
+ category: "inputs",
843
+ displayName: "Icon Button",
844
+ description: "Compact button for icon-only actions",
845
+ files: [
846
+ { path: "IconButton.tsx", type: "component" },
847
+ { path: "index.ts", type: "barrel" }
848
+ ],
849
+ dependencies: {
850
+ npm: ["@mui/material"],
851
+ components: []
852
+ },
853
+ hasVariants: true
854
+ },
855
+ "text-field": {
856
+ name: "text-field",
857
+ version: "1.0.0",
858
+ category: "inputs",
859
+ displayName: "Text Field",
860
+ description: "Text input with label and helper text",
861
+ files: [
862
+ { path: "TextField.tsx", type: "component" },
863
+ { path: "TextField.types.ts", type: "types" },
864
+ { path: "index.ts", type: "barrel" }
865
+ ],
866
+ dependencies: {
867
+ npm: ["@mui/material"],
868
+ components: []
869
+ },
870
+ hasVariants: true
871
+ },
872
+ select: {
873
+ name: "select",
874
+ version: "1.0.0",
875
+ category: "inputs",
876
+ displayName: "Select",
877
+ description: "Dropdown selection component",
878
+ files: [
879
+ { path: "Select.tsx", type: "component" },
880
+ { path: "Select.types.ts", type: "types" },
881
+ { path: "index.ts", type: "barrel" }
882
+ ],
883
+ dependencies: {
884
+ npm: ["@mui/material"],
885
+ components: []
886
+ },
887
+ hasVariants: true
888
+ },
889
+ checkbox: {
890
+ name: "checkbox",
891
+ version: "1.0.0",
892
+ category: "inputs",
893
+ displayName: "Checkbox",
894
+ description: "Checkbox input for boolean values",
895
+ files: [
896
+ { path: "Checkbox.tsx", type: "component" },
897
+ { path: "index.ts", type: "barrel" }
898
+ ],
899
+ dependencies: {
900
+ npm: ["@mui/material"],
901
+ components: []
902
+ },
903
+ hasVariants: false
904
+ },
905
+ switch: {
906
+ name: "switch",
907
+ version: "1.0.0",
908
+ category: "inputs",
909
+ displayName: "Switch",
910
+ description: "Toggle switch for on/off states",
911
+ files: [
912
+ { path: "Switch.tsx", type: "component" },
913
+ { path: "index.ts", type: "barrel" }
914
+ ],
915
+ dependencies: {
916
+ npm: ["@mui/material"],
917
+ components: []
918
+ },
919
+ hasVariants: false
920
+ },
921
+ // Data Display
922
+ avatar: {
923
+ name: "avatar",
924
+ version: "1.0.0",
925
+ category: "data-display",
926
+ displayName: "Avatar",
927
+ description: "User avatar with image or initials",
928
+ files: [
929
+ { path: "Avatar.tsx", type: "component" },
930
+ { path: "AvatarGroup.tsx", type: "component" },
931
+ { path: "index.ts", type: "barrel" }
932
+ ],
933
+ dependencies: {
934
+ npm: ["@mui/material"],
935
+ components: []
936
+ },
937
+ hasVariants: true
938
+ },
939
+ badge: {
940
+ name: "badge",
941
+ version: "1.0.0",
942
+ category: "data-display",
943
+ displayName: "Badge",
944
+ description: "Badge for notifications and status",
945
+ files: [
946
+ { path: "Badge.tsx", type: "component" },
947
+ { path: "index.ts", type: "barrel" }
948
+ ],
949
+ dependencies: {
950
+ npm: ["@mui/material"],
951
+ components: []
952
+ },
953
+ hasVariants: true
954
+ },
955
+ chip: {
956
+ name: "chip",
957
+ version: "1.0.0",
958
+ category: "data-display",
959
+ displayName: "Chip",
960
+ description: "Compact element for tags and selections",
961
+ files: [
962
+ { path: "Chip.tsx", type: "component" },
963
+ { path: "index.ts", type: "barrel" }
964
+ ],
965
+ dependencies: {
966
+ npm: ["@mui/material"],
967
+ components: []
968
+ },
969
+ hasVariants: true
970
+ },
971
+ tooltip: {
972
+ name: "tooltip",
973
+ version: "1.0.0",
974
+ category: "data-display",
975
+ displayName: "Tooltip",
976
+ description: "Informative tooltip on hover",
977
+ files: [
978
+ { path: "Tooltip.tsx", type: "component" },
979
+ { path: "index.ts", type: "barrel" }
980
+ ],
981
+ dependencies: {
982
+ npm: ["@mui/material"],
983
+ components: []
984
+ },
985
+ hasVariants: false
986
+ },
987
+ // Feedback
988
+ alert: {
989
+ name: "alert",
990
+ version: "1.0.0",
991
+ category: "feedback",
992
+ displayName: "Alert",
993
+ description: "Alert messages with severity levels",
994
+ files: [
995
+ { path: "Alert.tsx", type: "component" },
996
+ { path: "index.ts", type: "barrel" }
997
+ ],
998
+ dependencies: {
999
+ npm: ["@mui/material"],
1000
+ components: []
1001
+ },
1002
+ hasVariants: true
1003
+ },
1004
+ snackbar: {
1005
+ name: "snackbar",
1006
+ version: "1.0.0",
1007
+ category: "feedback",
1008
+ displayName: "Snackbar",
1009
+ description: "Brief notification messages",
1010
+ files: [
1011
+ { path: "Snackbar.tsx", type: "component" },
1012
+ { path: "SnackbarProvider.tsx", type: "component" },
1013
+ { path: "useSnackbar.ts", type: "component" },
1014
+ { path: "index.ts", type: "barrel" }
1015
+ ],
1016
+ dependencies: {
1017
+ npm: ["@mui/material", "notistack"],
1018
+ components: []
1019
+ },
1020
+ hasVariants: false
1021
+ },
1022
+ dialog: {
1023
+ name: "dialog",
1024
+ version: "1.0.0",
1025
+ category: "feedback",
1026
+ displayName: "Dialog",
1027
+ description: "Modal dialog with actions",
1028
+ files: [
1029
+ { path: "Dialog.tsx", type: "component" },
1030
+ { path: "ConfirmDialog.tsx", type: "component" },
1031
+ { path: "index.ts", type: "barrel" }
1032
+ ],
1033
+ dependencies: {
1034
+ npm: ["@mui/material"],
1035
+ components: ["button"]
1036
+ },
1037
+ hasVariants: false
1038
+ },
1039
+ progress: {
1040
+ name: "progress",
1041
+ version: "1.0.0",
1042
+ category: "feedback",
1043
+ displayName: "Progress",
1044
+ description: "Progress indicators (linear and circular)",
1045
+ files: [
1046
+ { path: "LinearProgress.tsx", type: "component" },
1047
+ { path: "CircularProgress.tsx", type: "component" },
1048
+ { path: "index.ts", type: "barrel" }
1049
+ ],
1050
+ dependencies: {
1051
+ npm: ["@mui/material"],
1052
+ components: []
1053
+ },
1054
+ hasVariants: false
1055
+ },
1056
+ // Surfaces
1057
+ card: {
1058
+ name: "card",
1059
+ version: "1.0.0",
1060
+ category: "surfaces",
1061
+ displayName: "Card",
1062
+ description: "Content card with header, content, and actions",
1063
+ files: [
1064
+ { path: "Card.tsx", type: "component" },
1065
+ { path: "Card.types.ts", type: "types" },
1066
+ { path: "index.ts", type: "barrel" }
1067
+ ],
1068
+ dependencies: {
1069
+ npm: ["@mui/material"],
1070
+ components: []
1071
+ },
1072
+ hasVariants: true
1073
+ },
1074
+ paper: {
1075
+ name: "paper",
1076
+ version: "1.0.0",
1077
+ category: "surfaces",
1078
+ displayName: "Paper",
1079
+ description: "Basic surface with elevation",
1080
+ files: [
1081
+ { path: "Paper.tsx", type: "component" },
1082
+ { path: "index.ts", type: "barrel" }
1083
+ ],
1084
+ dependencies: {
1085
+ npm: ["@mui/material"],
1086
+ components: []
1087
+ },
1088
+ hasVariants: false
1089
+ },
1090
+ accordion: {
1091
+ name: "accordion",
1092
+ version: "1.0.0",
1093
+ category: "surfaces",
1094
+ displayName: "Accordion",
1095
+ description: "Expandable content panels",
1096
+ files: [
1097
+ { path: "Accordion.tsx", type: "component" },
1098
+ { path: "index.ts", type: "barrel" }
1099
+ ],
1100
+ dependencies: {
1101
+ npm: ["@mui/material"],
1102
+ components: []
1103
+ },
1104
+ hasVariants: false
1105
+ },
1106
+ // Navigation
1107
+ tabs: {
1108
+ name: "tabs",
1109
+ version: "1.0.0",
1110
+ category: "navigation",
1111
+ displayName: "Tabs",
1112
+ description: "Tabbed navigation component",
1113
+ files: [
1114
+ { path: "Tabs.tsx", type: "component" },
1115
+ { path: "TabPanel.tsx", type: "component" },
1116
+ { path: "index.ts", type: "barrel" }
1117
+ ],
1118
+ dependencies: {
1119
+ npm: ["@mui/material"],
1120
+ components: []
1121
+ },
1122
+ hasVariants: true
1123
+ },
1124
+ breadcrumbs: {
1125
+ name: "breadcrumbs",
1126
+ version: "1.0.0",
1127
+ category: "navigation",
1128
+ displayName: "Breadcrumbs",
1129
+ description: "Navigation breadcrumb trail",
1130
+ files: [
1131
+ { path: "Breadcrumbs.tsx", type: "component" },
1132
+ { path: "index.ts", type: "barrel" }
1133
+ ],
1134
+ dependencies: {
1135
+ npm: ["@mui/material"],
1136
+ components: []
1137
+ },
1138
+ hasVariants: false
1139
+ },
1140
+ menu: {
1141
+ name: "menu",
1142
+ version: "1.0.0",
1143
+ category: "navigation",
1144
+ displayName: "Menu",
1145
+ description: "Dropdown menu for actions",
1146
+ files: [
1147
+ { path: "Menu.tsx", type: "component" },
1148
+ { path: "MenuItem.tsx", type: "component" },
1149
+ { path: "index.ts", type: "barrel" }
1150
+ ],
1151
+ dependencies: {
1152
+ npm: ["@mui/material"],
1153
+ components: []
1154
+ },
1155
+ hasVariants: false
1156
+ },
1157
+ // Layout
1158
+ stack: {
1159
+ name: "stack",
1160
+ version: "1.0.0",
1161
+ category: "layout",
1162
+ displayName: "Stack",
1163
+ description: "Vertical/horizontal flex layout",
1164
+ files: [
1165
+ { path: "Stack.tsx", type: "component" },
1166
+ { path: "index.ts", type: "barrel" }
1167
+ ],
1168
+ dependencies: {
1169
+ npm: ["@mui/material"],
1170
+ components: []
1171
+ },
1172
+ hasVariants: false
1173
+ },
1174
+ grid: {
1175
+ name: "grid",
1176
+ version: "1.0.0",
1177
+ category: "layout",
1178
+ displayName: "Grid",
1179
+ description: "Responsive grid layout",
1180
+ files: [
1181
+ { path: "Grid.tsx", type: "component" },
1182
+ { path: "index.ts", type: "barrel" }
1183
+ ],
1184
+ dependencies: {
1185
+ npm: ["@mui/material"],
1186
+ components: []
1187
+ },
1188
+ hasVariants: false
1189
+ },
1190
+ container: {
1191
+ name: "container",
1192
+ version: "1.0.0",
1193
+ category: "layout",
1194
+ displayName: "Container",
1195
+ description: "Centered content container",
1196
+ files: [
1197
+ { path: "Container.tsx", type: "component" },
1198
+ { path: "index.ts", type: "barrel" }
1199
+ ],
1200
+ dependencies: {
1201
+ npm: ["@mui/material"],
1202
+ components: []
1203
+ },
1204
+ hasVariants: false
1205
+ },
1206
+ divider: {
1207
+ name: "divider",
1208
+ version: "1.0.0",
1209
+ category: "layout",
1210
+ displayName: "Divider",
1211
+ description: "Visual separator",
1212
+ files: [
1213
+ { path: "Divider.tsx", type: "component" },
1214
+ { path: "index.ts", type: "barrel" }
1215
+ ],
1216
+ dependencies: {
1217
+ npm: ["@mui/material"],
1218
+ components: []
1219
+ },
1220
+ hasVariants: false
1221
+ },
1222
+ // Data
1223
+ "data-table": {
1224
+ name: "data-table",
1225
+ version: "1.0.0",
1226
+ category: "data",
1227
+ displayName: "Data Table",
1228
+ description: "Full-featured data table with sorting, filtering, pagination",
1229
+ files: [
1230
+ { path: "DataTable.tsx", type: "component" },
1231
+ { path: "DataTable.types.ts", type: "types" },
1232
+ { path: "DataTableToolbar.tsx", type: "component" },
1233
+ { path: "DataTablePagination.tsx", type: "component" },
1234
+ { path: "index.ts", type: "barrel" }
1235
+ ],
1236
+ dependencies: {
1237
+ npm: ["@mui/material", "@tanstack/react-table"],
1238
+ components: ["button", "text-field", "select", "checkbox", "menu"]
1239
+ },
1240
+ hasVariants: true,
1241
+ docs: "https://docs.prism.omnitron.dev/components/data-table"
1242
+ },
1243
+ table: {
1244
+ name: "table",
1245
+ version: "1.0.0",
1246
+ category: "data",
1247
+ displayName: "Table",
1248
+ description: "Basic table component",
1249
+ files: [
1250
+ { path: "Table.tsx", type: "component" },
1251
+ { path: "index.ts", type: "barrel" }
1252
+ ],
1253
+ dependencies: {
1254
+ npm: ["@mui/material"],
1255
+ components: []
1256
+ },
1257
+ hasVariants: false
1258
+ },
1259
+ list: {
1260
+ name: "list",
1261
+ version: "1.0.0",
1262
+ category: "data",
1263
+ displayName: "List",
1264
+ description: "Vertical list of items",
1265
+ files: [
1266
+ { path: "List.tsx", type: "component" },
1267
+ { path: "ListItem.tsx", type: "component" },
1268
+ { path: "index.ts", type: "barrel" }
1269
+ ],
1270
+ dependencies: {
1271
+ npm: ["@mui/material"],
1272
+ components: []
1273
+ },
1274
+ hasVariants: false
1275
+ }
1276
+ },
1277
+ blocks: {
1278
+ // Dashboard blocks
1279
+ "dashboard-layout": {
1280
+ name: "dashboard-layout",
1281
+ version: "1.0.0",
1282
+ category: "layouts",
1283
+ displayName: "Dashboard Layout",
1284
+ description: "Complete dashboard layout with sidebar and header",
1285
+ files: [
1286
+ { path: "DashboardLayout.tsx", type: "component" },
1287
+ { path: "DashboardLayout.types.ts", type: "type" },
1288
+ { path: "Sidebar.tsx", type: "component" },
1289
+ { path: "Header.tsx", type: "component" },
1290
+ { path: "NavSection.tsx", type: "component" },
1291
+ { path: "NavItem.tsx", type: "component" },
1292
+ { path: "useDashboard.ts", type: "hook" },
1293
+ { path: "index.ts", type: "barrel" }
1294
+ ],
1295
+ dependencies: {
1296
+ npm: ["@mui/material", "framer-motion"],
1297
+ components: ["avatar", "menu", "icon-button", "tooltip"],
1298
+ blocks: []
1299
+ },
1300
+ defaultConfig: {
1301
+ sidebarWidth: 280,
1302
+ headerHeight: 64,
1303
+ collapsedWidth: 72
1304
+ },
1305
+ docs: "https://docs.prism.omnitron.dev/blocks/dashboard-layout"
1306
+ },
1307
+ "auth-forms": {
1308
+ name: "auth-forms",
1309
+ version: "1.0.0",
1310
+ category: "auth",
1311
+ displayName: "Authentication Forms",
1312
+ description: "Login, register, forgot password, and verify forms",
1313
+ files: [
1314
+ { path: "LoginForm.tsx", type: "component" },
1315
+ { path: "RegisterForm.tsx", type: "component" },
1316
+ { path: "ForgotPasswordForm.tsx", type: "component" },
1317
+ { path: "VerifyCodeForm.tsx", type: "component" },
1318
+ { path: "auth.schema.ts", type: "schema" },
1319
+ { path: "useAuthForm.ts", type: "hook" },
1320
+ { path: "index.ts", type: "barrel" }
1321
+ ],
1322
+ dependencies: {
1323
+ npm: ["@mui/material", "react-hook-form", "@hookform/resolvers", "zod"],
1324
+ components: ["button", "text-field", "checkbox", "alert"],
1325
+ blocks: []
1326
+ },
1327
+ defaultConfig: {
1328
+ showSocialLogin: true,
1329
+ showRememberMe: true
1330
+ }
1331
+ },
1332
+ "settings-panel": {
1333
+ name: "settings-panel",
1334
+ version: "1.0.0",
1335
+ category: "settings",
1336
+ displayName: "Settings Panel",
1337
+ description: "Theme settings panel with live preview",
1338
+ files: [
1339
+ { path: "SettingsPanel.tsx", type: "component" },
1340
+ { path: "SettingsDrawer.tsx", type: "component" },
1341
+ { path: "ThemePreview.tsx", type: "component" },
1342
+ { path: "useSettings.ts", type: "hook" },
1343
+ { path: "index.ts", type: "barrel" }
1344
+ ],
1345
+ dependencies: {
1346
+ npm: ["@mui/material", "framer-motion"],
1347
+ components: ["button", "switch", "select", "icon-button"],
1348
+ blocks: []
1349
+ },
1350
+ defaultConfig: {
1351
+ position: "right"
1352
+ }
1353
+ },
1354
+ "user-profile": {
1355
+ name: "user-profile",
1356
+ version: "1.0.0",
1357
+ category: "data",
1358
+ displayName: "User Profile",
1359
+ description: "User profile page with avatar, info, and settings",
1360
+ files: [
1361
+ { path: "ProfilePage.tsx", type: "component" },
1362
+ { path: "ProfileHeader.tsx", type: "component" },
1363
+ { path: "ProfileTabs.tsx", type: "component" },
1364
+ { path: "AccountTab.tsx", type: "component" },
1365
+ { path: "SecurityTab.tsx", type: "component" },
1366
+ { path: "NotificationsTab.tsx", type: "component" },
1367
+ { path: "useProfile.ts", type: "hook" },
1368
+ { path: "index.ts", type: "barrel" }
1369
+ ],
1370
+ dependencies: {
1371
+ npm: ["@mui/material", "react-hook-form"],
1372
+ components: ["avatar", "button", "tabs", "card", "text-field", "switch"],
1373
+ blocks: []
1374
+ },
1375
+ defaultConfig: {}
1376
+ },
1377
+ "data-grid": {
1378
+ name: "data-grid",
1379
+ version: "1.0.0",
1380
+ category: "data",
1381
+ displayName: "Data Grid",
1382
+ description: "Advanced data grid with server-side features",
1383
+ files: [
1384
+ { path: "DataGrid.tsx", type: "component" },
1385
+ { path: "DataGrid.types.ts", type: "type" },
1386
+ { path: "GridToolbar.tsx", type: "component" },
1387
+ { path: "GridFilters.tsx", type: "component" },
1388
+ { path: "GridExport.tsx", type: "component" },
1389
+ { path: "useDataGrid.ts", type: "hook" },
1390
+ { path: "index.ts", type: "barrel" }
1391
+ ],
1392
+ dependencies: {
1393
+ npm: ["@mui/material", "@tanstack/react-table", "@tanstack/react-virtual"],
1394
+ components: ["button", "text-field", "select", "checkbox", "menu", "chip"],
1395
+ blocks: []
1396
+ },
1397
+ defaultConfig: {
1398
+ pageSize: 25,
1399
+ enableColumnResize: true,
1400
+ enableColumnReorder: true
1401
+ }
1402
+ }
1403
+ },
1404
+ themes: {}
1405
+ };
1406
+
1407
+ export { PrismInstaller, RegistryManager, createInstaller, createRegistryManager, defaultRegistrySchema, registry };
1408
+ //# sourceMappingURL=chunk-BV32OJ2A.js.map
1409
+ //# sourceMappingURL=chunk-BV32OJ2A.js.map