vectorvesper 1.0.0 → 1.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.
Files changed (2) hide show
  1. package/dist/index.js +84 -3
  2. package/package.json +4 -1
package/dist/index.js CHANGED
@@ -879,6 +879,64 @@ Using ${component.title || component.name}:`)));
879
879
  }
880
880
  }
881
881
 
882
+ // src/utils/transpile.ts
883
+ function isTsSource(target) {
884
+ return /\.(tsx|ts|mts|cts)$/i.test(target);
885
+ }
886
+ function toJsTarget(target) {
887
+ return target.replace(/\.tsx$/i, ".jsx").replace(/\.mts$/i, ".mjs").replace(/\.cts$/i, ".cjs").replace(/\.ts$/i, ".js");
888
+ }
889
+ async function stripTypes(content, filename) {
890
+ const babelMod = await import("@babel/core");
891
+ const transformAsync = babelMod.transformAsync ?? babelMod.default?.transformAsync;
892
+ if (typeof transformAsync !== "function") {
893
+ throw new Error("@babel/core is not available");
894
+ }
895
+ const presetMod = await import("@babel/preset-typescript");
896
+ const presetTypescript = presetMod.default ?? presetMod;
897
+ const result = await transformAsync(content, {
898
+ filename,
899
+ // .tsx → parse JSX; .ts → treat `<T>` as a generic
900
+ configFile: false,
901
+ babelrc: false,
902
+ comments: true,
903
+ // Only strip types. No JSX/react preset, so JSX is left untouched.
904
+ presets: [presetTypescript]
905
+ });
906
+ if (!result || typeof result.code !== "string") {
907
+ throw new Error("type-stripping produced no output");
908
+ }
909
+ return result.code;
910
+ }
911
+ async function fileToJs(target, content) {
912
+ if (!isTsSource(target)) return { target, content };
913
+ try {
914
+ const code = await stripTypes(content, target);
915
+ return { target: toJsTarget(target), content: code };
916
+ } catch (err) {
917
+ return { target, content, error: err instanceof Error ? err.message : String(err) };
918
+ }
919
+ }
920
+ async function maybeTranspile(components, tsx) {
921
+ if (tsx) return { components, warnings: [] };
922
+ const warnings = [];
923
+ const transpiled = await Promise.all(
924
+ components.map(async (component) => {
925
+ const files = await Promise.all(
926
+ component.files.map(async (file) => {
927
+ const res = await fileToJs(file.target, file.content ?? "");
928
+ if (res.error) {
929
+ warnings.push(`${file.target} kept as TypeScript (${res.error})`);
930
+ }
931
+ return { ...file, target: res.target, content: res.content };
932
+ })
933
+ );
934
+ return { ...component, files };
935
+ })
936
+ );
937
+ return { components: transpiled, warnings };
938
+ }
939
+
882
940
  // src/commands/add.ts
883
941
  async function handleDependencies(components, projectRoot, projectInfo, options) {
884
942
  const missing = getMissingDependencies(components, projectRoot);
@@ -993,6 +1051,13 @@ async function addCommand(slug, options = {}) {
993
1051
  process.exit(1);
994
1052
  return;
995
1053
  }
1054
+ let transpileWarnings = [];
1055
+ if (config.tsx === false) {
1056
+ spinner.text = "Converting to JavaScript...";
1057
+ const t = await maybeTranspile(resolvedComponents, false);
1058
+ resolvedComponents = t.components;
1059
+ transpileWarnings = t.warnings;
1060
+ }
996
1061
  spinner.text = "Checking file conflicts...";
997
1062
  let planned;
998
1063
  try {
@@ -1091,6 +1156,11 @@ async function addCommand(slug, options = {}) {
1091
1156
  framework: projectInfo.framework,
1092
1157
  hasTailwind: projectInfo.hasTailwind
1093
1158
  });
1159
+ if (transpileWarnings.length > 0) {
1160
+ console.log(pc6.yellow(`
1161
+ \u26A0\uFE0F Some files were kept as TypeScript:`));
1162
+ for (const w of transpileWarnings) console.log(` ${pc6.dim(w)}`);
1163
+ }
1094
1164
  console.log("");
1095
1165
  console.log(pc6.bold(pc6.green(`\u2714 Added ${pc6.cyan(targetComponent.slug)} to ${installPath}`)));
1096
1166
  console.log("");
@@ -1160,16 +1230,22 @@ async function updateCommand(slug, options = {}) {
1160
1230
  const upToDate = [];
1161
1231
  const failed = [];
1162
1232
  const updatedComponents = [];
1233
+ const transpileWarnings = [];
1163
1234
  for (const target of targets) {
1164
1235
  spinner.text = `Updating ${pc7.cyan(target)}...`;
1165
1236
  try {
1166
- const components = await resolveComponentTree(target);
1237
+ let components = await resolveComponentTree(target);
1167
1238
  const remote = components[components.length - 1];
1168
1239
  const localVersion = manifest.components[target]?.version;
1169
1240
  if (localVersion === remote.version && !options.force) {
1170
1241
  upToDate.push(target);
1171
1242
  continue;
1172
1243
  }
1244
+ if (config.tsx === false) {
1245
+ const t = await maybeTranspile(components, false);
1246
+ components = t.components;
1247
+ transpileWarnings.push(...t.warnings);
1248
+ }
1173
1249
  const planned = planFiles(components, installDir, projectRoot);
1174
1250
  writeFiles(planned.map((f) => ({ absolutePath: f.absolutePath, content: f.content })));
1175
1251
  recordInstall(components, installDir, projectRoot);
@@ -1197,6 +1273,11 @@ async function updateCommand(slug, options = {}) {
1197
1273
  Failed (${failed.length}):`)));
1198
1274
  for (const f of failed) console.log(` ${pc7.red("\u2716")} ${f.slug}: ${pc7.dim(f.reason)}`);
1199
1275
  }
1276
+ if (transpileWarnings.length > 0) {
1277
+ console.log(pc7.yellow(`
1278
+ \u26A0\uFE0F Some files were kept as TypeScript:`));
1279
+ for (const w of transpileWarnings) console.log(` ${pc7.dim(w)}`);
1280
+ }
1200
1281
  console.log("");
1201
1282
  if (updatedComponents.length > 0) {
1202
1283
  await handleDependencies(updatedComponents, projectRoot, projectInfo, options);
@@ -1305,7 +1386,7 @@ Remove ${slug}
1305
1386
  import fs9 from "fs";
1306
1387
  import path9 from "path";
1307
1388
  import pc9 from "picocolors";
1308
- var CLI_VERSION = true ? "1.0.0" : "0.0.0-dev";
1389
+ var CLI_VERSION = true ? "1.1.0" : "0.0.0-dev";
1309
1390
  async function infoCommand() {
1310
1391
  console.log(pc9.bold(pc9.cyan("\nVector Vesper Diagnostics\n")));
1311
1392
  const projectInfo = detectProject();
@@ -1603,7 +1684,7 @@ async function whoamiCommand() {
1603
1684
  }
1604
1685
 
1605
1686
  // src/index.ts
1606
- var version = true ? "1.0.0" : "0.0.0-dev";
1687
+ var version = true ? "1.1.0" : "0.0.0-dev";
1607
1688
  var program = new Command();
1608
1689
  program.name("vv").description("Vector Vesper CLI \u2014 add visual components to your React project").version(version).option("--verbose", "Show detailed debug output").hook("preAction", (thisCommand) => {
1609
1690
  const opts = thisCommand.opts();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vectorvesper",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Add WebGL, React Three Fiber & advanced motion components to your project via CLI.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,6 +46,8 @@
46
46
  "test:watch": "vitest"
47
47
  },
48
48
  "dependencies": {
49
+ "@babel/core": "^7.24.0",
50
+ "@babel/preset-typescript": "^7.24.0",
49
51
  "@clack/prompts": "^0.7.0",
50
52
  "commander": "^12.0.0",
51
53
  "ora": "^8.0.1",
@@ -53,6 +55,7 @@
53
55
  "zod": "^3.22.4"
54
56
  },
55
57
  "devDependencies": {
58
+ "@types/babel__core": "^7.20.5",
56
59
  "@types/node": "^25.9.2",
57
60
  "tsup": "^8.0.2",
58
61
  "typescript": "^6.0.3",