stera-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,32 @@
1
+ import { RegistryItem } from '../schema/index.js';
2
+ import 'zod';
3
+
4
+ interface RegistryIndexItem {
5
+ name: string;
6
+ type: string;
7
+ dependencies?: string[];
8
+ registryDependencies?: string[];
9
+ }
10
+ /**
11
+ * Fetch the registry index (component list without file contents).
12
+ */
13
+ declare function fetchRegistryIndex(): Promise<RegistryIndexItem[]>;
14
+ /**
15
+ * Fetch a single registry item with its file contents.
16
+ */
17
+ declare function fetchRegistryItem(name: string): Promise<RegistryItem>;
18
+ /**
19
+ * Get a component from the registry index (no file contents).
20
+ */
21
+ declare function getComponent(name: string): Promise<RegistryIndexItem | undefined>;
22
+ /**
23
+ * Get all components from the registry index.
24
+ */
25
+ declare function getAllComponents(): Promise<RegistryIndexItem[]>;
26
+ /**
27
+ * Resolve all dependencies for the given component names.
28
+ * Fetches full registry items (with file contents) for each.
29
+ */
30
+ declare function resolveDependencies(names: string[]): Promise<RegistryItem[]>;
31
+
32
+ export { RegistryItem, fetchRegistryIndex, fetchRegistryItem, getAllComponents, getComponent, resolveDependencies };
@@ -0,0 +1,59 @@
1
+ // src/registry/index.ts
2
+ var REGISTRY_URL = process.env.REGISTRY_URL ?? "https://ui.stera.site/r";
3
+ var _indexCache = null;
4
+ async function fetchJSON(url) {
5
+ const res = await fetch(url);
6
+ if (!res.ok) {
7
+ throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
8
+ }
9
+ return res.json();
10
+ }
11
+ async function fetchRegistryIndex() {
12
+ if (_indexCache) return _indexCache;
13
+ const data = await fetchJSON(
14
+ `${REGISTRY_URL}/index.json`
15
+ );
16
+ _indexCache = data.items;
17
+ return _indexCache;
18
+ }
19
+ async function fetchRegistryItem(name) {
20
+ return fetchJSON(`${REGISTRY_URL}/${name}.json`);
21
+ }
22
+ async function getComponent(name) {
23
+ const index = await fetchRegistryIndex();
24
+ return index.find((item) => item.name === name);
25
+ }
26
+ async function getAllComponents() {
27
+ return fetchRegistryIndex();
28
+ }
29
+ async function resolveDependencies(names) {
30
+ const resolved = /* @__PURE__ */ new Map();
31
+ const queue = [...names];
32
+ while (queue.length > 0) {
33
+ const name = queue.shift();
34
+ if (resolved.has(name)) continue;
35
+ let item;
36
+ try {
37
+ item = await fetchRegistryItem(name);
38
+ } catch {
39
+ console.error(`Component "${name}" not found in registry.`);
40
+ process.exit(1);
41
+ }
42
+ resolved.set(name, item);
43
+ if (item.registryDependencies) {
44
+ for (const dep of item.registryDependencies) {
45
+ if (!resolved.has(dep)) {
46
+ queue.push(dep);
47
+ }
48
+ }
49
+ }
50
+ }
51
+ return Array.from(resolved.values());
52
+ }
53
+ export {
54
+ fetchRegistryIndex,
55
+ fetchRegistryItem,
56
+ getAllComponents,
57
+ getComponent,
58
+ resolveDependencies
59
+ };
@@ -0,0 +1,191 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const registryItemTypeSchema: z.ZodEnum<["registry:ui", "registry:component", "registry:hook", "registry:lib", "registry:style"]>;
4
+ type RegistryItemType = z.infer<typeof registryItemTypeSchema>;
5
+ declare const registryItemFileSchema: z.ZodObject<{
6
+ path: z.ZodString;
7
+ type: z.ZodEnum<["registry:ui", "registry:component", "registry:hook", "registry:lib", "registry:style"]>;
8
+ content: z.ZodOptional<z.ZodString>;
9
+ target: z.ZodOptional<z.ZodString>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
12
+ path: string;
13
+ content?: string | undefined;
14
+ target?: string | undefined;
15
+ }, {
16
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
17
+ path: string;
18
+ content?: string | undefined;
19
+ target?: string | undefined;
20
+ }>;
21
+ type RegistryItemFile = z.infer<typeof registryItemFileSchema>;
22
+ declare const registryItemSchema: z.ZodObject<{
23
+ name: z.ZodString;
24
+ type: z.ZodEnum<["registry:ui", "registry:component", "registry:hook", "registry:lib", "registry:style"]>;
25
+ dependencies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
26
+ registryDependencies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
27
+ files: z.ZodArray<z.ZodObject<{
28
+ path: z.ZodString;
29
+ type: z.ZodEnum<["registry:ui", "registry:component", "registry:hook", "registry:lib", "registry:style"]>;
30
+ content: z.ZodOptional<z.ZodString>;
31
+ target: z.ZodOptional<z.ZodString>;
32
+ }, "strip", z.ZodTypeAny, {
33
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
34
+ path: string;
35
+ content?: string | undefined;
36
+ target?: string | undefined;
37
+ }, {
38
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
39
+ path: string;
40
+ content?: string | undefined;
41
+ target?: string | undefined;
42
+ }>, "many">;
43
+ }, "strip", z.ZodTypeAny, {
44
+ name: string;
45
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
46
+ files: {
47
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
48
+ path: string;
49
+ content?: string | undefined;
50
+ target?: string | undefined;
51
+ }[];
52
+ dependencies?: string[] | undefined;
53
+ registryDependencies?: string[] | undefined;
54
+ }, {
55
+ name: string;
56
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
57
+ files: {
58
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
59
+ path: string;
60
+ content?: string | undefined;
61
+ target?: string | undefined;
62
+ }[];
63
+ dependencies?: string[] | undefined;
64
+ registryDependencies?: string[] | undefined;
65
+ }>;
66
+ type RegistryItem = z.infer<typeof registryItemSchema>;
67
+ declare const registryIndexSchema: z.ZodObject<{
68
+ name: z.ZodString;
69
+ items: z.ZodArray<z.ZodObject<{
70
+ name: z.ZodString;
71
+ type: z.ZodEnum<["registry:ui", "registry:component", "registry:hook", "registry:lib", "registry:style"]>;
72
+ dependencies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
73
+ registryDependencies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
74
+ files: z.ZodArray<z.ZodObject<{
75
+ path: z.ZodString;
76
+ type: z.ZodEnum<["registry:ui", "registry:component", "registry:hook", "registry:lib", "registry:style"]>;
77
+ content: z.ZodOptional<z.ZodString>;
78
+ target: z.ZodOptional<z.ZodString>;
79
+ }, "strip", z.ZodTypeAny, {
80
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
81
+ path: string;
82
+ content?: string | undefined;
83
+ target?: string | undefined;
84
+ }, {
85
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
86
+ path: string;
87
+ content?: string | undefined;
88
+ target?: string | undefined;
89
+ }>, "many">;
90
+ }, "strip", z.ZodTypeAny, {
91
+ name: string;
92
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
93
+ files: {
94
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
95
+ path: string;
96
+ content?: string | undefined;
97
+ target?: string | undefined;
98
+ }[];
99
+ dependencies?: string[] | undefined;
100
+ registryDependencies?: string[] | undefined;
101
+ }, {
102
+ name: string;
103
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
104
+ files: {
105
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
106
+ path: string;
107
+ content?: string | undefined;
108
+ target?: string | undefined;
109
+ }[];
110
+ dependencies?: string[] | undefined;
111
+ registryDependencies?: string[] | undefined;
112
+ }>, "many">;
113
+ }, "strip", z.ZodTypeAny, {
114
+ name: string;
115
+ items: {
116
+ name: string;
117
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
118
+ files: {
119
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
120
+ path: string;
121
+ content?: string | undefined;
122
+ target?: string | undefined;
123
+ }[];
124
+ dependencies?: string[] | undefined;
125
+ registryDependencies?: string[] | undefined;
126
+ }[];
127
+ }, {
128
+ name: string;
129
+ items: {
130
+ name: string;
131
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
132
+ files: {
133
+ type: "registry:ui" | "registry:component" | "registry:hook" | "registry:lib" | "registry:style";
134
+ path: string;
135
+ content?: string | undefined;
136
+ target?: string | undefined;
137
+ }[];
138
+ dependencies?: string[] | undefined;
139
+ registryDependencies?: string[] | undefined;
140
+ }[];
141
+ }>;
142
+ type RegistryIndex = z.infer<typeof registryIndexSchema>;
143
+ declare const configSchema: z.ZodObject<{
144
+ $schema: z.ZodOptional<z.ZodString>;
145
+ version: z.ZodLiteral<1>;
146
+ css: z.ZodString;
147
+ aliases: z.ZodObject<{
148
+ components: z.ZodString;
149
+ utils: z.ZodString;
150
+ ui: z.ZodString;
151
+ lib: z.ZodString;
152
+ hooks: z.ZodString;
153
+ }, "strip", z.ZodTypeAny, {
154
+ components: string;
155
+ utils: string;
156
+ ui: string;
157
+ lib: string;
158
+ hooks: string;
159
+ }, {
160
+ components: string;
161
+ utils: string;
162
+ ui: string;
163
+ lib: string;
164
+ hooks: string;
165
+ }>;
166
+ }, "strip", z.ZodTypeAny, {
167
+ version: 1;
168
+ css: string;
169
+ aliases: {
170
+ components: string;
171
+ utils: string;
172
+ ui: string;
173
+ lib: string;
174
+ hooks: string;
175
+ };
176
+ $schema?: string | undefined;
177
+ }, {
178
+ version: 1;
179
+ css: string;
180
+ aliases: {
181
+ components: string;
182
+ utils: string;
183
+ ui: string;
184
+ lib: string;
185
+ hooks: string;
186
+ };
187
+ $schema?: string | undefined;
188
+ }>;
189
+ type SteraConfig = z.infer<typeof configSchema>;
190
+
191
+ export { type RegistryIndex, type RegistryItem, type RegistryItemFile, type RegistryItemType, type SteraConfig, configSchema, registryIndexSchema, registryItemFileSchema, registryItemSchema, registryItemTypeSchema };
@@ -0,0 +1,45 @@
1
+ // src/schema/index.ts
2
+ import { z } from "zod";
3
+ var registryItemTypeSchema = z.enum([
4
+ "registry:ui",
5
+ "registry:component",
6
+ "registry:hook",
7
+ "registry:lib",
8
+ "registry:style"
9
+ ]);
10
+ var registryItemFileSchema = z.object({
11
+ path: z.string(),
12
+ type: registryItemTypeSchema,
13
+ content: z.string().optional(),
14
+ target: z.string().optional()
15
+ });
16
+ var registryItemSchema = z.object({
17
+ name: z.string(),
18
+ type: registryItemTypeSchema,
19
+ dependencies: z.array(z.string()).optional(),
20
+ registryDependencies: z.array(z.string()).optional(),
21
+ files: z.array(registryItemFileSchema)
22
+ });
23
+ var registryIndexSchema = z.object({
24
+ name: z.string(),
25
+ items: z.array(registryItemSchema)
26
+ });
27
+ var configSchema = z.object({
28
+ $schema: z.string().optional(),
29
+ version: z.literal(1),
30
+ css: z.string(),
31
+ aliases: z.object({
32
+ components: z.string(),
33
+ utils: z.string(),
34
+ ui: z.string(),
35
+ lib: z.string(),
36
+ hooks: z.string()
37
+ })
38
+ });
39
+ export {
40
+ configSchema,
41
+ registryIndexSchema,
42
+ registryItemFileSchema,
43
+ registryItemSchema,
44
+ registryItemTypeSchema
45
+ };
@@ -0,0 +1,103 @@
1
+ import { RegistryItem } from '../schema/index.js';
2
+ import 'zod';
3
+
4
+ interface SteraConfig {
5
+ $schema?: string;
6
+ version: 1;
7
+ css: string;
8
+ aliases: {
9
+ components: string;
10
+ utils: string;
11
+ ui: string;
12
+ lib: string;
13
+ hooks: string;
14
+ };
15
+ }
16
+ declare const CONFIG_FILE = "components.json";
17
+ declare function findConfigPath(cwd: string): string | null;
18
+ declare function loadConfig(cwd: string): SteraConfig | null;
19
+
20
+ interface TransformContext {
21
+ config: SteraConfig;
22
+ filename: string;
23
+ }
24
+ type TransformFn = (content: string, ctx: TransformContext) => string;
25
+ /**
26
+ * Apply a sequence of transforms to file content.
27
+ */
28
+ declare function applyTransforms(content: string, ctx: TransformContext, transforms: TransformFn[]): string;
29
+
30
+ /**
31
+ * Rewrite import paths in component files to match the user's configured aliases.
32
+ *
33
+ * Registry components use default aliases (e.g. `@/lib/utils`, `@/components/ui/button`).
34
+ * If the user configured different aliases, this transform rewrites the paths.
35
+ *
36
+ * When aliases match defaults (the common case), this is a no-op.
37
+ */
38
+ declare const transformImports: TransformFn;
39
+
40
+ /**
41
+ * Given a registry file, determine where it should be written in the consumer's project.
42
+ */
43
+ declare function resolveOutputPath(config: SteraConfig, projectRoot: string, file: {
44
+ path: string;
45
+ type: string;
46
+ }): string;
47
+
48
+ interface ProjectInfo {
49
+ hasSrc: boolean;
50
+ framework: "next" | "vite" | "other";
51
+ rsc: boolean;
52
+ existingCssFile: string | null;
53
+ }
54
+ /**
55
+ * Detect the project structure to inform configuration defaults.
56
+ *
57
+ * Checks for:
58
+ * - src/ directory
59
+ * - Framework (Next.js, Vite)
60
+ * - React Server Components (Next.js App Router)
61
+ * - Existing Tailwind CSS entry file
62
+ */
63
+ declare function detectProject(cwd: string): ProjectInfo;
64
+
65
+ /**
66
+ * Check if Stera has already been initialised in the user's project.
67
+ * Looks for the presence of `stera-ui.css` alongside the user's CSS file.
68
+ */
69
+ declare function hasGlobalsCss(config: SteraConfig, projectRoot: string): boolean;
70
+
71
+ type PackageManager = "pnpm" | "npm" | "yarn" | "bun";
72
+ declare function detectPackageManager(cwd: string): PackageManager;
73
+ /**
74
+ * Install npm dependencies, skipping any already in the consumer's package.json.
75
+ */
76
+ declare function installDependencies(deps: string[], cwd: string): Promise<void>;
77
+
78
+ interface WriteOptions {
79
+ overwrite?: boolean;
80
+ }
81
+ interface WriteResult {
82
+ written: string[];
83
+ skipped: string[];
84
+ }
85
+ /**
86
+ * Write component files to the consumer's project.
87
+ * Checks for existing files and prompts before overwriting.
88
+ */
89
+ declare function writeComponentFiles(items: RegistryItem[], config: SteraConfig, projectRoot: string, options?: WriteOptions): Promise<WriteResult>;
90
+
91
+ declare const brand: (text: string) => string;
92
+ declare const dim: (text: string) => string;
93
+ declare const LOGO: string;
94
+ declare const CHECK: string;
95
+ declare const CROSS = "\u2717";
96
+ declare const WARN = "!";
97
+
98
+ declare function createSpinner(text: string): {
99
+ succeed(msg: string): void;
100
+ fail(msg: string): void;
101
+ };
102
+
103
+ export { CHECK, CONFIG_FILE, CROSS, LOGO, type ProjectInfo, type TransformContext, type TransformFn, WARN, type WriteOptions, type WriteResult, applyTransforms, brand, createSpinner, detectPackageManager, detectProject, dim, findConfigPath, hasGlobalsCss, installDependencies, loadConfig, resolveOutputPath, transformImports, writeComponentFiles };