@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.
- package/LICENSE +21 -0
- package/README.md +44 -0
- package/bin/prism.js +13 -0
- package/dist/accessibility/index.d.ts +157 -0
- package/dist/accessibility/index.js +186 -0
- package/dist/accessibility/index.js.map +1 -0
- package/dist/blocks/index.d.ts +1239 -0
- package/dist/blocks/index.js +1712 -0
- package/dist/blocks/index.js.map +1 -0
- package/dist/chunk-77KIJLPP.js +37 -0
- package/dist/chunk-77KIJLPP.js.map +1 -0
- package/dist/chunk-BTIT7WYH.js +339 -0
- package/dist/chunk-BTIT7WYH.js.map +1 -0
- package/dist/chunk-BV32OJ2A.js +1409 -0
- package/dist/chunk-BV32OJ2A.js.map +1 -0
- package/dist/chunk-DDY7TLUI.js +139 -0
- package/dist/chunk-DDY7TLUI.js.map +1 -0
- package/dist/chunk-DXXZ3ITR.js +4227 -0
- package/dist/chunk-DXXZ3ITR.js.map +1 -0
- package/dist/chunk-E3XANPTO.js +2319 -0
- package/dist/chunk-E3XANPTO.js.map +1 -0
- package/dist/chunk-FU52GL2E.js +3 -0
- package/dist/chunk-FU52GL2E.js.map +1 -0
- package/dist/chunk-GYDT5EKX.js +16505 -0
- package/dist/chunk-GYDT5EKX.js.map +1 -0
- package/dist/chunk-HO2GKTWJ.js +28 -0
- package/dist/chunk-HO2GKTWJ.js.map +1 -0
- package/dist/chunk-JDTC2SBY.js +140 -0
- package/dist/chunk-JDTC2SBY.js.map +1 -0
- package/dist/chunk-JNU4QHJK.js +6 -0
- package/dist/chunk-JNU4QHJK.js.map +1 -0
- package/dist/chunk-LAEY5USO.js +2621 -0
- package/dist/chunk-LAEY5USO.js.map +1 -0
- package/dist/chunk-UR6X3W5I.js +530 -0
- package/dist/chunk-UR6X3W5I.js.map +1 -0
- package/dist/chunk-WC2WM2JD.js +883 -0
- package/dist/chunk-WC2WM2JD.js.map +1 -0
- package/dist/chunk-XWL6J6IO.js +40 -0
- package/dist/chunk-XWL6J6IO.js.map +1 -0
- package/dist/cli/index.js +2695 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config-BA6IeTq9.d.ts +100 -0
- package/dist/core/index.d.ts +454 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/forms/index.d.ts +562 -0
- package/dist/forms/index.js +545 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.js +10 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/http/index.d.ts +233 -0
- package/dist/http/index.js +282 -0
- package/dist/http/index.js.map +1 -0
- package/dist/index-odhPSv9I.d.ts +2491 -0
- package/dist/index.css +131 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +9109 -0
- package/dist/index.js +13280 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts/index.d.ts +854 -0
- package/dist/layouts/index.js +6 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/netron/index.d.ts +4 -0
- package/dist/netron/index.js +4 -0
- package/dist/netron/index.js.map +1 -0
- package/dist/registry/index.d.ts +352 -0
- package/dist/registry/index.js +4 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry-BrDNftd5.d.ts +574 -0
- package/dist/settings-plpR26Xk.d.ts +455 -0
- package/dist/state/index.d.ts +981 -0
- package/dist/state/index.js +5 -0
- package/dist/state/index.js.map +1 -0
- package/dist/theme/index.d.ts +1049 -0
- package/dist/theme/index.js +5 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme-CrXLfP1c.d.ts +389 -0
- package/dist/types/index.d.ts +146 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/use-timeout-D7U3EAtH.d.ts +808 -0
- 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
|