@g3nomaly/ui 0.3.0 → 0.3.2

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 (92) hide show
  1. package/LICENSE +95 -0
  2. package/dist/cli/adapter.d.ts +86 -0
  3. package/dist/cli/adapter.d.ts.map +1 -0
  4. package/dist/cli/adapter.js +114 -0
  5. package/dist/cli/adapter.js.map +1 -0
  6. package/dist/cli/commands/add.d.ts +24 -0
  7. package/dist/cli/commands/add.d.ts.map +1 -0
  8. package/dist/cli/commands/add.js +24 -0
  9. package/dist/cli/commands/add.js.map +1 -0
  10. package/dist/cli/commands/index.d.ts +15 -0
  11. package/dist/cli/commands/index.d.ts.map +1 -0
  12. package/dist/cli/commands/index.js +9 -0
  13. package/dist/cli/commands/index.js.map +1 -0
  14. package/dist/cli/commands/init.d.ts +48 -0
  15. package/dist/cli/commands/init.d.ts.map +1 -0
  16. package/dist/cli/commands/init.js +167 -0
  17. package/dist/cli/commands/init.js.map +1 -0
  18. package/dist/cli/commands/ls.d.ts +20 -0
  19. package/dist/cli/commands/ls.d.ts.map +1 -0
  20. package/dist/cli/commands/ls.js +25 -0
  21. package/dist/cli/commands/ls.js.map +1 -0
  22. package/dist/cli/commands/manifest.d.ts +19 -0
  23. package/dist/cli/commands/manifest.d.ts.map +1 -0
  24. package/dist/cli/commands/manifest.js +95 -0
  25. package/dist/cli/commands/manifest.js.map +1 -0
  26. package/dist/cli/commands/remove.d.ts +15 -0
  27. package/dist/cli/commands/remove.d.ts.map +1 -0
  28. package/dist/cli/commands/remove.js +16 -0
  29. package/dist/cli/commands/remove.js.map +1 -0
  30. package/dist/cli/commands/source.d.ts +41 -0
  31. package/dist/cli/commands/source.d.ts.map +1 -0
  32. package/dist/cli/commands/source.js +38 -0
  33. package/dist/cli/commands/source.js.map +1 -0
  34. package/dist/cli/commands/update.d.ts +16 -0
  35. package/dist/cli/commands/update.d.ts.map +1 -0
  36. package/dist/cli/commands/update.js +17 -0
  37. package/dist/cli/commands/update.js.map +1 -0
  38. package/dist/cli/index.d.ts +3 -0
  39. package/dist/cli/index.d.ts.map +1 -0
  40. package/dist/cli/index.js +90 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/components/basic/Card.css +32 -0
  43. package/dist/components/basic/Card.debug.ts +5 -0
  44. package/dist/components/basic/Card.tsx +31 -0
  45. package/dist/components/basic/CardFooter.css +16 -0
  46. package/dist/components/basic/CardFooter.debug.ts +5 -0
  47. package/dist/components/basic/CardFooter.tsx +29 -0
  48. package/dist/components/basic/CardHeader.css +14 -0
  49. package/dist/components/basic/CardHeader.debug.ts +5 -0
  50. package/dist/components/basic/CardHeader.tsx +29 -0
  51. package/dist/components/basic/card.meta.ts +14 -0
  52. package/dist/components/basic/cardfooter.meta.ts +14 -0
  53. package/dist/components/basic/cardheader.meta.ts +14 -0
  54. package/dist/components/input/Button.css +34 -0
  55. package/dist/components/input/Button.debug.ts +5 -0
  56. package/dist/components/input/Button.tsx +28 -0
  57. package/dist/components/input/button.meta.ts +14 -0
  58. package/dist/components.json +138 -0
  59. package/dist/index.d.ts +2 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +3 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/registry/adapters/shadcn.adapter.d.ts +41 -0
  64. package/dist/registry/adapters/shadcn.adapter.d.ts.map +1 -0
  65. package/dist/registry/adapters/shadcn.adapter.js +123 -0
  66. package/dist/registry/adapters/shadcn.adapter.js.map +1 -0
  67. package/dist/registry/componentsJson.d.ts +24 -0
  68. package/dist/registry/componentsJson.d.ts.map +1 -0
  69. package/dist/registry/componentsJson.js +56 -0
  70. package/dist/registry/componentsJson.js.map +1 -0
  71. package/dist/registry/index.d.ts +6 -0
  72. package/dist/registry/index.d.ts.map +1 -0
  73. package/dist/registry/index.js +6 -0
  74. package/dist/registry/index.js.map +1 -0
  75. package/dist/registry/manifest.d.ts +21 -0
  76. package/dist/registry/manifest.d.ts.map +1 -0
  77. package/dist/registry/manifest.js +88 -0
  78. package/dist/registry/manifest.js.map +1 -0
  79. package/dist/registry/readSource.d.ts +37 -0
  80. package/dist/registry/readSource.d.ts.map +1 -0
  81. package/dist/registry/readSource.js +58 -0
  82. package/dist/registry/readSource.js.map +1 -0
  83. package/dist/registry/types.d.ts +100 -0
  84. package/dist/registry/types.d.ts.map +1 -0
  85. package/dist/registry/types.js +48 -0
  86. package/dist/registry/types.js.map +1 -0
  87. package/dist/sources/builtins.d.ts +8 -0
  88. package/dist/sources/builtins.d.ts.map +1 -0
  89. package/dist/sources/builtins.js +10 -0
  90. package/dist/sources/builtins.js.map +1 -0
  91. package/package.json +84 -3
  92. package/README.md +0 -3
@@ -0,0 +1,14 @@
1
+ // packages/ui/src/components/basic/cardfooter.meta.ts
2
+ import type { PackagedComponent } from "@g3nomaly/ui/types";
3
+
4
+ export default {
5
+ name: "CardFooter",
6
+ description: "Footer section for Card component.",
7
+ category: "basic",
8
+ files: [
9
+ { path: "basic/CardFooter.tsx", type: "component" },
10
+ { path: "basic/CardFooter.css", type: "style" },
11
+ { path: "basic/CardFooter.debug.ts", type: "util" },
12
+ ],
13
+ registryDependencies: ["card"],
14
+ } satisfies PackagedComponent;
@@ -0,0 +1,14 @@
1
+ // packages/ui/src/components/basic/cardheader.meta.ts
2
+ import type { PackagedComponent } from "@g3nomaly/ui/types";
3
+
4
+ export default {
5
+ name: "CardHeader",
6
+ description: "Header section for Card component.",
7
+ category: "basic",
8
+ files: [
9
+ { path: "basic/CardHeader.tsx", type: "component" },
10
+ { path: "basic/CardHeader.css", type: "style" },
11
+ { path: "basic/CardHeader.debug.ts", type: "util" },
12
+ ],
13
+ registryDependencies: ["card"],
14
+ } satisfies PackagedComponent;
@@ -0,0 +1,34 @@
1
+ .g3nui {
2
+ &.button {
3
+ display: inline-flex;
4
+ align-items: center;
5
+ justify-content: center;
6
+ padding: 0.5rem 1rem;
7
+ border-radius: 0.375rem;
8
+ font-weight: 500;
9
+ cursor: pointer;
10
+ transition: all 0.15s ease;
11
+ border: none;
12
+
13
+ &--primary {
14
+ background-color: #2563eb;
15
+ color: white;
16
+
17
+ &:hover { background-color: #1d4ed8; }
18
+ }
19
+
20
+ &--secondary {
21
+ background-color: #e5e7eb;
22
+ color: #111827;
23
+
24
+ &:hover { background-color: #d1d5db; }
25
+ }
26
+
27
+ &--ghost {
28
+ background-color: transparent;
29
+ color: #374151;
30
+
31
+ &:hover { background-color: #f3f4f6; }
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,5 @@
1
+ // packages/ui/src/components/input/Button.debug.ts
2
+ export const __debug = {
3
+ componentName: "Button",
4
+ version: "0.1.0",
5
+ };
@@ -0,0 +1,28 @@
1
+ // packages/ui/src/components/input/Button.tsx
2
+ import React from 'react';
3
+ import './Button.css';
4
+
5
+ /**
6
+ * @brief Props of Button: the native button attributes plus its look.
7
+ *
8
+ * @property variant - Look of the button: `primary` (default), `secondary` or `ghost`, set as the `button--<variant>` class.
9
+ */
10
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
11
+ variant?: 'primary' | 'secondary' | 'ghost';
12
+ }
13
+
14
+ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
15
+ ({ children, className = '', variant = 'primary', ...props }, ref) => {
16
+ return (
17
+ <button
18
+ ref={ref}
19
+ className={`g3nui button button--${variant} ${className}`}
20
+ {...props}
21
+ >
22
+ {children}
23
+ </button>
24
+ );
25
+ }
26
+ );
27
+
28
+ Button.displayName = 'Button';
@@ -0,0 +1,14 @@
1
+ // packages/ui/src/components/input/button.meta.ts
2
+ import type { PackagedComponent } from "@g3nomaly/ui/types";
3
+
4
+ export default {
5
+ name: "Button",
6
+ description: "A flexible button component.",
7
+ category: "input",
8
+ files: [
9
+ { path: "input/Button.tsx", type: "component" },
10
+ { path: "input/Button.css", type: "style" },
11
+ { path: "input/Button.debug.ts", type: "util" },
12
+ ],
13
+ registryDependencies: [],
14
+ } satisfies PackagedComponent;
@@ -0,0 +1,138 @@
1
+ {
2
+ "button": {
3
+ "name": "Button",
4
+ "description": "A flexible button component.",
5
+ "category": "input",
6
+ "registryDependencies": [],
7
+ "files": [
8
+ {
9
+ "path": "input/Button.tsx",
10
+ "type": "component",
11
+ "version": "0.3.2",
12
+ "hash": "4911cf7ade40890c2bc1ee9eba65b9297f33cc0c1287c550701780295ed16086"
13
+ },
14
+ {
15
+ "path": "input/Button.css",
16
+ "type": "style",
17
+ "version": "0.3.2",
18
+ "hash": "eaff21a3e7afa0e48210f146e6558df6997ff31fa8d239031ea110914d5ff208"
19
+ },
20
+ {
21
+ "path": "input/Button.debug.ts",
22
+ "type": "util",
23
+ "version": "0.3.2",
24
+ "hash": "f7be8d51584045a3dd712741922c9009fd1879db06915fcf1f11b9b4152d1441"
25
+ },
26
+ {
27
+ "path": "input/button.meta.ts",
28
+ "type": "meta",
29
+ "version": "0.3.2",
30
+ "hash": "51294b1c334186be2378259245c3a444b509328785f7ceee6d555ccc99ad05c6"
31
+ }
32
+ ],
33
+ "version": "0.3.2"
34
+ },
35
+ "card": {
36
+ "name": "Card",
37
+ "description": "A flexible card component.",
38
+ "category": "basic",
39
+ "registryDependencies": [],
40
+ "files": [
41
+ {
42
+ "path": "basic/Card.tsx",
43
+ "type": "component",
44
+ "version": "0.3.2",
45
+ "hash": "2602d00902b38c45d4a6409febe47bdb9e79657d83d7da3bc4dff3c7a3ebea6d"
46
+ },
47
+ {
48
+ "path": "basic/Card.css",
49
+ "type": "style",
50
+ "version": "0.3.2",
51
+ "hash": "5315468962112167dd37b4893e7d38404c19a7f2ba76bf51372bc30d67d5dc42"
52
+ },
53
+ {
54
+ "path": "basic/Card.debug.ts",
55
+ "type": "util",
56
+ "version": "0.3.2",
57
+ "hash": "acecf600200a49337f65714f0b2b4efc5325446b11fa49d5360f1aee88f1023f"
58
+ },
59
+ {
60
+ "path": "basic/card.meta.ts",
61
+ "type": "meta",
62
+ "version": "0.3.2",
63
+ "hash": "4ffcfd020601e222f26961ac595f478d6e8907ad894cdba992ea2b34a8ba6b92"
64
+ }
65
+ ],
66
+ "version": "0.3.2"
67
+ },
68
+ "cardfooter": {
69
+ "name": "CardFooter",
70
+ "description": "Footer section for Card component.",
71
+ "category": "basic",
72
+ "registryDependencies": [
73
+ "card"
74
+ ],
75
+ "files": [
76
+ {
77
+ "path": "basic/CardFooter.tsx",
78
+ "type": "component",
79
+ "version": "0.3.2",
80
+ "hash": "bfd4e73de6b16b529c22ca69e4661c30bd4be1237a5972eefce45cd6deb7dff5"
81
+ },
82
+ {
83
+ "path": "basic/CardFooter.css",
84
+ "type": "style",
85
+ "version": "0.3.2",
86
+ "hash": "751573c89dc46e83c9f240e58895f42652399f0519907c058568b14aaa52cb4d"
87
+ },
88
+ {
89
+ "path": "basic/CardFooter.debug.ts",
90
+ "type": "util",
91
+ "version": "0.3.2",
92
+ "hash": "3226f24e154a19daf4f0d9828245ff0cdf7b2e8bb75f10d785a33c1234578484"
93
+ },
94
+ {
95
+ "path": "basic/cardfooter.meta.ts",
96
+ "type": "meta",
97
+ "version": "0.3.2",
98
+ "hash": "1e9d82552826862ca25f13e71f80301b61fa8b9c3c8d0dc3ed51038db5b0f94c"
99
+ }
100
+ ],
101
+ "version": "0.3.2"
102
+ },
103
+ "cardheader": {
104
+ "name": "CardHeader",
105
+ "description": "Header section for Card component.",
106
+ "category": "basic",
107
+ "registryDependencies": [
108
+ "card"
109
+ ],
110
+ "files": [
111
+ {
112
+ "path": "basic/CardHeader.tsx",
113
+ "type": "component",
114
+ "version": "0.3.2",
115
+ "hash": "fac021c0f55b4c115b0b9fcc3e6f452aea7403e99b4b7a1287861de5653c9eb5"
116
+ },
117
+ {
118
+ "path": "basic/CardHeader.css",
119
+ "type": "style",
120
+ "version": "0.3.2",
121
+ "hash": "e36cf86636d2e7619dd69725faaedac9604a9605be11c0e2a6aa3663db8c3b53"
122
+ },
123
+ {
124
+ "path": "basic/CardHeader.debug.ts",
125
+ "type": "util",
126
+ "version": "0.3.2",
127
+ "hash": "e5879c6caebc2d14ffaf49b8d630a32a23c1c5a1c3877288d7ea4333e333c9e7"
128
+ },
129
+ {
130
+ "path": "basic/cardheader.meta.ts",
131
+ "type": "meta",
132
+ "version": "0.3.2",
133
+ "hash": "46d85bb6e00d8fa518548b89a89deb53c2e27304fc5f808f7e4cd5472a51871a"
134
+ }
135
+ ],
136
+ "version": "0.3.2"
137
+ }
138
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./registry/types";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ // packages/ui/src/index.ts
2
+ export * from "./registry/types";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { EntrySource } from "@g3nomaly/core/cli";
2
+ import type { ComponentFileType, ComponentMeta } from "../types";
3
+ /**
4
+ * @brief A single file returned by fetchShadcnComponentFiles().
5
+ *
6
+ * @property path - File path relative to the user's installDir, e.g. "shadcn/button.tsx".
7
+ * @property type - g3nui `ComponentFileType` the shadcn file type maps to.
8
+ */
9
+ export interface ShadcnFileContent {
10
+ path: string;
11
+ content: string;
12
+ type: ComponentFileType;
13
+ }
14
+ /**
15
+ * @brief Fetches the shadcn component index as entries keyed `@shadcn/<name>`,
16
+ * recorded under the `shadcn` source. Hashes are absent until install.
17
+ *
18
+ * @returns no entries and a warning when shadcn is not installed or the index cannot be fetched
19
+ */
20
+ export declare function readShadcnEntries(): Promise<{
21
+ entries: [string, ComponentMeta][];
22
+ warnings: string[];
23
+ }>;
24
+ /**
25
+ * @brief Fetches the file contents of one shadcn component through the installed
26
+ * shadcn package.
27
+ *
28
+ * @param name - Component name without the `@shadcn/` prefix, e.g. `button`.
29
+ * @returns Files with their contents; empty when the component is unknown or lists no files.
30
+ */
31
+ export declare function fetchShadcnComponentFiles(name: string): Promise<ShadcnFileContent[]>;
32
+ /**
33
+ * @brief Entry source that fetches shadcn components, one request per component,
34
+ * and writes each file from its content; entries of any other source go to
35
+ * `fallback`.
36
+ *
37
+ * @param fallback - Entry source for every entry of another source.
38
+ * @returns Entry source that serves shadcn entries and delegates the rest to `fallback`.
39
+ */
40
+ export declare function shadcnFileSource(fallback: EntrySource): EntrySource;
41
+ //# sourceMappingURL=shadcn.adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadcn.adapter.d.ts","sourceRoot":"","sources":["../../../src/registry/adapters/shadcn.adapter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAMjE;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAK,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAK,iBAAiB,CAAC;CAC5B;AAgED;;;;;GAKG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC;IAAE,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA6B7G;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAW1F;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,GAAG,WAAW,CAanE"}
@@ -0,0 +1,123 @@
1
+ // packages/ui/src/registry/adapters/shadcn.adapter.ts
2
+ import path from "node:path";
3
+ import { createRequire } from "node:module";
4
+ import { OriginEntrySchema } from "@g3nomaly/core/installer";
5
+ import { SHADCN_SOURCE } from "../manifest";
6
+ const require = createRequire(import.meta.url);
7
+ const SHADCN_INDEX_URL = "https://ui.shadcn.com/r/index.json";
8
+ /**
9
+ * @brief Root of the installed shadcn package.
10
+ *
11
+ * @returns Absolute folder of the package.
12
+ * @throws {Error} When shadcn is not installed.
13
+ */
14
+ function resolveShadcnRoot() {
15
+ return path.dirname(require.resolve("shadcn/package.json"));
16
+ }
17
+ /**
18
+ * @brief The g3nui file type for a shadcn registry file type.
19
+ *
20
+ * @param shadcnType - shadcn registry file type, e.g. `registry:ui`.
21
+ * @returns The g3nui `ComponentFileType`; `component` for any type not listed.
22
+ */
23
+ function mapShadcnType(shadcnType) {
24
+ if (shadcnType === "registry:ui")
25
+ return "component";
26
+ if (shadcnType === "registry:hook")
27
+ return "hook";
28
+ if (shadcnType === "registry:lib")
29
+ return "util";
30
+ if (shadcnType.includes("style") || shadcnType.includes("css"))
31
+ return "style";
32
+ return "component";
33
+ }
34
+ /**
35
+ * @brief Every shadcn file lands in `shadcn/<filename>`, whatever folder shadcn
36
+ * keeps it in: `ui/button.tsx` and `registry/new-york-v4/ui/button.tsx` both
37
+ * become `shadcn/button.tsx`.
38
+ *
39
+ * @param fullPath - Path as shadcn lists it, e.g. `registry/new-york-v4/ui/button.tsx`.
40
+ */
41
+ function normalizeFilePath(fullPath) {
42
+ const parts = fullPath.split("/");
43
+ return `shadcn/${parts[parts.length - 1]}`;
44
+ }
45
+ /**
46
+ * @brief Fetches the shadcn component index as entries keyed `@shadcn/<name>`,
47
+ * recorded under the `shadcn` source. Hashes are absent until install.
48
+ *
49
+ * @returns no entries and a warning when shadcn is not installed or the index cannot be fetched
50
+ */
51
+ export async function readShadcnEntries() {
52
+ try {
53
+ resolveShadcnRoot();
54
+ }
55
+ catch {
56
+ return { entries: [], warnings: ["shadcn is not installed: run `bun add shadcn@latest`"] };
57
+ }
58
+ let items;
59
+ try {
60
+ const res = await fetch(SHADCN_INDEX_URL);
61
+ if (!res.ok)
62
+ throw new Error(`HTTP ${res.status}`);
63
+ items = (await res.json());
64
+ }
65
+ catch (err) {
66
+ return { entries: [], warnings: [`the shadcn index could not be fetched: ${String(err)}`] };
67
+ }
68
+ const entries = [];
69
+ for (const item of items) {
70
+ if (!item.name || !item.files?.length)
71
+ continue;
72
+ entries.push([`@shadcn/${item.name.toLowerCase()}`, {
73
+ name: item.name,
74
+ description: item.description,
75
+ group: SHADCN_SOURCE,
76
+ origin: { source: SHADCN_SOURCE, dir: "" },
77
+ registryDependencies: (item.registryDependencies ?? []).map((dep) => `@shadcn/${dep.toLowerCase()}`),
78
+ files: item.files.map((f) => ({ path: normalizeFilePath(f.path), type: mapShadcnType(f.type) })),
79
+ }]);
80
+ }
81
+ return { entries, warnings: [] };
82
+ }
83
+ /**
84
+ * @brief Fetches the file contents of one shadcn component through the installed
85
+ * shadcn package.
86
+ *
87
+ * @param name - Component name without the `@shadcn/` prefix, e.g. `button`.
88
+ * @returns Files with their contents; empty when the component is unknown or lists no files.
89
+ */
90
+ export async function fetchShadcnComponentFiles(name) {
91
+ // Imported on use, so only commands that install shadcn components need the package.
92
+ const { getRegistryItems } = await import("shadcn/registry");
93
+ const items = await getRegistryItems([name]);
94
+ const item = items[0];
95
+ if (!item?.files?.length)
96
+ return [];
97
+ return item.files
98
+ .filter((f) => typeof f.content === "string")
99
+ .map((f) => ({ path: normalizeFilePath(f.path), content: f.content, type: mapShadcnType(f.type) }));
100
+ }
101
+ /**
102
+ * @brief Entry source that fetches shadcn components, one request per component,
103
+ * and writes each file from its content; entries of any other source go to
104
+ * `fallback`.
105
+ *
106
+ * @param fallback - Entry source for every entry of another source.
107
+ * @returns Entry source that serves shadcn entries and delegates the rest to `fallback`.
108
+ */
109
+ export function shadcnFileSource(fallback) {
110
+ return async (entry) => {
111
+ const { origin } = OriginEntrySchema.pick({ origin: true }).parse(entry);
112
+ if (origin.source !== SHADCN_SOURCE)
113
+ return fallback(entry);
114
+ const fetched = await fetchShadcnComponentFiles(entry.name.toLowerCase());
115
+ const contents = new Map(fetched.map((f) => [f.path, f.content]));
116
+ const source = (file) => {
117
+ const content = contents.get(file.path);
118
+ return content === undefined ? null : { kind: "write", content };
119
+ };
120
+ return source;
121
+ };
122
+ }
123
+ //# sourceMappingURL=shadcn.adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadcn.adapter.js","sourceRoot":"","sources":["../../../src/registry/adapters/shadcn.adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { PackagedComponent } from "./types";
2
+ /** Where a package keeps its built components and their registry, relative to the package root. */
3
+ export declare const COMPONENTS_DIR: string;
4
+ export declare const COMPONENTS_JSON: string;
5
+ /**
6
+ * @brief Builds `components.json` from every `*.meta.ts` under the built components
7
+ * folder: each component with its files hashed and stamped with the package
8
+ * version, the meta file itself included. Run by `packages/ui/scripts/build-registry.ts`.
9
+ *
10
+ * @param componentsDir - Absolute built components folder, e.g. `<package>/dist/components`
11
+ * @param outFile - Absolute path to write, e.g. `<package>/dist/components.json`
12
+ * @param version - Package version stamped on every component and file
13
+ * @returns how many components were written
14
+ */
15
+ export declare function writeComponentsJson(componentsDir: string, outFile: string, version: string): Promise<number>;
16
+ /**
17
+ * @brief Reads a package's `components.json`, keyed by lowercase component key.
18
+ *
19
+ * @param packageRoot - Absolute folder holding `dist/components.json`, e.g. `<package>`.
20
+ * @returns Components by lowercase key.
21
+ * @throws {Error} naming the file when it is missing, not JSON, or does not match the schema
22
+ */
23
+ export declare function readComponentsJson(packageRoot: string): Record<string, PackagedComponent>;
24
+ //# sourceMappingURL=componentsJson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentsJson.d.ts","sourceRoot":"","sources":["../../src/registry/componentsJson.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,mGAAmG;AACnG,eAAO,MAAM,cAAc,QAAmC,CAAC;AAC/D,eAAO,MAAM,eAAe,QAAuC,CAAC;AAIpE;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBlH;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAMzF"}
@@ -0,0 +1,56 @@
1
+ // packages/ui/src/registry/componentsJson.ts
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { glob } from "glob";
5
+ import { z } from "zod";
6
+ import { createRegistryStore, jsonHandler, register, writeTo } from "@g3nomaly/core/registry";
7
+ import { hashFile } from "@g3nomaly/core/hash";
8
+ import { getSafeObject } from "@g3nomaly/core/security";
9
+ import { PackagedComponentSchema } from "./types";
10
+ /** Where a package keeps its built components and their registry, relative to the package root. */
11
+ export const COMPONENTS_DIR = path.join("dist", "components");
12
+ export const COMPONENTS_JSON = path.join("dist", "components.json");
13
+ const ComponentsJsonSchema = z.record(z.string(), PackagedComponentSchema);
14
+ /**
15
+ * @brief Builds `components.json` from every `*.meta.ts` under the built components
16
+ * folder: each component with its files hashed and stamped with the package
17
+ * version, the meta file itself included. Run by `packages/ui/scripts/build-registry.ts`.
18
+ *
19
+ * @param componentsDir - Absolute built components folder, e.g. `<package>/dist/components`
20
+ * @param outFile - Absolute path to write, e.g. `<package>/dist/components.json`
21
+ * @param version - Package version stamped on every component and file
22
+ * @returns how many components were written
23
+ */
24
+ export async function writeComponentsJson(componentsDir, outFile, version) {
25
+ const store = createRegistryStore();
26
+ const metaFiles = await glob("**/*.meta.ts", { cwd: componentsDir, absolute: true });
27
+ for (const metaFile of metaFiles.sort()) {
28
+ const meta = await getSafeObject(metaFile, PackagedComponentSchema);
29
+ const files = [...meta.files, { path: path.relative(componentsDir, metaFile), type: "meta" }];
30
+ const hashed = await Promise.all(files.map(async (file) => ({
31
+ ...file,
32
+ version,
33
+ hash: await hashFile(path.join(componentsDir, file.path)),
34
+ })));
35
+ register(store, meta.name.toLowerCase(), { ...meta, version, files: hashed });
36
+ }
37
+ writeTo(store, outFile, jsonHandler);
38
+ return Object.keys(store.store.state).length;
39
+ }
40
+ /**
41
+ * @brief Reads a package's `components.json`, keyed by lowercase component key.
42
+ *
43
+ * @param packageRoot - Absolute folder holding `dist/components.json`, e.g. `<package>`.
44
+ * @returns Components by lowercase key.
45
+ * @throws {Error} naming the file when it is missing, not JSON, or does not match the schema
46
+ */
47
+ export function readComponentsJson(packageRoot) {
48
+ const file = path.join(packageRoot, COMPONENTS_JSON);
49
+ if (!fs.existsSync(file))
50
+ throw new Error(`${file} is missing: run \`bun run build\` in the package to create it`);
51
+ const parsed = ComponentsJsonSchema.safeParse(JSON.parse(fs.readFileSync(file, "utf8")));
52
+ if (!parsed.success)
53
+ throw new Error(`${file} is not a valid components.json:\n${z.prettifyError(parsed.error)}`);
54
+ return Object.fromEntries(Object.entries(parsed.data).map(([key, meta]) => [key.toLowerCase(), meta]));
55
+ }
56
+ //# sourceMappingURL=componentsJson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"componentsJson.js","sourceRoot":"","sources":["../../src/registry/componentsJson.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAGlD,mGAAmG;AACnG,MAAM,CAAC,MAAM,cAAc,GAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAEpE,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC;AAE3E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,aAAqB,EAAE,OAAe,EAAE,OAAe;IAC/F,MAAM,KAAK,GAAO,mBAAmB,EAAqB,CAAC;IAC3D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAErF,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,GAAI,MAAM,aAAa,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,CAAC,CAAC;QACvG,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YAC1D,GAAG,IAAI;YACP,OAAO;YACP,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;SAC1D,CAAC,CAAC,CAAC,CAAC;QACL,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;AAC/C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IACrD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,gEAAgE,CAAC,CAAC;IACnH,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACzF,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,qCAAqC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClH,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACzG,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from "./types";
2
+ export { COMPONENTS_DIR, COMPONENTS_JSON, readComponentsJson, writeComponentsJson } from "./componentsJson";
3
+ export { readComponentSource, filterFiles, groupOf } from "./readSource";
4
+ export type { ComponentFileFlags } from "./readSource";
5
+ export { uiManifestPath, migrateLegacyManifest, SHADCN_SOURCE } from "./manifest";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ // packages/ui/src/registry/index.ts
2
+ export * from "./types";
3
+ export { COMPONENTS_DIR, COMPONENTS_JSON, readComponentsJson, writeComponentsJson } from "./componentsJson";
4
+ export { readComponentSource, filterFiles, groupOf } from "./readSource";
5
+ export { uiManifestPath, migrateLegacyManifest, SHADCN_SOURCE } from "./manifest";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,21 @@
1
+ /** Source name shadcn components are recorded under. */
2
+ export declare const SHADCN_SOURCE = "shadcn";
3
+ /**
4
+ * @brief Path of the project's g3nui manifest.
5
+ *
6
+ * @param projectRoot - Absolute project root, e.g. `/home/me/app`.
7
+ * @returns absolute path, e.g. `/home/me/app/.g3n/.g3nui-manifest.json`
8
+ */
9
+ export declare function uiManifestPath(projectRoot: string): string;
10
+ /**
11
+ * @brief Rewrites a manifest from before the shared `{ sources, entries }` shape:
12
+ * a flat `.g3nui-manifest.json`, or a `.g3nui-manifest.ts` whose `registry`
13
+ * export becomes the JSON file and is then deleted. Does nothing when the
14
+ * manifest is already in the shared shape or does not exist.
15
+ *
16
+ * @param projectRoot - Absolute project root, e.g. `/home/me/app`.
17
+ * @returns the path that was migrated, or `null` when nothing changed
18
+ * @throws {Error} When a legacy manifest does not match the old entry shape.
19
+ */
20
+ export declare function migrateLegacyManifest(projectRoot: string): Promise<string | null>;
21
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/registry/manifest.ts"],"names":[],"mappings":"AAYA,wDAAwD;AACxD,eAAO,MAAM,aAAa,WAAW,CAAC;AAetC;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AA8BD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkBvF"}