@sparkelf/dsh-plus 0.1.0-rc.30 → 0.1.0-rc.31

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/lib/bin.js CHANGED
@@ -3,7 +3,7 @@ import { r as runApply } from "./apply-e0aMC4B4.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { execFileSync, spawn, spawnSync } from "node:child_process";
5
5
  import { createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
6
- import { dirname, join, resolve } from "node:path";
6
+ import { dirname, join, posix, resolve, win32 } from "node:path";
7
7
  import { homedir } from "node:os";
8
8
  import semver from "semver";
9
9
  import { fileURLToPath } from "node:url";
@@ -232,6 +232,27 @@ function resolveHome(env = process.env) {
232
232
  return configured === void 0 || configured === "" ? join(homedir(), ".dsh") : resolve(configured);
233
233
  }
234
234
  /**
235
+ * Whether one absolute path is the other or sits beneath it.
236
+ *
237
+ * A path outside the parent has a relative form starting with `..`, which every
238
+ * platform answers the same way. Comparing the text against a literal separator is
239
+ * not: Windows separates with a backslash, so a nested path never matched its own
240
+ * ancestor and every Windows installation reported the distribution as sitting
241
+ * outside its own tree.
242
+ *
243
+ * @param candidate - absolute path to test.
244
+ * @param parent - absolute path that may contain it.
245
+ * @param platform - separating convention, injectable so the Windows answer is
246
+ * testable where the suite runs on a POSIX host.
247
+ * @returns true when the candidate is the parent or inside it.
248
+ */
249
+ function isWithin(candidate, parent, platform = process.platform) {
250
+ if (candidate === parent) return true;
251
+ const path = platform === "win32" ? win32 : posix;
252
+ const inside = path.relative(parent, candidate);
253
+ return inside !== "" && !inside.startsWith("..") && !inside.startsWith(path.sep + "..");
254
+ }
255
+ /**
235
256
  * Resolve the installed distribution directory from one requiring anchor.
236
257
  *
237
258
  * The anchor must be a path inside the consumer's own tree. Resolving from this
@@ -250,7 +271,7 @@ function resolveDistributionDirectory(anchor) {
250
271
  }
251
272
  let current = resolve(dirname(anchor));
252
273
  for (;;) {
253
- if (resolved === current || resolved.startsWith(current + "/")) return resolved;
274
+ if (isWithin(resolved, current)) return resolved;
254
275
  const parent = dirname(current);
255
276
  if (parent === current) break;
256
277
  current = parent;
@@ -21,6 +21,22 @@ export interface StandalonePaths {
21
21
  }
22
22
  /** Resolve the DSH home, honouring the environment override the launcher itself reads. */
23
23
  export declare function resolveHome(env?: NodeJS.ProcessEnv): string;
24
+ /**
25
+ * Whether one absolute path is the other or sits beneath it.
26
+ *
27
+ * A path outside the parent has a relative form starting with `..`, which every
28
+ * platform answers the same way. Comparing the text against a literal separator is
29
+ * not: Windows separates with a backslash, so a nested path never matched its own
30
+ * ancestor and every Windows installation reported the distribution as sitting
31
+ * outside its own tree.
32
+ *
33
+ * @param candidate - absolute path to test.
34
+ * @param parent - absolute path that may contain it.
35
+ * @param platform - separating convention, injectable so the Windows answer is
36
+ * testable where the suite runs on a POSIX host.
37
+ * @returns true when the candidate is the parent or inside it.
38
+ */
39
+ export declare function isWithin(candidate: string, parent: string, platform?: NodeJS.Platform): boolean;
24
40
  /**
25
41
  * Resolve the installed distribution directory from one requiring anchor.
26
42
  *
@@ -11,7 +11,7 @@
11
11
  import { existsSync, mkdirSync, readdirSync, readFileSync, symlinkSync, writeFileSync } from 'node:fs';
12
12
  import { createRequire } from 'node:module';
13
13
  import { homedir } from 'node:os';
14
- import { dirname, join, resolve } from 'node:path';
14
+ import { dirname, join, posix, resolve, win32 } from 'node:path';
15
15
  /** Profile name a standalone installation owns. */
16
16
  export const STANDALONE_PROFILE = 'plus';
17
17
  function requireRecord(value, label) {
@@ -29,6 +29,28 @@ export function resolveHome(env = process.env) {
29
29
  const configured = env.DSH_HOME;
30
30
  return configured === undefined || configured === '' ? join(homedir(), '.dsh') : resolve(configured);
31
31
  }
32
+ /**
33
+ * Whether one absolute path is the other or sits beneath it.
34
+ *
35
+ * A path outside the parent has a relative form starting with `..`, which every
36
+ * platform answers the same way. Comparing the text against a literal separator is
37
+ * not: Windows separates with a backslash, so a nested path never matched its own
38
+ * ancestor and every Windows installation reported the distribution as sitting
39
+ * outside its own tree.
40
+ *
41
+ * @param candidate - absolute path to test.
42
+ * @param parent - absolute path that may contain it.
43
+ * @param platform - separating convention, injectable so the Windows answer is
44
+ * testable where the suite runs on a POSIX host.
45
+ * @returns true when the candidate is the parent or inside it.
46
+ */
47
+ export function isWithin(candidate, parent, platform = process.platform) {
48
+ if (candidate === parent)
49
+ return true;
50
+ const path = platform === 'win32' ? win32 : posix;
51
+ const inside = path.relative(parent, candidate);
52
+ return inside !== '' && !inside.startsWith('..') && !inside.startsWith(path.sep + '..');
53
+ }
32
54
  /**
33
55
  * Resolve the installed distribution directory from one requiring anchor.
34
56
  *
@@ -54,7 +76,7 @@ export function resolveDistributionDirectory(anchor) {
54
76
  // reports \`<root>/node_modules/@sparkelf/dsh-plus\`.
55
77
  let current = resolve(dirname(anchor));
56
78
  for (;;) {
57
- if (resolved === current || resolved.startsWith(current + '/'))
79
+ if (isWithin(resolved, current))
58
80
  return resolved;
59
81
  const parent = dirname(current);
60
82
  if (parent === current)
package/package.json CHANGED
@@ -138,5 +138,5 @@
138
138
  },
139
139
  "type": "module",
140
140
  "types": "lib/types/index.d.ts",
141
- "version": "0.1.0-rc.30"
141
+ "version": "0.1.0-rc.31"
142
142
  }