synthesisui 0.1.23 → 0.1.24
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/dist/commands/component.js +27 -0
- package/dist/index.js +23 -0
- package/dist/registry.js +21 -0
- package/package.json +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { resolveRegistry } from "../config.js";
|
|
4
|
+
import { fetchComponent } from "../registry.js";
|
|
5
|
+
/**
|
|
6
|
+
* Brings ONE component from a design system into the project (granular "bring
|
|
7
|
+
* specific", INS-18 fatia 3) - its recipe + compiled CSS, written under
|
|
8
|
+
* `_synthesisui/ds/<slug>/components/`. Handy for a component you refit/created
|
|
9
|
+
* on the platform. The component's styles reference the DS tokens, so the system
|
|
10
|
+
* itself must be installed (`synthesisui add <slug>`) for `tokens.css` to resolve.
|
|
11
|
+
*/
|
|
12
|
+
export async function component(slug, name, opts) {
|
|
13
|
+
const base = resolveRegistry(opts.registry);
|
|
14
|
+
const root = opts.dir ?? process.cwd();
|
|
15
|
+
console.log(`→ fetching "${name}" from "${slug}" …`);
|
|
16
|
+
const res = await fetchComponent(base, slug, name, opts.version);
|
|
17
|
+
const dir = join(root, "_synthesisui", "ds", slug, "components");
|
|
18
|
+
await mkdir(dir, { recursive: true });
|
|
19
|
+
await writeFile(join(dir, `${res.name}.json`), `${JSON.stringify(res.recipe, null, 2)}\n`, "utf8");
|
|
20
|
+
await writeFile(join(dir, `${res.name}.css`), `${res.css}\n`, "utf8");
|
|
21
|
+
console.log(`✓ ${res.name} → _synthesisui/ds/${slug}/components/${res.name}.{json,css} (${slug} v${res.version})`);
|
|
22
|
+
console.log("");
|
|
23
|
+
console.log("Use it:");
|
|
24
|
+
console.log(` • ensure the DS is installed: synthesisui add ${slug} (provides tokens.css)`);
|
|
25
|
+
console.log(` • @import "_synthesisui/ds/${slug}/components/${res.name}.css" in your CSS`);
|
|
26
|
+
console.log(` • <div data-ds="${slug}"><div class="ds-${res.name}">…</div></div>`);
|
|
27
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { add } from "./commands/add.js";
|
|
3
3
|
import { advise } from "./commands/advise.js";
|
|
4
|
+
import { component } from "./commands/component.js";
|
|
4
5
|
import { generate } from "./commands/generate.js";
|
|
5
6
|
import { init } from "./commands/init.js";
|
|
6
7
|
import { list } from "./commands/list.js";
|
|
@@ -16,6 +17,7 @@ Usage:
|
|
|
16
17
|
synthesisui list [options] list the published design systems
|
|
17
18
|
synthesisui add <slug> [options] materialize a DS into _synthesisui/ds/<slug>/
|
|
18
19
|
synthesisui template <slug> <name> materialize a whole page from a DS template
|
|
20
|
+
synthesisui component <slug> <name> bring one component (recipe + css) into the project
|
|
19
21
|
synthesisui use <slug> "<intent>" print a ready-to-paste agent prompt to build/modify on-system
|
|
20
22
|
synthesisui advise "<value prop>" engagement-pattern proposals for this project (login required)
|
|
21
23
|
synthesisui generate "<desc>" generate a token-only component recipe for your DS (login required)
|
|
@@ -41,6 +43,7 @@ Examples:
|
|
|
41
43
|
synthesisui add halogen --version 3
|
|
42
44
|
synthesisui template halogen dashboard-sidebar
|
|
43
45
|
synthesisui template halogen landing --out app/page.tsx
|
|
46
|
+
synthesisui component halogen pricing-tier
|
|
44
47
|
synthesisui use halogen "a pricing section with three tiers and a highlighted plan"
|
|
45
48
|
synthesisui use halogen "make the card shadow softer in components/StatCard.tsx"
|
|
46
49
|
synthesisui advise "habit-building app for tracking personal finances"
|
|
@@ -153,6 +156,26 @@ async function main() {
|
|
|
153
156
|
await template(slug, name, { registry, dir, out, target, version });
|
|
154
157
|
break;
|
|
155
158
|
}
|
|
159
|
+
case "component": {
|
|
160
|
+
const slug = args[0];
|
|
161
|
+
const name = args[1];
|
|
162
|
+
if (!slug || !name) {
|
|
163
|
+
console.error("error: provide slug and component name - `synthesisui component <slug> <name>`");
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
let version;
|
|
168
|
+
if (typeof flags.version === "string") {
|
|
169
|
+
version = Number.parseInt(flags.version.replace(/^v/i, ""), 10);
|
|
170
|
+
if (!Number.isInteger(version) || version < 1) {
|
|
171
|
+
console.error(`error: invalid --version "${flags.version}" - use an integer ≥ 1`);
|
|
172
|
+
process.exitCode = 1;
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
await component(slug, name, { registry, dir, version });
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
156
179
|
case "use": {
|
|
157
180
|
const slug = args[0];
|
|
158
181
|
if (!slug) {
|
package/dist/registry.js
CHANGED
|
@@ -63,6 +63,27 @@ export async function fetchTemplate(base, slug, template, target, version) {
|
|
|
63
63
|
}
|
|
64
64
|
return (await res.json());
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Fetches ONE component from a DS (`?component=<name>`): its recipe + compiled
|
|
68
|
+
* CSS. Granular "bring specific" - the system must exist; works for public DS
|
|
69
|
+
* without login (private/owned needs the token).
|
|
70
|
+
*/
|
|
71
|
+
export async function fetchComponent(base, slug, name, version) {
|
|
72
|
+
const url = new URL(`${base}/api/registry/ds/${encodeURIComponent(slug)}`);
|
|
73
|
+
url.searchParams.set("component", name);
|
|
74
|
+
if (version != null)
|
|
75
|
+
url.searchParams.set("version", String(version));
|
|
76
|
+
const res = await request(url.toString());
|
|
77
|
+
if (res.status === 404) {
|
|
78
|
+
const body = (await res.json().catch(() => ({})));
|
|
79
|
+
throw new RegistryError(body.message ??
|
|
80
|
+
`No component "${name}" in "${slug}". Run \`synthesisui add ${slug}\` and check its components.`);
|
|
81
|
+
}
|
|
82
|
+
if (!res.ok) {
|
|
83
|
+
throw new RegistryError(`Registry responded ${res.status} while fetching "${name}".`);
|
|
84
|
+
}
|
|
85
|
+
return (await res.json());
|
|
86
|
+
}
|
|
66
87
|
/**
|
|
67
88
|
* Calls the hosted advisor (`POST /api/ai/advisor`). Gated + metered server-side:
|
|
68
89
|
* 401 = not logged in, 429 = daily quota reached. Sends the Bearer token if present.
|