@weborigami/origami 0.0.61 → 0.0.62

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.
@@ -98,6 +98,7 @@ export { default as treeHttp } from "../src/builtins/@treeHttp.js";
98
98
  export { default as treeHttps } from "../src/builtins/@treeHttps.js";
99
99
  export { default as unpack } from "../src/builtins/@unpack.js";
100
100
  export { default as values } from "../src/builtins/@values.js";
101
+ export { default as version } from "../src/builtins/@version.js";
101
102
  export { default as watch } from "../src/builtins/@watch.js";
102
103
  export { default as yaml } from "../src/builtins/@yaml.js";
103
104
  export { default as yamlParse } from "../src/builtins/@yamlParse.js";
@@ -110,6 +111,7 @@ export { default as jsHandler } from "../src/builtins/js_handler.js";
110
111
  export { default as jsonHandler } from "../src/builtins/json_handler.js";
111
112
  export { default as mdHandler } from "../src/builtins/md_handler.js";
112
113
  export { default as mjsHandler } from "../src/builtins/mjs_handler.js";
114
+ export { default as oriDocumentHandler } from "../src/builtins/ori_document_handler.js";
113
115
  export { default as oriHandler } from "../src/builtins/ori_handler.js";
114
116
  export { default as txtHandler } from "../src/builtins/txt_handler.js";
115
117
  export { default as wasmHandler } from "../src/builtins/wasm_handler.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/origami",
3
- "version": "0.0.61",
3
+ "version": "0.0.62",
4
4
  "description": "Web Origami language, CLI, framework, and server",
5
5
  "type": "module",
6
6
  "repository": {
@@ -17,9 +17,9 @@
17
17
  "typescript": "5.5.3"
18
18
  },
19
19
  "dependencies": {
20
- "@weborigami/async-tree": "0.0.61",
21
- "@weborigami/language": "0.0.61",
22
- "@weborigami/types": "0.0.61",
20
+ "@weborigami/async-tree": "0.0.62",
21
+ "@weborigami/language": "0.0.62",
22
+ "@weborigami/types": "0.0.62",
23
23
  "exif-parser": "0.1.12",
24
24
  "graphviz-wasm": "3.0.2",
25
25
  "highlight.js": "11.9.0",
@@ -3,8 +3,8 @@ import { Tree } from "@weborigami/async-tree";
3
3
  // Given an old tree and a new tree, return a tree of changes indicated
4
4
  // by the values: "added", "changed", or "deleted".
5
5
  export default async function changes(oldTreelike, newTreelike) {
6
- const oldTree = Tree.from(oldTreelike);
7
- const newTree = Tree.from(newTreelike);
6
+ const oldTree = Tree.from(oldTreelike, { deep: true });
7
+ const newTree = Tree.from(newTreelike, { deep: true });
8
8
 
9
9
  const oldKeys = Array.from(await oldTree.keys());
10
10
  const newKeys = Array.from(await newTree.keys());
@@ -11,7 +11,13 @@ import getTreeArgument from "../misc/getTreeArgument.js";
11
11
  * @param {Treelike} [treelike]
12
12
  */
13
13
  export default async function deepValuesBuiltin(treelike) {
14
- const tree = await getTreeArgument(this, arguments, treelike, "@valuesDeep");
14
+ const tree = await getTreeArgument(
15
+ this,
16
+ arguments,
17
+ treelike,
18
+ "@valuesDeep",
19
+ true
20
+ );
15
21
  return deepValues(tree);
16
22
  }
17
23
 
@@ -41,9 +41,9 @@ export default async function rss(jsonFeedTree, options = {}) {
41
41
 
42
42
  const itemsRss = items?.map((story) => itemRss(story)).join("") ?? [];
43
43
 
44
- const titleElement = title ? ` <title>![CDATA[${title}]]</title>\n` : "";
44
+ const titleElement = title ? ` <title>${escapeXml(title)}</title>\n` : "";
45
45
  const descriptionElement = description
46
- ? ` <description>${description}</description>\n`
46
+ ? ` <description>${escapeXml(description)}</description>\n`
47
47
  : "";
48
48
  const linkElement = home_page_url
49
49
  ? ` <link>${home_page_url}</link>\n`
@@ -78,13 +78,13 @@ function itemRss(jsonFeedItem) {
78
78
  id !== undefined && !URL.canParse(id) ? ` isPermaLink="false"` : "";
79
79
  const guidElement = id ? ` <guid${isPermaLink}>${id}</guid>\n` : "";
80
80
  const descriptionElement = summary
81
- ? ` <description><![CDATA[${summary}]]></description>\n`
81
+ ? ` <description>${escapeXml(summary)}</description>\n`
82
82
  : "";
83
83
  const contentElement = content_html
84
84
  ? ` <content:encoded><![CDATA[${content_html}]]></content:encoded>\n`
85
85
  : "";
86
86
  const titleElement = title
87
- ? ` <title><![CDATA[${title}]]></title>\n`
87
+ ? ` <title>${escapeXml(title)}</title>\n`
88
88
  : "";
89
89
  const linkElement = url ? ` <link>${url}</link>\n` : "";
90
90
 
@@ -93,6 +93,16 @@ ${dateElement}${titleElement}${linkElement}${guidElement}${descriptionElement}${
93
93
  `;
94
94
  }
95
95
 
96
+ // Escape XML entities for in the text.
97
+ function escapeXml(text) {
98
+ return text
99
+ .replace(/&/g, "&amp;")
100
+ .replace(/</g, "&lt;")
101
+ .replace(/>/g, "&gt;")
102
+ .replace(/"/g, "&quot;")
103
+ .replace(/'/g, "&apos;");
104
+ }
105
+
96
106
  // RSS wants dates in RFC-822.
97
107
  function toRFC822Date(date) {
98
108
  const day = days[date.getUTCDay()];
@@ -0,0 +1,13 @@
1
+ // When this is no longer experimental in Node:
2
+ // import packageJson from "../../package.json" with { type: "json" };
3
+
4
+ import fs from "node:fs/promises";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const packageJsonPath = path.resolve(dirname, "../../package.json");
10
+ const buffer = await fs.readFile(packageJsonPath);
11
+ const data = JSON.parse(String(buffer));
12
+
13
+ export default data.version;
@@ -0,0 +1,43 @@
1
+ import { symbols } from "@weborigami/async-tree";
2
+ import { compile } from "@weborigami/language";
3
+ import processUnpackedContent from "../common/processUnpackedContent.js";
4
+ import * as utilities from "../common/utilities.js";
5
+
6
+ /**
7
+ * An Origami template document: a plain text file that contains Origami
8
+ * expressions.
9
+ */
10
+ export default {
11
+ mediaType: "text/plain",
12
+
13
+ /** @type {import("@weborigami/language").UnpackFunction} */
14
+ async unpack(packed, options = {}) {
15
+ const parent =
16
+ options.parent ??
17
+ /** @type {any} */ (packed).parent ??
18
+ /** @type {any} */ (packed)[symbols.parent];
19
+
20
+ // Construct an object to represent the source code.
21
+ const sourceName = options.key;
22
+ let url;
23
+ if (sourceName && parent?.url) {
24
+ let parentHref = parent.url.href;
25
+ if (!parentHref.endsWith("/")) {
26
+ parentHref += "/";
27
+ }
28
+ url = new URL(sourceName, parentHref);
29
+ }
30
+
31
+ const source = {
32
+ text: utilities.toString(packed),
33
+ name: options.key,
34
+ url,
35
+ };
36
+
37
+ // Compile the text as an Origami template document.
38
+ const templateDefineFn = compile.templateDocument(source);
39
+ const templateFn = await templateDefineFn.call(parent);
40
+
41
+ return processUnpackedContent(templateFn, parent);
42
+ },
43
+ };
@@ -1,4 +1,4 @@
1
- import { Tree } from "@weborigami/async-tree";
1
+ import { symbols, Tree } from "@weborigami/async-tree";
2
2
  import builtins from "../builtins/@builtins.js";
3
3
 
4
4
  /**
@@ -29,6 +29,14 @@ export default function processUnpackedContent(content, parent, attachedData) {
29
29
  const result = Object.create(content);
30
30
  result.parent = parent;
31
31
  return result;
32
+ } else if (Object.isExtensible(content) && !content[symbols.parent]) {
33
+ Object.defineProperty(content, symbols.parent, {
34
+ configurable: true,
35
+ enumerable: false,
36
+ value: parent,
37
+ writable: true,
38
+ });
39
+ return content;
32
40
  } else {
33
41
  return content;
34
42
  }
@@ -18,13 +18,15 @@ import assertTreeIsDefined from "./assertTreeIsDefined.js";
18
18
  * @param {IArguments} args
19
19
  * @param {Treelike|undefined} treelike
20
20
  * @param {string} methodName
21
+ * @param {boolean} [deep]
21
22
  * @returns {Promise<AsyncTree>}
22
23
  */
23
24
  export default async function getTreeArgument(
24
25
  parent,
25
26
  args,
26
27
  treelike,
27
- methodName
28
+ methodName,
29
+ deep = false
28
30
  ) {
29
31
  assertTreeIsDefined(parent, methodName);
30
32
 
@@ -33,7 +35,7 @@ export default async function getTreeArgument(
33
35
  treelike = await treelike.unpack();
34
36
  }
35
37
  if (isTreelike(treelike)) {
36
- let tree = Tree.from(treelike);
38
+ let tree = Tree.from(treelike, { deep });
37
39
  // If the tree was created from a treelike object and does not yet have a
38
40
  // parent, make the current tree its parent.
39
41
  if (!tree.parent) {