@absolutejs/absolute 0.16.12 → 0.17.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.
@@ -8,7 +8,8 @@
8
8
  "WebFetch(domain:gist.github.com)",
9
9
  "WebFetch(domain:vite.dev)",
10
10
  "WebFetch(domain:leapcell.io)",
11
- "Bash(bun run build:*)"
11
+ "Bash(bun run build:*)",
12
+ "Bash(bun run:*)"
12
13
  ]
13
14
  }
14
15
  }
package/dist/cli/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
+ var __require = import.meta.require;
3
4
 
4
5
  // src/cli/scripts/dev.ts
5
6
  var {$: $2 } = globalThis.Bun;
6
7
  var {env } = globalThis.Bun;
7
- import { existsSync as existsSync2 } from "fs";
8
- import { resolve as resolve2 } from "path";
8
+ import { existsSync as existsSync3 } from "fs";
9
+ import { resolve as resolve3 } from "path";
9
10
 
10
11
  // src/constants.ts
11
12
  var SECONDS_IN_A_MINUTE = 60;
@@ -295,14 +296,124 @@ var createInteractiveHandler = (actions) => {
295
296
  return { clearPrompt, dispose, showPrompt };
296
297
  };
297
298
 
299
+ // src/cli/telemetryEvent.ts
300
+ import { readFileSync as readFileSync2 } from "fs";
301
+ import { arch, platform } from "os";
302
+ import { resolve } from "path";
303
+
304
+ // src/cli/scripts/telemetry.ts
305
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
306
+ import { homedir } from "os";
307
+ import { join } from "path";
308
+ var configDir = join(homedir(), ".absolutejs");
309
+ var configPath = join(configDir, "telemetry.json");
310
+ var getTelemetryConfig = () => {
311
+ try {
312
+ if (!existsSync(configPath))
313
+ return null;
314
+ const raw = readFileSync(configPath, "utf-8");
315
+ return JSON.parse(raw);
316
+ } catch {
317
+ return null;
318
+ }
319
+ };
320
+ var saveTelemetryConfig = (config) => {
321
+ mkdirSync(configDir, { recursive: true });
322
+ writeFileSync(configPath, JSON.stringify(config, null, "\t") + `
323
+ `);
324
+ };
325
+ var enable = () => {
326
+ const existing = getTelemetryConfig();
327
+ const config = {
328
+ enabled: true,
329
+ anonymousId: existing?.anonymousId ?? crypto.randomUUID(),
330
+ createdAt: existing?.createdAt ?? new Date().toISOString()
331
+ };
332
+ saveTelemetryConfig(config);
333
+ console.log("Telemetry enabled.");
334
+ console.log(`Anonymous ID: ${config.anonymousId}`);
335
+ };
336
+ var disable = () => {
337
+ const existing = getTelemetryConfig();
338
+ if (existing) {
339
+ saveTelemetryConfig({ ...existing, enabled: false });
340
+ }
341
+ console.log("Telemetry disabled.");
342
+ };
343
+ var status = () => {
344
+ const config = getTelemetryConfig();
345
+ if (!config || !config.enabled) {
346
+ console.log("Telemetry is disabled.");
347
+ } else {
348
+ console.log("Telemetry is enabled.");
349
+ console.log(`Anonymous ID: ${config.anonymousId}`);
350
+ }
351
+ };
352
+ var telemetry = (args) => {
353
+ const subcommand = args[0];
354
+ if (subcommand === "enable") {
355
+ enable();
356
+ } else if (subcommand === "disable") {
357
+ disable();
358
+ } else if (subcommand === "status" || !subcommand) {
359
+ status();
360
+ if (!subcommand) {
361
+ console.log("");
362
+ console.log("Usage: absolute telemetry <command>");
363
+ console.log("Commands:");
364
+ console.log(" enable Enable anonymous telemetry");
365
+ console.log(" disable Disable telemetry");
366
+ console.log(" status Show current telemetry status");
367
+ }
368
+ } else {
369
+ console.error(`Unknown telemetry command: ${subcommand}`);
370
+ console.error("Usage: absolute telemetry <enable|disable|status>");
371
+ process.exit(1);
372
+ }
373
+ };
374
+
375
+ // src/cli/telemetryEvent.ts
376
+ var __dirname = "/home/alexkahn/abs/absolutejs/src/cli";
377
+ var getVersion = () => {
378
+ try {
379
+ const pkgPath = resolve(__dirname, "../../package.json");
380
+ const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
381
+ return pkg.version;
382
+ } catch {
383
+ return "unknown";
384
+ }
385
+ };
386
+ var sendTelemetryEvent = (event, payload) => {
387
+ try {
388
+ const config = getTelemetryConfig();
389
+ if (!config?.enabled)
390
+ return;
391
+ const body = {
392
+ event,
393
+ anonymousId: config.anonymousId,
394
+ version: getVersion(),
395
+ os: platform(),
396
+ arch: arch(),
397
+ bunVersion: Bun.version,
398
+ timestamp: new Date().toISOString(),
399
+ payload
400
+ };
401
+ fetch("https://absolutejs.com/api/telemetry", {
402
+ method: "POST",
403
+ headers: { "Content-Type": "application/json" },
404
+ body: JSON.stringify(body)
405
+ }).catch(() => {});
406
+ } catch {}
407
+ };
408
+
298
409
  // src/cli/utils.ts
299
410
  var {$ } = globalThis.Bun;
300
411
  import { execSync } from "child_process";
301
- import { existsSync, readFileSync } from "fs";
302
- import { resolve } from "path";
412
+ import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
413
+ import { resolve as resolve2 } from "path";
303
414
  var isWSLEnvironment = () => {
304
415
  try {
305
- const release = readFileSync("/proc/version", "utf-8");
416
+ const release = readFileSync3("/proc/version", "utf-8");
306
417
  return /microsoft|wsl/i.test(release);
307
418
  } catch {
308
419
  return false;
@@ -311,8 +422,8 @@ var isWSLEnvironment = () => {
311
422
  var COMPOSE_PATH = "db/docker-compose.db.yml";
312
423
  var DEFAULT_SERVER_ENTRY = "src/backend/server.ts";
313
424
  var readDbScripts = async () => {
314
- const pkgPath = resolve("package.json");
315
- if (!existsSync(pkgPath))
425
+ const pkgPath = resolve2("package.json");
426
+ if (!existsSync2(pkgPath))
316
427
  return null;
317
428
  const pkg = await Bun.file(pkgPath).json();
318
429
  const upCommand = pkg.scripts?.["db:up"];
@@ -380,7 +491,7 @@ var cliTag = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cl
380
491
  var dev = async (serverEntry) => {
381
492
  const port = Number(env.PORT) || DEFAULT_PORT;
382
493
  killStaleProcesses(port);
383
- const usesDocker = existsSync2(resolve2(COMPOSE_PATH));
494
+ const usesDocker = existsSync3(resolve3(COMPOSE_PATH));
384
495
  const scripts = usesDocker ? await readDbScripts() : null;
385
496
  if (scripts)
386
497
  await startDatabase(scripts);
@@ -428,10 +539,16 @@ var dev = async (serverEntry) => {
428
539
  return proc;
429
540
  };
430
541
  let serverProcess = spawnServer();
542
+ const sessionStart = Date.now();
543
+ sendTelemetryEvent("dev:start", { entry: serverEntry });
431
544
  const cleanup = async (exitCode = 0) => {
432
545
  if (cleaning)
433
546
  return;
434
547
  cleaning = true;
548
+ sendTelemetryEvent("dev:session-duration", {
549
+ duration: Math.round((Date.now() - sessionStart) / 1000),
550
+ entry: serverEntry
551
+ });
435
552
  if (interactive)
436
553
  interactive.dispose();
437
554
  if (paused)
@@ -484,9 +601,9 @@ var dev = async (serverEntry) => {
484
601
  };
485
602
  const openInBrowser = async () => {
486
603
  const url = `http://localhost:${port}`;
487
- const { platform } = process;
488
- const isWSL = platform === "linux" && isWSLEnvironment();
489
- const cmd = isWSL ? "cmd.exe" : platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
604
+ const { platform: platform2 } = process;
605
+ const isWSL = platform2 === "linux" && isWSLEnvironment();
606
+ const cmd = isWSL ? "cmd.exe" : platform2 === "darwin" ? "open" : platform2 === "win32" ? "start" : "xdg-open";
490
607
  const args = isWSL ? ["/c", "start", url] : [url];
491
608
  try {
492
609
  Bun.spawn([cmd, ...args], {
@@ -529,6 +646,10 @@ var dev = async (serverEntry) => {
529
646
  return;
530
647
  }
531
648
  console.error(cliTag("\x1B[31m", `Server exited (code ${exitCode}), restarting...`));
649
+ sendTelemetryEvent("dev:server-crash", {
650
+ exitCode,
651
+ entry: serverEntry
652
+ });
532
653
  serverProcess = spawnServer();
533
654
  }
534
655
  };
@@ -537,7 +658,7 @@ var dev = async (serverEntry) => {
537
658
 
538
659
  // src/cli/cache.ts
539
660
  import { mkdir } from "fs/promises";
540
- import { join } from "path";
661
+ import { join as join2 } from "path";
541
662
  var {Glob } = globalThis.Bun;
542
663
  var CACHE_DIR = ".absolutejs";
543
664
  var MAX_FILES_PER_BATCH = 200;
@@ -561,7 +682,7 @@ var hashConfigs = async (configFiles) => {
561
682
  };
562
683
  var loadCache = async (tool) => {
563
684
  try {
564
- const path = join(CACHE_DIR, `${tool}.cache.json`);
685
+ const path = join2(CACHE_DIR, `${tool}.cache.json`);
565
686
  const data = await Bun.file(path).json();
566
687
  return data;
567
688
  } catch {
@@ -570,7 +691,7 @@ var loadCache = async (tool) => {
570
691
  };
571
692
  var saveCache = async (tool, data) => {
572
693
  await mkdir(CACHE_DIR, { recursive: true });
573
- const path = join(CACHE_DIR, `${tool}.cache.json`);
694
+ const path = join2(CACHE_DIR, `${tool}.cache.json`);
574
695
  await Bun.write(path, JSON.stringify(data, null, "\t"));
575
696
  };
576
697
  var getChangedFiles = async (adapter) => {
@@ -663,6 +784,142 @@ var eslint = async (args) => {
663
784
  await runTool(eslintAdapter, args);
664
785
  };
665
786
 
787
+ // src/cli/scripts/info.ts
788
+ import { execSync as execSync2 } from "child_process";
789
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
790
+ import { arch as arch2, cpus, platform as platform2, totalmem, version } from "os";
791
+ import { resolve as resolve4 } from "path";
792
+ var __dirname = "/home/alexkahn/abs/absolutejs/src/cli/scripts";
793
+ var bold = (str) => `\x1B[1m${str}\x1B[0m`;
794
+ var getBinaryVersion = (binary, flag = "--version") => {
795
+ try {
796
+ const raw = execSync2(`${binary} ${flag}`, {
797
+ encoding: "utf-8",
798
+ timeout: 5000,
799
+ stdio: ["pipe", "pipe", "pipe"]
800
+ }).trim();
801
+ const match = /(\d+\.\d+\.\d+[\w.-]*)/.exec(raw);
802
+ return match !== null ? match[1] : raw.replace(/^v/, "");
803
+ } catch {
804
+ return "N/A";
805
+ }
806
+ };
807
+ var getPackageVersion = (packageName) => {
808
+ try {
809
+ const pkgPath = __require.resolve(`${packageName}/package.json`, {
810
+ paths: [process.cwd()]
811
+ });
812
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
813
+ return pkg.version;
814
+ } catch {
815
+ return "N/A";
816
+ }
817
+ };
818
+ var getAbsoluteVersion = () => {
819
+ try {
820
+ const pkgPath = resolve4(__dirname, "../../../package.json");
821
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
822
+ return pkg.version;
823
+ } catch {
824
+ return getPackageVersion("@absolutejs/absolute");
825
+ }
826
+ };
827
+ var detectCI = () => {
828
+ const { env: env2 } = process;
829
+ if (env2.GITHUB_ACTIONS)
830
+ return "GitHub Actions";
831
+ if (env2.GITLAB_CI)
832
+ return "GitLab CI";
833
+ if (env2.CIRCLECI)
834
+ return "CircleCI";
835
+ if (env2.JENKINS_URL)
836
+ return "Jenkins";
837
+ if (env2.TRAVIS)
838
+ return "Travis CI";
839
+ if (env2.BUILDKITE)
840
+ return "Buildkite";
841
+ if (env2.CODEBUILD_BUILD_ID)
842
+ return "AWS CodeBuild";
843
+ if (env2.TF_BUILD)
844
+ return "Azure Pipelines";
845
+ if (env2.VERCEL)
846
+ return "Vercel";
847
+ if (env2.NETLIFY)
848
+ return "Netlify";
849
+ if (env2.CI)
850
+ return "Yes (unknown provider)";
851
+ return "No";
852
+ };
853
+ var isDockerEnvironment = () => {
854
+ try {
855
+ return existsSync4("/.dockerenv");
856
+ } catch {
857
+ return false;
858
+ }
859
+ };
860
+ var getMemoryMB = () => Math.round(totalmem() / 1024 / 1024);
861
+ var getGlibcVersion = () => {
862
+ if (platform2() !== "linux")
863
+ return null;
864
+ try {
865
+ const output = execSync2("ldd --version 2>&1 || true", {
866
+ encoding: "utf-8",
867
+ timeout: 5000
868
+ });
869
+ const match = /(\d+\.\d+)/.exec(output);
870
+ return match !== null ? match[1] : "N/A";
871
+ } catch {
872
+ return "N/A";
873
+ }
874
+ };
875
+ var info = () => {
876
+ const lines = [];
877
+ const section = (title) => {
878
+ lines.push(`${bold(title)}`);
879
+ };
880
+ const field = (key, val) => {
881
+ lines.push(` ${key}: ${val}`);
882
+ };
883
+ section("Operating System:");
884
+ field("Platform", platform2());
885
+ field("Arch", arch2());
886
+ field("Version", version());
887
+ field("Available memory (MB)", String(getMemoryMB()));
888
+ field("Available CPU cores", String(cpus().length));
889
+ const glibc = getGlibcVersion();
890
+ if (glibc)
891
+ field("glibc", glibc);
892
+ lines.push("");
893
+ section("Environment:");
894
+ field("WSL", isWSLEnvironment() ? "Yes" : "No");
895
+ field("Docker", isDockerEnvironment() ? "Yes" : "No");
896
+ field("CI", detectCI());
897
+ lines.push("");
898
+ section("Binaries:");
899
+ field("Bun", getBinaryVersion("bun"));
900
+ field("Node", getBinaryVersion("node"));
901
+ field("npm", getBinaryVersion("npm"));
902
+ field("Yarn", getBinaryVersion("yarn"));
903
+ field("pnpm", getBinaryVersion("pnpm"));
904
+ field("Docker", getBinaryVersion("docker", "--version"));
905
+ field("docker-compose", getBinaryVersion("docker-compose", "--version"));
906
+ lines.push("");
907
+ section("Relevant Packages:");
908
+ field("@absolutejs/absolute", getAbsoluteVersion());
909
+ field("elysia", getPackageVersion("elysia"));
910
+ field("react", getPackageVersion("react"));
911
+ field("react-dom", getPackageVersion("react-dom"));
912
+ field("svelte", getPackageVersion("svelte"));
913
+ field("vue", getPackageVersion("vue"));
914
+ field("typescript", getPackageVersion("typescript"));
915
+ field("tailwindcss", getPackageVersion("tailwindcss"));
916
+ field("@tailwindcss/cli", getPackageVersion("@tailwindcss/cli"));
917
+ lines.push("");
918
+ console.log("");
919
+ console.log(lines.join(`
920
+ `));
921
+ };
922
+
666
923
  // src/cli/scripts/prettier.ts
667
924
  var prettierAdapter = {
668
925
  name: "prettier",
@@ -695,19 +952,30 @@ var prettier = async (args) => {
695
952
  var command = process.argv[2];
696
953
  var args = process.argv.slice(3);
697
954
  if (command === "dev") {
955
+ sendTelemetryEvent("cli:command", { command });
698
956
  const serverEntry = args[0] ?? DEFAULT_SERVER_ENTRY;
699
957
  await dev(serverEntry);
700
958
  } else if (command === "eslint") {
959
+ sendTelemetryEvent("cli:command", { command });
701
960
  await eslint(args);
702
961
  } else if (command === "prettier") {
962
+ sendTelemetryEvent("cli:command", { command });
703
963
  await prettier(args);
964
+ } else if (command === "info") {
965
+ sendTelemetryEvent("cli:command", { command });
966
+ info();
967
+ } else if (command === "telemetry") {
968
+ sendTelemetryEvent("cli:command", { command });
969
+ telemetry(args);
704
970
  } else {
705
971
  const message = command ? `Unknown command: ${command}` : "No command specified";
706
972
  console.error(message);
707
- console.error("Usage: absolutejs <command>");
973
+ console.error("Usage: absolute <command>");
708
974
  console.error("Commands:");
709
975
  console.error(" dev [entry] Start development server");
710
976
  console.error(" eslint Run ESLint (cached)");
977
+ console.error(" info Print system info for bug reports");
711
978
  console.error(" prettier Run Prettier check (cached)");
979
+ console.error(" telemetry Manage anonymous telemetry");
712
980
  process.exit(1);
713
981
  }