@remotedraw/cli 0.2.1 → 0.3.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.
package/dist/update.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { globalConfigPath } from "./cloud.js";
3
3
  import { t } from "./i18n.js";
4
+ import { packageManagerCommands, packageManagerFromUserAgent, } from "./packageManagers.js";
4
5
  export const CLI_PACKAGE_NAME = "@remotedraw/cli";
5
6
  const DEFAULT_REGISTRY_URL = "https://registry.npmjs.org";
6
7
  const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
@@ -75,45 +76,71 @@ export function compareVersions(a, b) {
75
76
  }
76
77
  return comparePrerelease(left.prerelease, right.prerelease);
77
78
  }
79
+ /** Splits a table entry like "pnpm dlx" into something spawnable. */
80
+ function commandLine(text, ...extra) {
81
+ const [command, ...args] = text.split(" ");
82
+ return { command: command, args: [...args, ...extra] };
83
+ }
84
+ /**
85
+ * Where each manager parks a package it is running once and throwing away.
86
+ * Matching the wrong one is not cosmetic: telling someone who ran `pnpm dlx`
87
+ * to `pnpm add --global` installs a copy they never asked for.
88
+ */
89
+ const EPHEMERAL_PATHS = [
90
+ ["npm", /\/(_npx|\.npm\/_npx)\//],
91
+ ["bun", /\/\.bun\/install\/cache\//],
92
+ ["pnpm", /\/pnpm\/dlx\//],
93
+ // Berry's `yarn dlx` builds a throwaway project directory named dlx-<pid>.
94
+ ["yarn", /\/dlx-\d+\//],
95
+ ];
96
+ /** Where each manager parks a package it installed to stay. */
97
+ const INSTALLED_PATHS = [
98
+ ["bun", /\/\.bun\//],
99
+ ["pnpm", /\/(\.pnpm|pnpm)\//],
100
+ ["yarn", /\/(\.yarn|[Yy]arn)\//],
101
+ ];
78
102
  /**
79
- * Derives the update command from where the running binary lives. Guessing
80
- * wrong only prints the wrong suggestion, so the fallback is plain npm.
103
+ * Yarn Berry removed global installs, so `yarn global add` is not a command
104
+ * that exists for it; a Berry user has the CLI as a project dependency, and
105
+ * `yarn up` is what moves it. Classic (v1) still has the global store.
81
106
  */
82
- export function detectInstallMethod(binPath) {
107
+ function yarnIsBerry(normalizedBinPath) {
108
+ return /(\.yarn\/(berry|cache|unplugged|__virtual__)|\.pnp)/.test(normalizedBinPath);
109
+ }
110
+ /**
111
+ * Derives the update command from where the running binary lives, falling back
112
+ * to the manager that invoked us. Guessing wrong only prints the wrong
113
+ * suggestion, so the last fallback is plain npm.
114
+ */
115
+ export function detectInstallMethod(binPath, env = {}) {
83
116
  const normalized = binPath.replace(/\\/g, "/");
84
117
  const update = `${CLI_PACKAGE_NAME}@latest`;
85
- if (/\/(_npx|\.npm\/_npx|\.bun\/install\/cache)\//.test(normalized)) {
86
- return { manager: "npm", ephemeral: true, command: "npx", args: [update] };
87
- }
88
- if (/\/\.bun\//.test(normalized)) {
89
- return {
90
- manager: "bun",
91
- ephemeral: false,
92
- command: "bun",
93
- args: ["add", "--global", update],
94
- };
95
- }
96
- if (/\/(\.pnpm|pnpm)\//.test(normalized)) {
97
- return {
98
- manager: "pnpm",
99
- ephemeral: false,
100
- command: "pnpm",
101
- args: ["add", "--global", update],
102
- };
118
+ for (const [manager, pattern] of EPHEMERAL_PATHS) {
119
+ if (pattern.test(normalized)) {
120
+ return {
121
+ manager,
122
+ ephemeral: true,
123
+ ...commandLine(packageManagerCommands[manager].dlx, update),
124
+ };
125
+ }
103
126
  }
104
- if (/\/(\.yarn|Yarn)\//.test(normalized)) {
127
+ // The path says who owns the binary; the user agent only says who launched
128
+ // this run, which can be a project's npm script over a pnpm-installed CLI.
129
+ const manager = INSTALLED_PATHS.find(([, pattern]) => pattern.test(normalized))?.[0] ??
130
+ packageManagerFromUserAgent(env) ??
131
+ "npm";
132
+ if (manager === "yarn") {
105
133
  return {
106
- manager: "yarn",
134
+ manager,
107
135
  ephemeral: false,
108
- command: "yarn",
109
- args: ["global", "add", update],
136
+ ...commandLine(yarnIsBerry(normalized) ? "yarn up" : "yarn global add", update),
110
137
  };
111
138
  }
139
+ const addGlobal = packageManagerCommands[manager].addGlobal;
112
140
  return {
113
- manager: "npm",
141
+ manager,
114
142
  ephemeral: false,
115
- command: "npm",
116
- args: ["install", "--global", update],
143
+ ...commandLine(addGlobal ?? packageManagerCommands[manager].dlx, update),
117
144
  };
118
145
  }
119
146
  export function installMethodDisplay(method) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotedraw/cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Command-line tools for creating and inspecting RemoteDraw integrations.",
5
5
  "type": "module",
6
6
  "bin": {