@intentius/chant 0.18.5 → 0.18.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.
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when the module identified by `importMetaUrl` is the process entry point
|
|
3
|
+
* (`process.argv[1]`) — i.e. run directly, not imported.
|
|
4
|
+
*
|
|
5
|
+
* A naive `import.meta.url === \`file://${process.argv[1]}\`` is a false negative
|
|
6
|
+
* whenever the invocation path crosses a symlink (pnpm, global bins, a symlinked
|
|
7
|
+
* checkout, the npm `.bin` shim, `/tmp`→`/private/tmp`): the loader canonicalises
|
|
8
|
+
* `import.meta.url` to the realpath while `argv[1]` keeps the symlink, so the CLI
|
|
9
|
+
* silently exits 0 having done nothing. Canonicalise both sides so the entry
|
|
10
|
+
* point is detected regardless of how the path was spelled.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isEntryPoint(argv1: string | undefined, importMetaUrl: string): boolean;
|
|
13
|
+
//# sourceMappingURL=is-entry-point.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-entry-point.d.ts","sourceRoot":"","sources":["../../src/cli/is-entry-point.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAOtF"}
|
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAMA,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAiB9E;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA2LpD"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, test, expect, beforeAll, afterAll } from "vitest";
|
|
2
|
+
import { isEntryPoint } from "./is-entry-point";
|
|
3
|
+
import { mkdtempSync, writeFileSync, symlinkSync, rmSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
|
|
8
|
+
describe("isEntryPoint", () => {
|
|
9
|
+
let dir: string;
|
|
10
|
+
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
dir = mkdtempSync(join(tmpdir(), "chant-entry-"));
|
|
13
|
+
writeFileSync(join(dir, "cli.ts"), "");
|
|
14
|
+
writeFileSync(join(dir, "marker"), "");
|
|
15
|
+
symlinkSync(join(dir, "cli.ts"), join(dir, "cli-link.ts"));
|
|
16
|
+
});
|
|
17
|
+
afterAll(() => rmSync(dir, { recursive: true, force: true }));
|
|
18
|
+
|
|
19
|
+
test("true when argv1 and import.meta.url are the same real file", () => {
|
|
20
|
+
const file = join(dir, "cli.ts");
|
|
21
|
+
expect(isEntryPoint(file, pathToFileURL(file).href)).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("true when argv1 is a symlink to the file import.meta.url resolves to", () => {
|
|
25
|
+
// The regression: import.meta.url is the realpath (real cli.ts); argv1 is the
|
|
26
|
+
// symlink (cli-link.ts). A raw string compare would be false; this must be true.
|
|
27
|
+
const symlinkArg = join(dir, "cli-link.ts");
|
|
28
|
+
const realUrl = pathToFileURL(join(dir, "cli.ts")).href;
|
|
29
|
+
expect(symlinkArg).not.toBe(join(dir, "cli.ts"));
|
|
30
|
+
expect(isEntryPoint(symlinkArg, realUrl)).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("false for a different file (imported, not the entry point)", () => {
|
|
34
|
+
const other = join(dir, "cli.ts");
|
|
35
|
+
const importedUrl = pathToFileURL(join(dir, "marker")).href;
|
|
36
|
+
expect(isEntryPoint(other, importedUrl)).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("false when there is no argv1", () => {
|
|
40
|
+
expect(isEntryPoint(undefined, pathToFileURL(join(dir, "cli.ts")).href)).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("false (not a throw) when a path does not exist", () => {
|
|
44
|
+
expect(isEntryPoint(join(dir, "gone.ts"), pathToFileURL(join(dir, "cli.ts")).href)).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* True when the module identified by `importMetaUrl` is the process entry point
|
|
6
|
+
* (`process.argv[1]`) — i.e. run directly, not imported.
|
|
7
|
+
*
|
|
8
|
+
* A naive `import.meta.url === \`file://${process.argv[1]}\`` is a false negative
|
|
9
|
+
* whenever the invocation path crosses a symlink (pnpm, global bins, a symlinked
|
|
10
|
+
* checkout, the npm `.bin` shim, `/tmp`→`/private/tmp`): the loader canonicalises
|
|
11
|
+
* `import.meta.url` to the realpath while `argv[1]` keeps the symlink, so the CLI
|
|
12
|
+
* silently exits 0 having done nothing. Canonicalise both sides so the entry
|
|
13
|
+
* point is detected regardless of how the path was spelled.
|
|
14
|
+
*/
|
|
15
|
+
export function isEntryPoint(argv1: string | undefined, importMetaUrl: string): boolean {
|
|
16
|
+
if (!argv1) return false;
|
|
17
|
+
try {
|
|
18
|
+
return realpathSync(argv1) === realpathSync(fileURLToPath(importMetaUrl));
|
|
19
|
+
} catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/cli/main.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
+
import { isEntryPoint } from "./is-entry-point";
|
|
4
5
|
import { formatSuccess, formatError } from "./format";
|
|
5
6
|
import { loadPlugins, resolveProjectLexicons } from "./plugins";
|
|
6
7
|
import { resolveCommand, type CommandDef, type ParsedArgs } from "./registry";
|
|
@@ -536,8 +537,10 @@ async function main(): Promise<void> {
|
|
|
536
537
|
process.exit(await match.def.handler(ctx));
|
|
537
538
|
}
|
|
538
539
|
|
|
539
|
-
// Only run main when executed directly, not when imported
|
|
540
|
-
|
|
540
|
+
// Only run main when executed directly, not when imported. Robust to symlinked
|
|
541
|
+
// invocation paths — see isEntryPoint (a raw string compare silently no-ops the
|
|
542
|
+
// whole CLI through the npm .bin shim / a symlinked checkout).
|
|
543
|
+
const isMain = isEntryPoint(process.argv[1], import.meta.url);
|
|
541
544
|
if (isMain) {
|
|
542
545
|
main().catch((err) => {
|
|
543
546
|
const verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
|