@venn-lang/cli 0.1.0 → 0.1.2

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/cli.mjs CHANGED
@@ -1454,6 +1454,29 @@ function readBare(cur) {
1454
1454
  const num = Number(raw);
1455
1455
  return raw !== "" && !Number.isNaN(num) ? num : raw;
1456
1456
  }
1457
+ /**
1458
+ * Keys that reach the prototype rather than the object.
1459
+ *
1460
+ * A manifest is data that arrives with somebody else's project, and assigning
1461
+ * one of these from it changes how every object in the process behaves. A
1462
+ * `venn.toml` containing `[package.__proto__]` was enough to put a property on
1463
+ * `Object.prototype`.
1464
+ */
1465
+ const RESERVED$1 = /* @__PURE__ */ new Set([
1466
+ "__proto__",
1467
+ "constructor",
1468
+ "prototype"
1469
+ ]);
1470
+ /**
1471
+ * Whether a key read from a manifest may be assigned.
1472
+ *
1473
+ * @param key The key exactly as it was written in the file.
1474
+ * @returns `false` for a key that would reach the prototype, which the caller
1475
+ * should skip rather than assign.
1476
+ */
1477
+ function isSafeKey(key) {
1478
+ return !RESERVED$1.has(key);
1479
+ }
1457
1480
  /** The table `[path]` names, created along the way if it is not there yet. */
1458
1481
  function enterSection(root, path) {
1459
1482
  let node = root;
@@ -1481,7 +1504,7 @@ function enterTableArray(root, path) {
1481
1504
  return table;
1482
1505
  }
1483
1506
  function keysOf$1(path) {
1484
- return path.split(".").map((part) => part.trim().replace(/^["']|["']$/g, "")).filter((part) => part !== "");
1507
+ return path.split(".").map((part) => part.trim().replace(/^["']|["']$/g, "")).filter((part) => part !== "" && isSafeKey(part));
1485
1508
  }
1486
1509
  /**
1487
1510
  * A TOML reader for `venn.toml`: sections, nested `[a.b]`, arrays of tables
@@ -1522,6 +1545,7 @@ function assign(section, line) {
1522
1545
  const eq = line.indexOf("=");
1523
1546
  if (eq < 0) return;
1524
1547
  const key = line.slice(0, eq).trim().replace(/^["']|["']$/g, "");
1548
+ if (!isSafeKey(key)) return;
1525
1549
  section[key] = readValue(cursor(line.slice(eq + 1)));
1526
1550
  }
1527
1551
  /**
@@ -9462,9 +9486,9 @@ function addNoneTerminalToCst(node, ruleName, ruleResult) {
9462
9486
  }
9463
9487
  //#endregion
9464
9488
  //#region ../../node_modules/.pnpm/chevrotain@12.0.0/node_modules/chevrotain/lib/src/lang/lang_extensions.js
9465
- const NAME = "name";
9489
+ const NAME$1 = "name";
9466
9490
  function defineNameProp(obj, nameValue) {
9467
- Object.defineProperty(obj, NAME, {
9491
+ Object.defineProperty(obj, NAME$1, {
9468
9492
  enumerable: false,
9469
9493
  configurable: true,
9470
9494
  writable: false,
@@ -55970,20 +55994,41 @@ function isPlugin(value) {
55970
55994
  }
55971
55995
  //#endregion
55972
55996
  //#region src/upgrade/version.ts
55997
+ /** The manifest to accept, so a neighbour's is never read by mistake. */
55998
+ const NAME = "@venn-lang/cli";
55999
+ /** Where the manifest sits relative to this file, in a release and in the tree. */
56000
+ const CANDIDATES = [
56001
+ "../package.json",
56002
+ "../../package.json",
56003
+ "../../../package.json"
56004
+ ];
55973
56005
  /**
55974
56006
  * The version of the CLI that is running.
55975
56007
  *
55976
56008
  * Read from the package manifest rather than written into the source, so a
55977
- * release cannot ship a binary that reports the version before it. The manifest
55978
- * sits one level above the bundle, which is true both in `dist` and in `src`
55979
- * during development.
56009
+ * release cannot ship a binary that reports the version before it.
56010
+ *
56011
+ * The path is searched rather than assumed. The bundle flattens
56012
+ * `src/upgrade/version.ts` into `dist/cli.mjs`, so the manifest is two levels up
56013
+ * while developing and one in a release; assuming either one reports `0.0.0` to
56014
+ * everybody living with the other, and the name check keeps the search from
56015
+ * settling on some other package's manifest on the way up.
55980
56016
  */
55981
56017
  const VERSION = read();
55982
56018
  function read() {
56019
+ const require = createRequire(import.meta.url);
56020
+ for (const path of CANDIDATES) {
56021
+ const version = versionAt(require, path);
56022
+ if (version) return version;
56023
+ }
56024
+ return "0.0.0";
56025
+ }
56026
+ function versionAt(require, path) {
55983
56027
  try {
55984
- return createRequire(import.meta.url)("../../package.json").version ?? "0.0.0";
56028
+ const manifest = require(path);
56029
+ return manifest.name === NAME ? manifest.version : void 0;
55985
56030
  } catch {
55986
- return "0.0.0";
56031
+ return;
55987
56032
  }
55988
56033
  }
55989
56034
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venn-lang/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "The venn binary: one command for starting, checking, running and testing a Venn project.",
5
5
  "keywords": [
6
6
  "venn",
@@ -41,17 +41,17 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "citty": "^0.2.2",
44
- "@venn-lang/assert": "0.1.0",
45
- "@venn-lang/contracts": "0.1.0",
46
- "@venn-lang/core": "0.1.0",
47
- "@venn-lang/dts": "0.1.0",
48
- "@venn-lang/http": "0.1.0",
49
- "@venn-lang/io": "0.1.0",
50
- "@venn-lang/project": "0.1.0",
51
- "@venn-lang/runtime": "0.1.0",
52
- "@venn-lang/sdk": "0.1.0",
53
- "@venn-lang/stdlib": "0.1.0",
54
- "@venn-lang/types": "0.1.0"
44
+ "@venn-lang/assert": "0.1.2",
45
+ "@venn-lang/contracts": "0.1.2",
46
+ "@venn-lang/core": "0.1.2",
47
+ "@venn-lang/dts": "0.1.2",
48
+ "@venn-lang/http": "0.1.2",
49
+ "@venn-lang/io": "0.1.2",
50
+ "@venn-lang/project": "0.1.2",
51
+ "@venn-lang/runtime": "0.1.2",
52
+ "@venn-lang/sdk": "0.1.2",
53
+ "@venn-lang/stdlib": "0.1.2",
54
+ "@venn-lang/types": "0.1.2"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/node": "^24",
@@ -1,21 +1,39 @@
1
1
  import { createRequire } from "node:module";
2
2
 
3
+ /** The manifest to accept, so a neighbour's is never read by mistake. */
4
+ const NAME = "@venn-lang/cli";
5
+
6
+ /** Where the manifest sits relative to this file, in a release and in the tree. */
7
+ const CANDIDATES = ["../package.json", "../../package.json", "../../../package.json"];
8
+
3
9
  /**
4
10
  * The version of the CLI that is running.
5
11
  *
6
12
  * Read from the package manifest rather than written into the source, so a
7
- * release cannot ship a binary that reports the version before it. The manifest
8
- * sits one level above the bundle, which is true both in `dist` and in `src`
9
- * during development.
13
+ * release cannot ship a binary that reports the version before it.
14
+ *
15
+ * The path is searched rather than assumed. The bundle flattens
16
+ * `src/upgrade/version.ts` into `dist/cli.mjs`, so the manifest is two levels up
17
+ * while developing and one in a release; assuming either one reports `0.0.0` to
18
+ * everybody living with the other, and the name check keeps the search from
19
+ * settling on some other package's manifest on the way up.
10
20
  */
11
21
  export const VERSION: string = read();
12
22
 
13
23
  function read(): string {
24
+ const require = createRequire(import.meta.url);
25
+ for (const path of CANDIDATES) {
26
+ const version = versionAt(require, path);
27
+ if (version) return version;
28
+ }
29
+ return "0.0.0";
30
+ }
31
+
32
+ function versionAt(require: ReturnType<typeof createRequire>, path: string): string | undefined {
14
33
  try {
15
- const require = createRequire(import.meta.url);
16
- const manifest = require("../../package.json") as { version?: string };
17
- return manifest.version ?? "0.0.0";
34
+ const manifest = require(path) as { name?: string; version?: string };
35
+ return manifest.name === NAME ? manifest.version : undefined;
18
36
  } catch {
19
- return "0.0.0";
37
+ return undefined;
20
38
  }
21
39
  }