wensity 0.1.1 → 0.1.3
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/README.md +4 -1
- package/dist/index.js +81 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,8 +7,11 @@ pnpm dlx wensity init
|
|
|
7
7
|
pnpm dlx wensity login
|
|
8
8
|
pnpm dlx wensity list
|
|
9
9
|
pnpm dlx wensity add liquid-multimodal-input
|
|
10
|
+
pnpm dlx wensity list --type block
|
|
11
|
+
pnpm dlx wensity add monolith-hero --type block
|
|
10
12
|
pnpm dlx wensity whoami
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
Premium components require an API token from the Wensity dashboard. Tokens are
|
|
14
|
-
stored at `~/.config/wensity/credentials.json` with `0600` permissions.
|
|
16
|
+
stored at `~/.config/wensity/credentials.json` with `0600` permissions.
|
|
17
|
+
Blocks are always premium and require an authenticated Pro token.
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { dirname as dirname5, join as join6 } from "path";
|
|
|
6
6
|
|
|
7
7
|
// src/constants.ts
|
|
8
8
|
var CLI_NAME = "wensity";
|
|
9
|
-
var CLI_VERSION = "0.1.
|
|
9
|
+
var CLI_VERSION = "0.1.3";
|
|
10
10
|
var CONFIG_FILE_NAME = "wensity.json";
|
|
11
11
|
var DEFAULT_API_ORIGIN = "https://ui.wensity.com";
|
|
12
12
|
var DEFAULT_REGISTRY_PATH = "/api/registry";
|
|
@@ -21,9 +21,9 @@ Usage:
|
|
|
21
21
|
wensity login [options]
|
|
22
22
|
wensity logout
|
|
23
23
|
wensity whoami [--json]
|
|
24
|
-
wensity list [options]
|
|
25
|
-
wensity add <slug> [options]
|
|
26
|
-
wensity update <slug> [options]
|
|
24
|
+
wensity list [--type component|block] [options]
|
|
25
|
+
wensity add <slug> [--type component|block] [options]
|
|
26
|
+
wensity update <slug> [--type component|block] [options]
|
|
27
27
|
wensity version
|
|
28
28
|
|
|
29
29
|
Commands:
|
|
@@ -31,14 +31,15 @@ Commands:
|
|
|
31
31
|
login Save a Wensity API token for premium component access
|
|
32
32
|
logout Remove saved CLI credentials
|
|
33
33
|
whoami Verify the saved token and print the authenticated account
|
|
34
|
-
list List registry components
|
|
35
|
-
add Download a component source file into this project
|
|
36
|
-
update Re-download a component and overwrite the local copy
|
|
34
|
+
list List registry components or blocks
|
|
35
|
+
add Download a component or block source file into this project
|
|
36
|
+
update Re-download a component or block and overwrite the local copy
|
|
37
37
|
version Print the CLI version
|
|
38
38
|
|
|
39
39
|
Options:
|
|
40
40
|
--api-url <url> Override the Wensity app origin, defaults to ${DEFAULT_API_ORIGIN}
|
|
41
41
|
--registry <url> Override the registry endpoint
|
|
42
|
+
--type <type> Select component or block, defaults to component
|
|
42
43
|
--token <token> Provide a token non-interactively for login
|
|
43
44
|
--force Overwrite generated files when adding or initializing
|
|
44
45
|
--no-install Write files without running the package manager
|
|
@@ -107,7 +108,7 @@ function hasFlag(args, name) {
|
|
|
107
108
|
return args.options.get(name) === true;
|
|
108
109
|
}
|
|
109
110
|
function expectsValue(name) {
|
|
110
|
-
return ["api-url", "registry", "token"].includes(name);
|
|
111
|
+
return ["api-url", "registry", "token", "type"].includes(name);
|
|
111
112
|
}
|
|
112
113
|
function normalizeOptionName(name) {
|
|
113
114
|
if (name === "dry") return "dry-run";
|
|
@@ -752,13 +753,19 @@ function summarizeFiles(projectRoot, files) {
|
|
|
752
753
|
return files.map((file) => toPosixPath(relative3(projectRoot, file.absolutePath)));
|
|
753
754
|
}
|
|
754
755
|
function transformComponentSource(content, config) {
|
|
755
|
-
const needsUtility = content.includes("@wensity/ui/lib");
|
|
756
|
-
const needsPrimitives = content.includes("@wensity/ui/components");
|
|
756
|
+
const needsUtility = content.includes("@wensity/ui/lib") || importsFrom(content, "@/lib/utils");
|
|
757
|
+
const needsPrimitives = content.includes("@wensity/ui/components") || importsFrom(content, "@/components/wensity/primitives");
|
|
757
758
|
let transformed = content;
|
|
758
759
|
transformed = transformed.replace(/from\s+["']@wensity\/ui\/lib["']/g, `from "${config.aliases.utils}"`);
|
|
760
|
+
transformed = transformed.replace(/from\s+["']@\/lib\/utils["']/g, `from "${config.aliases.utils}"`);
|
|
759
761
|
transformed = transformed.replace(/from\s+["']@wensity\/ui\/components["']/g, `from "${config.aliases.components}/primitives"`);
|
|
762
|
+
transformed = transformed.replace(/from\s+["']@\/components\/wensity\/primitives["']/g, `from "${config.aliases.components}/primitives"`);
|
|
760
763
|
return { content: transformed, needsUtility, needsPrimitives };
|
|
761
764
|
}
|
|
765
|
+
function importsFrom(source, specifier) {
|
|
766
|
+
const escaped = specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
767
|
+
return new RegExp(`from\\s+["']${escaped}["']`).test(source);
|
|
768
|
+
}
|
|
762
769
|
function collectDependencies(input) {
|
|
763
770
|
const dependencies = /* @__PURE__ */ new Set();
|
|
764
771
|
for (const dependency of input.declared) {
|
|
@@ -911,10 +918,26 @@ async function whoamiCommand(context, parsed) {
|
|
|
911
918
|
}
|
|
912
919
|
}
|
|
913
920
|
async function listCommand(context, parsed) {
|
|
921
|
+
const resourceType = getResourceType(parsed);
|
|
914
922
|
const apiUrl = getStringOption(parsed, "api-url") ?? context.env.WENSITY_API_URL;
|
|
915
923
|
const registryOverride = getStringOption(parsed, "registry");
|
|
916
924
|
const loaded = await loadConfig(context.cwd, { registry: registryOverride, apiUrl });
|
|
917
|
-
const
|
|
925
|
+
const registry = registryUrlForType(loaded.config.registry, resourceType, registryOverride);
|
|
926
|
+
if (resourceType === "block") {
|
|
927
|
+
const response2 = await requestJson(registry);
|
|
928
|
+
if (hasFlag(parsed, "json")) {
|
|
929
|
+
printJson(response2);
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
if (response2.blocks.length === 0) {
|
|
933
|
+
print("No Wensity blocks found.");
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
print("Available Wensity blocks:");
|
|
937
|
+
print(formatBlockGroup(response2.blocks));
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
const response = await requestJson(registry);
|
|
918
941
|
if (hasFlag(parsed, "json")) {
|
|
919
942
|
printJson(response);
|
|
920
943
|
return;
|
|
@@ -938,16 +961,31 @@ ${rows.join("\n")}` : `
|
|
|
938
961
|
${label}
|
|
939
962
|
No components`;
|
|
940
963
|
}
|
|
964
|
+
function formatBlockGroup(blocks) {
|
|
965
|
+
const rows = blocks.map((block) => {
|
|
966
|
+
const category = block.category ? ` ${block.category}` : "";
|
|
967
|
+
return ` ${block.slug.padEnd(32)}${category}`;
|
|
968
|
+
});
|
|
969
|
+
return rows.length > 0 ? `
|
|
970
|
+
Pro
|
|
971
|
+
${rows.join("\n")}` : "\nPro\n No blocks";
|
|
972
|
+
}
|
|
941
973
|
async function addCommand(context, parsed, positionals, updateMode) {
|
|
974
|
+
const resourceType = getResourceType(parsed);
|
|
942
975
|
const slug = positionals[0];
|
|
943
|
-
if (!slug)
|
|
976
|
+
if (!slug) {
|
|
977
|
+
throw new CliError(
|
|
978
|
+
`Missing ${resourceType} slug.
|
|
944
979
|
|
|
945
|
-
Usage: wensity ${updateMode ? "update" : "add"} <slug
|
|
980
|
+
Usage: wensity ${updateMode ? "update" : "add"} <slug>${resourceType === "block" ? " --type block" : ""}`
|
|
981
|
+
);
|
|
982
|
+
}
|
|
946
983
|
const apiUrl = getStringOption(parsed, "api-url") ?? context.env.WENSITY_API_URL;
|
|
947
984
|
const registryOverride = getStringOption(parsed, "registry");
|
|
948
985
|
const loaded = await loadConfig(context.cwd, { registry: registryOverride, apiUrl });
|
|
949
986
|
const credentials = await readCredentials(context.env);
|
|
950
|
-
const
|
|
987
|
+
const registry = registryUrlForType(loaded.config.registry, resourceType, registryOverride);
|
|
988
|
+
const payload = resourceType === "block" ? await fetchBlockPayload({ slug, registry, credentials }) : await fetchComponentPayload({ slug, registry, credentials });
|
|
951
989
|
const prepared = await prepareInstall(loaded.projectRoot, loaded.config, payload);
|
|
952
990
|
const force = updateMode || hasFlag(parsed, "force");
|
|
953
991
|
const dryRun = hasFlag(parsed, "dry-run");
|
|
@@ -978,7 +1016,12 @@ async function fetchComponentPayload(input) {
|
|
|
978
1016
|
if (input.credentials) {
|
|
979
1017
|
const cliEndpoint = metadata.endpoints?.cli ?? `/api/cli/${input.slug}`;
|
|
980
1018
|
const endpoint2 = cliEndpoint.startsWith("http") ? cliEndpoint : joinUrl(input.credentials.apiBaseUrl, cliEndpoint);
|
|
981
|
-
|
|
1019
|
+
try {
|
|
1020
|
+
return await requestJson(endpoint2, { token: input.credentials.token });
|
|
1021
|
+
} catch (error) {
|
|
1022
|
+
if (metadata.access === "pro" || !isAuthFailure(error)) throw error;
|
|
1023
|
+
warn("Saved Wensity credentials were rejected; falling back to the public free registry payload.");
|
|
1024
|
+
}
|
|
982
1025
|
}
|
|
983
1026
|
if (metadata.access === "pro") {
|
|
984
1027
|
throw new CliError(`${metadata.name} is a premium component. Run wensity login, then try again.`);
|
|
@@ -987,6 +1030,29 @@ async function fetchComponentPayload(input) {
|
|
|
987
1030
|
const endpoint = publicSourceEndpoint.startsWith("http") ? publicSourceEndpoint : joinUrl(registryOrigin(input.registry), publicSourceEndpoint);
|
|
988
1031
|
return requestJson(endpoint);
|
|
989
1032
|
}
|
|
1033
|
+
function isAuthFailure(error) {
|
|
1034
|
+
return error instanceof CliError && /^(401|403)\b/.test(error.message);
|
|
1035
|
+
}
|
|
1036
|
+
async function fetchBlockPayload(input) {
|
|
1037
|
+
info(`Fetching ${input.slug}...`);
|
|
1038
|
+
const metadata = await requestJson(registryMetadataUrl(input.registry, input.slug));
|
|
1039
|
+
if (!input.credentials) {
|
|
1040
|
+
throw new CliError(`${metadata.name} is a premium block. Run wensity login, then try again.`);
|
|
1041
|
+
}
|
|
1042
|
+
const cliEndpoint = metadata.endpoints?.cli ?? `/api/cli/blocks/${input.slug}`;
|
|
1043
|
+
const endpoint = cliEndpoint.startsWith("http") ? cliEndpoint : joinUrl(input.credentials.apiBaseUrl, cliEndpoint);
|
|
1044
|
+
return requestJson(endpoint, { token: input.credentials.token });
|
|
1045
|
+
}
|
|
1046
|
+
function getResourceType(parsed) {
|
|
1047
|
+
const value = getStringOption(parsed, "type") ?? "component";
|
|
1048
|
+
if (value === "component" || value === "block") return value;
|
|
1049
|
+
throw new CliError(`Invalid --type value: ${value}. Expected "component" or "block".`);
|
|
1050
|
+
}
|
|
1051
|
+
function registryUrlForType(componentRegistry, resourceType, registryOverride) {
|
|
1052
|
+
if (resourceType === "component") return componentRegistry;
|
|
1053
|
+
if (registryOverride) return registryOverride;
|
|
1054
|
+
return joinUrl(registryOrigin(componentRegistry), "/api/blocks");
|
|
1055
|
+
}
|
|
990
1056
|
async function requireCredentials(env) {
|
|
991
1057
|
const credentials = await readCredentials(env);
|
|
992
1058
|
if (!credentials) {
|