@ts-graphviz/adapter 3.0.7 → 3.0.8

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @ts-graphviz/adapter
2
2
 
3
+ ## 3.0.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1763](https://github.com/ts-graphviz/ts-graphviz/pull/1763) [`24cc46e`](https://github.com/ts-graphviz/ts-graphviz/commit/24cc46ebf0078440fa498f89b21e7224725c16b6) Thanks [@kamiazya](https://github.com/kamiazya)! - Options are read from their own properties only, and values are always written as DOT text:
8
+
9
+ - `toStream` / `toFile`, `parse`, `stringify`, `fromModel` / `toModel`, `fromDot` and `toDot` read only the options their caller set. `toStream` / `toFile` also pass Node.js only the options and environment they set.
10
+ - Attribute keys and values, IDs, ports, compass points and comments are written so that DOT reads them back as the same text. A string of the form `<…>` is written as an HTML-like label only when it is well-formed; otherwise it is written as a quoted string.
11
+ - Writing attribute values and reading block comments are faster on large inputs.
12
+
3
13
  ## 3.0.7
4
14
 
5
15
  ### Patch Changes
package/README.md CHANGED
@@ -22,7 +22,7 @@ Cross-platform interfaces for executing Graphviz DOT commands in various JavaScr
22
22
 
23
23
  [![GitHub](https://img.shields.io/badge/-GitHub-181717?logo=GitHub&style=flat)](https://github.com/ts-graphviz/ts-graphviz)
24
24
  [![npm](https://img.shields.io/badge/-npm-CB3837?logo=npm&style=flat)](https://www.npmjs.com/package/ts-graphviz)
25
- [![Reference](https://img.shields.io/badge/-API_Reference-3178C6?logo=TypeScript&style=flat&logoColor=fff)](https://ts-graphviz.github.io/ts-graphviz/)
25
+ [![Reference](https://img.shields.io/badge/-API_Reference-3178C6?logo=TypeScript&style=flat&logoColor=fff)](https://ts-graphviz.github.io/api/)
26
26
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ts-graphviz/ts-graphviz)
27
27
 
28
28
  [![Sponsor](https://img.shields.io/badge/-GitHub%20Sponsor-fff?logo=GitHub%20Sponsors&style=flat)](https://github.com/sponsors/ts-graphviz)
@@ -249,6 +249,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
249
249
  <td align="center" valign="top" width="14.28%"><a href="http://www.walterra.dev"><img src="https://avatars.githubusercontent.com/u/230104?v=4?s=100" width="100px;" alt="Walter Rafelsberger"/><br /><sub><b>Walter Rafelsberger</b></sub></a><br /><a href="#question-walterra" title="Answering Questions">💬</a></td>
250
250
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/grsjst"><img src="https://avatars.githubusercontent.com/u/4739018?v=4?s=100" width="100px;" alt="grsjst"/><br /><sub><b>grsjst</b></sub></a><br /><a href="https://github.com/ts-graphviz/ts-graphviz/issues?q=author%3Agrsjst" title="Bug reports">🐛</a></td>
251
251
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/stephenirven"><img src="https://avatars.githubusercontent.com/u/4293560?v=4?s=100" width="100px;" alt="Steve"/><br /><sub><b>Steve</b></sub></a><br /><a href="https://github.com/ts-graphviz/ts-graphviz/issues?q=author%3Astephenirven" title="Bug reports">🐛</a></td>
252
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/btomaj"><img src="https://avatars.githubusercontent.com/u/2638986?v=4?s=100" width="100px;" alt="poetry by"/><br /><sub><b>poetry by</b></sub></a><br /><a href="https://github.com/ts-graphviz/ts-graphviz/issues?q=author%3Abtomaj" title="Bug reports">🐛</a></td>
252
253
  </tr>
253
254
  </tbody>
254
255
  </table>
@@ -1,3 +1,14 @@
1
+ function ownOptions(options) {
2
+ const own = /* @__PURE__ */ Object.create(null);
3
+ if (options != null) {
4
+ const descriptors = Object.getOwnPropertyDescriptors(options);
5
+ for (const key of Object.getOwnPropertyNames(descriptors)) {
6
+ const descriptor = descriptors[key];
7
+ own[key] = "value" in descriptor ? descriptor.value : descriptor.get?.call(options);
8
+ }
9
+ }
10
+ return own;
11
+ }
1
12
  function escapeValue(value) {
2
13
  if (value !== true) {
3
14
  if (typeof value === "string" && /\s/g.test(value)) {
@@ -8,39 +19,45 @@ function escapeValue(value) {
8
19
  return "";
9
20
  }
10
21
  function* createCommandArgs(options) {
22
+ const own = ownOptions(options);
11
23
  const {
12
24
  suppressWarnings = true,
13
25
  format = "svg",
14
- attributes = {},
26
+ attributes,
15
27
  library = [],
16
28
  y = false,
17
29
  scale
18
- } = options;
30
+ } = own;
19
31
  if (suppressWarnings) yield "-q";
20
32
  yield `-T${format}`;
21
- if (attributes.graph) {
22
- for (const [key, value] of Object.entries(attributes.graph)) {
33
+ const { graph, node, edge } = ownOptions(attributes);
34
+ if (graph) {
35
+ for (const [key, value] of Object.entries(graph)) {
23
36
  yield `-G${key}${escapeValue(value)}`;
24
37
  }
25
38
  }
26
- if (attributes.node) {
27
- for (const [key, value] of Object.entries(attributes.node)) {
39
+ if (node) {
40
+ for (const [key, value] of Object.entries(node)) {
28
41
  yield `-N${key}${escapeValue(value)}`;
29
42
  }
30
43
  }
31
- if (attributes.edge) {
32
- for (const [key, value] of Object.entries(attributes.edge)) {
44
+ if (edge) {
45
+ for (const [key, value] of Object.entries(edge)) {
33
46
  yield `-E${key}${escapeValue(value)}`;
34
47
  }
35
48
  }
36
49
  if (typeof scale === "number" && !Number.isNaN(scale)) yield `-s${scale}`;
37
- if (Array.isArray(library)) for (const lib of library) yield `-l${lib}`;
50
+ if (Array.isArray(library)) {
51
+ for (let i = 0; i < library.length; i++) {
52
+ if (Object.hasOwn(library, i)) yield `-l${library[i]}`;
53
+ }
54
+ }
38
55
  if (y === true) yield "-y";
39
- if (typeof options.layout === "string") {
40
- yield `-K${options.layout}`;
41
- switch (options.layout) {
56
+ if (typeof own.layout === "string") {
57
+ yield `-K${own.layout}`;
58
+ switch (own.layout) {
42
59
  case "neato": {
43
- const { reduce, noop } = options;
60
+ const { reduce, noop } = own;
44
61
  if (reduce === true) yield "-x";
45
62
  if (typeof noop === "number") yield `-n${noop}`;
46
63
  break;
@@ -53,7 +70,7 @@ function* createCommandArgs(options) {
53
70
  unscaledFactor,
54
71
  overlapExpansionFactor,
55
72
  temperature
56
- } = options;
73
+ } = own;
57
74
  yield ["-L", grid ? "" : "g", oldAttractive ? "O" : ""].join("");
58
75
  if (typeof iterations === "number") yield `-Ln${iterations}`;
59
76
  if (typeof unscaledFactor === "number") yield `-LU${unscaledFactor}`;
@@ -66,7 +83,8 @@ function* createCommandArgs(options) {
66
83
  }
67
84
  }
68
85
  function createCommandAndArgs(options) {
69
- return [options.dotCommand ?? "dot", Array.from(createCommandArgs(options))];
86
+ const own = ownOptions(options);
87
+ return [own.dotCommand ?? "dot", Array.from(createCommandArgs(own))];
70
88
  }
71
89
  export {
72
90
  createCommandAndArgs
package/lib/deno.js CHANGED
@@ -2,6 +2,7 @@ import { createCommandAndArgs } from "./create-command-and-args.js";
2
2
  async function toStream(dot, options) {
3
3
  const [command, args] = createCommandAndArgs(options ?? {});
4
4
  const cp = new Deno.Command(command, {
5
+ __proto__: null,
5
6
  args,
6
7
  stdin: "piped",
7
8
  stdout: "piped"
@@ -13,10 +14,10 @@ async function toStream(dot, options) {
13
14
  }
14
15
  function open(path) {
15
16
  try {
16
- return Deno.open(path, { write: true });
17
+ return Deno.open(path, { __proto__: null, write: true });
17
18
  } catch (e) {
18
19
  if (e instanceof Deno.errors.NotFound) {
19
- return Deno.open(path, { createNew: true, write: true });
20
+ return Deno.open(path, { __proto__: null, createNew: true, write: true });
20
21
  }
21
22
  throw e;
22
23
  }
package/lib/node.js CHANGED
@@ -6,7 +6,12 @@ import { createCommandAndArgs } from "./create-command-and-args.js";
6
6
  async function toStream(dot, options) {
7
7
  const [command, args] = createCommandAndArgs(options ?? {});
8
8
  return new Promise(function toStreamInternal(resolve, reject) {
9
- const p = spawn(command, args, { stdio: "pipe" });
9
+ const p = spawn(command, args, {
10
+ __proto__: null,
11
+ stdio: "pipe",
12
+ shell: false,
13
+ env: ownEnv()
14
+ });
10
15
  p.on("error", (e) => {
11
16
  reject(
12
17
  new Error(`Command "${command}" failed.
@@ -40,9 +45,22 @@ MESSAGE: ${message}`
40
45
  pipeline(Readable.from([dot]), p.stdin);
41
46
  });
42
47
  }
48
+ function ownEnv() {
49
+ const env = /* @__PURE__ */ Object.create(null);
50
+ for (const key of Object.keys(process.env)) {
51
+ env[key] = process.env[key];
52
+ }
53
+ return env;
54
+ }
43
55
  async function toFile(dot, path, options) {
44
56
  const stream = await toStream(dot, options);
45
- await pipeline(stream, createWriteStream(path));
57
+ await pipeline(
58
+ stream,
59
+ createWriteStream(path, {
60
+ __proto__: null,
61
+ flags: "w"
62
+ })
63
+ );
46
64
  }
47
65
  export {
48
66
  toFile,
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The own properties of an options object, in an object without a
3
+ * prototype, so that a property inherited from `Object.prototype` is never
4
+ * read as an option.
5
+ *
6
+ * The property descriptors are taken in one step before any value is read,
7
+ * so an accessor cannot remove another property and expose an inherited one.
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function ownOptions<T extends object>(options: T | undefined): T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ts-graphviz/adapter",
3
- "version": "3.0.7",
3
+ "version": "3.0.8",
4
4
  "description": "Graphviz Runtime adapters for Cross Platform",
5
5
  "keywords": [
6
6
  "graphviz",