bluefairy 0.0.3 → 0.0.6

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.
@@ -2,10 +2,6 @@
2
2
 
3
3
  _bluefairy_home="${BLUEFAIRY_HOME:-$HOME/.bluefairy}"
4
4
 
5
- if command -v bluefairy >/dev/null 2>&1; then
6
- bluefairy init --quiet >/dev/null 2>&1 || return $?
7
- fi
8
-
9
5
  case ":$PATH:" in
10
6
  *":$_bluefairy_home/shims:"*) ;;
11
7
  *) PATH="$_bluefairy_home/shims:$PATH" ;;
@@ -2,11 +2,6 @@
2
2
  setlocal
3
3
  if "%BLUEFAIRY_HOME%"=="" set "BLUEFAIRY_HOME=%USERPROFILE%\.bluefairy"
4
4
 
5
- call bluefairy.cmd init --quiet >NUL 2>&1
6
- if errorlevel 1 (
7
- endlocal & exit /b %errorlevel%
8
- )
9
-
10
5
  echo %PATH% | find /I "%BLUEFAIRY_HOME%\shims" >NUL
11
6
  if errorlevel 1 (
12
7
  endlocal & set "PATH=%BLUEFAIRY_HOME%\shims;%PATH%"
@@ -2,11 +2,6 @@ if (-not $env:BLUEFAIRY_HOME) {
2
2
  $env:BLUEFAIRY_HOME = Join-Path $HOME ".bluefairy"
3
3
  }
4
4
 
5
- & bluefairy.cmd init --quiet *> $null
6
- if ($LASTEXITCODE -ne 0) {
7
- return
8
- }
9
-
10
5
  $shimDir = Join-Path $env:BLUEFAIRY_HOME "shims"
11
6
  $pathEntries = $env:PATH -split ';'
12
7
 
@@ -1,14 +1,10 @@
1
- import { ensureDir } from "../fs-utils.js";
2
- import { ensureManagedShims } from "../shims.js";
1
+ import { ensureRuntimeLayout } from "../install.js";
3
2
  function hasFlag(args, flag) {
4
3
  return args.includes(flag);
5
4
  }
6
5
  export async function runInit(config, args) {
7
6
  const quiet = hasFlag(args, "--quiet");
8
- await ensureDir(config.paths.homeDir);
9
- await ensureDir(config.paths.tempDir);
10
- await ensureDir(config.paths.stateDir);
11
- await ensureManagedShims(config.paths);
7
+ await ensureRuntimeLayout(config.paths);
12
8
  if (quiet) {
13
9
  return;
14
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,SAAS,OAAO,CAAC,IAAc,EAAE,IAAY;IAC3C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAuB,EACvB,IAAc;IAEd,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAEvC,MAAM,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEvC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;AACxD,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,SAAS,OAAO,CAAC,IAAc,EAAE,IAAY;IAC3C,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAuB,EACvB,IAAc;IAEd,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAEvC,MAAM,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAExC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,56 @@
1
+ import path from "node:path";
2
+ import { ensureDir, writeExecutableFile } from "./fs-utils.js";
3
+ import { ensureManagedShims } from "./shims.js";
4
+ export async function ensureRuntimeLayout(paths) {
5
+ await ensureDir(paths.homeDir);
6
+ await ensureDir(paths.tempDir);
7
+ await ensureDir(paths.stateDir);
8
+ await ensureManagedShims(paths);
9
+ }
10
+ export function renderPosixActivationHelper() {
11
+ return `#!/bin/sh
12
+
13
+ _bluefairy_home="\${BLUEFAIRY_HOME:-$HOME/.bluefairy}"
14
+
15
+ case ":$PATH:" in
16
+ *":$_bluefairy_home/shims:"*) ;;
17
+ *) PATH="$_bluefairy_home/shims:$PATH" ;;
18
+ esac
19
+
20
+ export PATH
21
+ unset _bluefairy_home
22
+ `;
23
+ }
24
+ export function renderCmdActivationHelper() {
25
+ return `@echo off
26
+ setlocal
27
+ if "%BLUEFAIRY_HOME%"=="" set "BLUEFAIRY_HOME=%USERPROFILE%\\.bluefairy"
28
+
29
+ echo %PATH% | find /I "%BLUEFAIRY_HOME%\\shims" >NUL
30
+ if errorlevel 1 (
31
+ endlocal & set "PATH=%BLUEFAIRY_HOME%\\shims;%PATH%"
32
+ ) else (
33
+ endlocal & set "PATH=%PATH%"
34
+ )
35
+ `;
36
+ }
37
+ export function renderPowerShellActivationHelper() {
38
+ return `if (-not $env:BLUEFAIRY_HOME) {
39
+ $env:BLUEFAIRY_HOME = Join-Path $HOME ".bluefairy"
40
+ }
41
+
42
+ $shimDir = Join-Path $env:BLUEFAIRY_HOME "shims"
43
+ $pathEntries = $env:PATH -split ';'
44
+
45
+ if (-not ($pathEntries | Where-Object { $_ -eq $shimDir })) {
46
+ $env:PATH = "$shimDir;$env:PATH"
47
+ }
48
+ `;
49
+ }
50
+ export async function installActivationHelpers(binDir) {
51
+ await ensureDir(binDir);
52
+ await writeExecutableFile(path.join(binDir, "bluefairy-activate"), renderPosixActivationHelper());
53
+ await writeExecutableFile(path.join(binDir, "bluefairy-activate.cmd"), renderCmdActivationHelper());
54
+ await writeExecutableFile(path.join(binDir, "bluefairy-activate.ps1"), renderPowerShellActivationHelper());
55
+ }
56
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAmB;IAC3D,MAAM,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,2BAA2B;IACzC,OAAO;;;;;;;;;;;CAWR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO;;;;;;;;;;CAUR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gCAAgC;IAC9C,OAAO;;;;;;;;;;CAUR,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAc;IAC3D,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,mBAAmB,CACvB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,EACvC,2BAA2B,EAAE,CAC9B,CAAC;IACF,MAAM,mBAAmB,CACvB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,wBAAwB,CAAC,EAC3C,yBAAyB,EAAE,CAC5B,CAAC;IACF,MAAM,mBAAmB,CACvB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,wBAAwB,CAAC,EAC3C,gCAAgC,EAAE,CACnC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,23 +1,22 @@
1
1
  {
2
2
  "name": "bluefairy",
3
- "version": "0.0.3",
3
+ "version": "0.0.6",
4
4
  "description": "A standalone package freshness guard for uv and npm.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "bluefairy": "./dist/cli.js",
8
- "bluefairy-activate": "./bin/bluefairy-activate",
9
- "bluefairy-activate.cmd": "./bin/bluefairy-activate.cmd",
10
- "bluefairy-activate.ps1": "./bin/bluefairy-activate.ps1"
7
+ "bluefairy": "./dist/cli.js"
11
8
  },
12
9
  "files": [
13
10
  "bin",
14
- "dist"
11
+ "dist",
12
+ "scripts"
15
13
  ],
16
14
  "scripts": {
17
15
  "build": "tsc -p tsconfig.json",
18
16
  "build:test": "tsc -p tsconfig.test.json",
19
17
  "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
20
18
  "clean:test": "node -e \"require('node:fs').rmSync('dist-test', { recursive: true, force: true })\"",
19
+ "postinstall": "node scripts/postinstall.mjs",
21
20
  "prepare": "npm run build",
22
21
  "test:prepare": "npm run build && npm run build:test",
23
22
  "test:unit": "npm run test:prepare && node scripts/run-node-tests.mjs unit",
@@ -0,0 +1,57 @@
1
+ import path from "node:path";
2
+ import process from "node:process";
3
+ import { execFileSync } from "node:child_process";
4
+
5
+ function isGlobalInstall() {
6
+ const value = process.env.npm_config_global;
7
+ return typeof value === "string" && value.toLowerCase() === "true";
8
+ }
9
+
10
+ function getNpmPrefix() {
11
+ const explicit = process.env.npm_config_prefix?.trim();
12
+ if (explicit) {
13
+ return explicit;
14
+ }
15
+
16
+ const npmExecPath = process.env.npm_execpath?.trim();
17
+ if (npmExecPath) {
18
+ return execFileSync(process.execPath, [npmExecPath, "prefix", "-g"], {
19
+ encoding: "utf8"
20
+ }).trim();
21
+ }
22
+
23
+ const npmBinary = process.platform === "win32" ? "npm.cmd" : "npm";
24
+ return execFileSync(npmBinary, ["prefix", "-g"], {
25
+ encoding: "utf8"
26
+ }).trim();
27
+ }
28
+
29
+ function getGlobalBinDir(prefix) {
30
+ return process.platform === "win32" ? prefix : path.join(prefix, "bin");
31
+ }
32
+
33
+ async function main() {
34
+ if (!isGlobalInstall()) {
35
+ return;
36
+ }
37
+
38
+ const [{ ensureRuntimeLayout, installActivationHelpers }, { getRuntimePaths }] =
39
+ await Promise.all([
40
+ import("../dist/install.js"),
41
+ import("../dist/paths.js")
42
+ ]);
43
+
44
+ const runtimePaths = getRuntimePaths(process.env);
45
+ await ensureRuntimeLayout(runtimePaths);
46
+
47
+ const prefix = getNpmPrefix();
48
+ const binDir = getGlobalBinDir(prefix);
49
+ await installActivationHelpers(binDir);
50
+ }
51
+
52
+ main().catch((error) => {
53
+ const message =
54
+ error instanceof Error ? error.message : `Unknown error: ${String(error)}`;
55
+ console.error(`bluefairy postinstall: ${message}`);
56
+ process.exitCode = 1;
57
+ });
@@ -0,0 +1,91 @@
1
+ import { readdirSync, statSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { spawnSync } from "node:child_process";
4
+
5
+ const suite = process.argv[2];
6
+ const distTestRoot = path.resolve("dist-test", "test");
7
+
8
+ function walk(directory) {
9
+ const entries = readdirSync(directory, { withFileTypes: true });
10
+ const files = [];
11
+
12
+ for (const entry of entries) {
13
+ const resolved = path.join(directory, entry.name);
14
+ if (entry.isDirectory()) {
15
+ files.push(...walk(resolved));
16
+ continue;
17
+ }
18
+
19
+ if (entry.isFile()) {
20
+ files.push(resolved);
21
+ }
22
+ }
23
+
24
+ return files;
25
+ }
26
+
27
+ function toPosixLike(filePath) {
28
+ return filePath.split(path.sep).join("/");
29
+ }
30
+
31
+ function selectFiles(files, selectedSuite) {
32
+ switch (selectedSuite) {
33
+ case "unit":
34
+ return files.filter(
35
+ ({ normalizedPath }) =>
36
+ normalizedPath.includes("/test/unit/") &&
37
+ normalizedPath.endsWith(".test.js")
38
+ );
39
+ case "integration:fake":
40
+ return files.filter(
41
+ ({ normalizedPath }) =>
42
+ normalizedPath.includes("/test/integration/") &&
43
+ normalizedPath.includes(".fake.") &&
44
+ normalizedPath.endsWith(".test.js")
45
+ );
46
+ case "integration:real":
47
+ return files.filter(
48
+ ({ normalizedPath }) =>
49
+ normalizedPath.includes("/test/integration/") &&
50
+ normalizedPath.includes(".real.") &&
51
+ normalizedPath.endsWith(".test.js")
52
+ );
53
+ default:
54
+ throw new Error(
55
+ `Unknown test suite "${selectedSuite}". Expected one of: unit, integration:fake, integration:real`
56
+ );
57
+ }
58
+ }
59
+
60
+ if (!suite) {
61
+ throw new Error("Missing test suite argument");
62
+ }
63
+
64
+ if (!statSync(distTestRoot).isDirectory()) {
65
+ throw new Error(`Missing compiled test directory: ${distTestRoot}`);
66
+ }
67
+
68
+ const files = selectFiles(
69
+ walk(distTestRoot)
70
+ .sort()
71
+ .map((filePath) => ({
72
+ filePath,
73
+ normalizedPath: toPosixLike(filePath)
74
+ })),
75
+ suite
76
+ ).map(({ filePath }) => filePath);
77
+
78
+ if (files.length === 0) {
79
+ throw new Error(`No compiled test files found for suite: ${suite}`);
80
+ }
81
+
82
+ const result = spawnSync(process.execPath, ["--test", ...files], {
83
+ stdio: "inherit",
84
+ env: process.env
85
+ });
86
+
87
+ if (result.error) {
88
+ throw result.error;
89
+ }
90
+
91
+ process.exit(result.status ?? 1);