@weborigami/origami 0.0.43 → 0.0.45
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/exports/exports.js +10 -7
- package/package.json +5 -4
- package/src/builtins/@arrows.js +1 -1
- package/src/builtins/@count.js +1 -1
- package/src/builtins/@inline.js +11 -0
- package/src/builtins/@loaders/css.js +2 -4
- package/src/builtins/@loaders/htm.js +2 -4
- package/src/builtins/@loaders/html.js +2 -4
- package/src/builtins/@loaders/jpeg.js +55 -0
- package/src/builtins/@loaders/jpg.js +2 -0
- package/src/builtins/@loaders/json.js +7 -1
- package/src/builtins/@loaders/md.js +2 -4
- package/src/builtins/@loaders/mjs.js +2 -4
- package/src/builtins/@loaders/ori.js +4 -4
- package/src/builtins/@loaders/txt.js +5 -1
- package/src/builtins/@loaders/wasm.js +11 -0
- package/src/builtins/@loaders/xhtml.js +2 -4
- package/src/builtins/@loaders/yaml.js +6 -1
- package/src/builtins/@loaders/yml.js +2 -4
- package/src/builtins/@node.js +12 -1
- package/src/builtins/@ori.js +3 -3
- package/src/builtins/@rss.js +8 -6
- package/src/common/CommandModulesTransform.js +1 -1
- package/src/common/TextDocument.js +2 -1
- package/src/common/processUnpackedContent.js +6 -4
- package/src/common/utilities.d.ts +0 -1
- package/src/common/utilities.js +0 -2
- package/src/misc/yamlOrigamiTag.js +2 -2
package/exports/exports.js
CHANGED
|
@@ -38,18 +38,21 @@ export { default as js } from "../src/builtins/@js.js";
|
|
|
38
38
|
export { default as json } from "../src/builtins/@json.js";
|
|
39
39
|
export { default as keys } from "../src/builtins/@keys.js";
|
|
40
40
|
export { default as keysJson } from "../src/builtins/@keysJson.js";
|
|
41
|
-
export
|
|
42
|
-
export
|
|
43
|
-
export
|
|
41
|
+
export * from "../src/builtins/@loaders/css.js";
|
|
42
|
+
export * from "../src/builtins/@loaders/htm.js";
|
|
43
|
+
export * from "../src/builtins/@loaders/html.js";
|
|
44
|
+
export { default as loadersJpeg } from "../src/builtins/@loaders/jpeg.js";
|
|
45
|
+
export * from "../src/builtins/@loaders/jpg.js";
|
|
44
46
|
export { default as loadersJs } from "../src/builtins/@loaders/js.js";
|
|
45
47
|
export { default as loadersJson } from "../src/builtins/@loaders/json.js";
|
|
46
|
-
export
|
|
47
|
-
export
|
|
48
|
+
export * from "../src/builtins/@loaders/md.js";
|
|
49
|
+
export * from "../src/builtins/@loaders/mjs.js";
|
|
48
50
|
export { default as loadersOri } from "../src/builtins/@loaders/ori.js";
|
|
49
51
|
export { default as loadersTxt } from "../src/builtins/@loaders/txt.js";
|
|
50
|
-
export { default as
|
|
52
|
+
export { default as loadersWasm } from "../src/builtins/@loaders/wasm.js";
|
|
53
|
+
export * from "../src/builtins/@loaders/xhtml.js";
|
|
51
54
|
export { default as loadersYaml } from "../src/builtins/@loaders/yaml.js";
|
|
52
|
-
export
|
|
55
|
+
export * from "../src/builtins/@loaders/yml.js";
|
|
53
56
|
export { default as map } from "../src/builtins/@map.js";
|
|
54
57
|
export { default as mapDeep } from "../src/builtins/@mapDeep.js";
|
|
55
58
|
export { default as match } from "../src/builtins/@match.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/origami",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.45",
|
|
4
4
|
"description": "Web Origami language, CLI, framework, and server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -19,9 +19,10 @@
|
|
|
19
19
|
"typescript": "5.3.3"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@weborigami/async-tree": "0.0.
|
|
23
|
-
"@weborigami/language": "0.0.
|
|
24
|
-
"@weborigami/types": "0.0.
|
|
22
|
+
"@weborigami/async-tree": "0.0.45",
|
|
23
|
+
"@weborigami/language": "0.0.45",
|
|
24
|
+
"@weborigami/types": "0.0.45",
|
|
25
|
+
"exif-parser": "0.1.12",
|
|
25
26
|
"graphviz-wasm": "3.0.1",
|
|
26
27
|
"highlight.js": "11.9.0",
|
|
27
28
|
"marked": "11.1.1",
|
package/src/builtins/@arrows.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Scope, functionResultsMap } from "@weborigami/language";
|
|
2
|
-
import builtins from "../../src/builtins/@builtins.js";
|
|
3
2
|
import arrowFunctionsMap from "../common/arrowFunctionsMap.js";
|
|
4
3
|
import { keySymbol } from "../common/utilities.js";
|
|
5
4
|
import getTreeArgument from "../misc/getTreeArgument.js";
|
|
5
|
+
import builtins from "./@builtins.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Interpret arrow keys in the tree as function calls.
|
package/src/builtins/@count.js
CHANGED
|
@@ -10,7 +10,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
10
10
|
*/
|
|
11
11
|
export default async function count(treelike) {
|
|
12
12
|
const tree = await getTreeArgument(this, arguments, treelike, "@count");
|
|
13
|
-
const keys =
|
|
13
|
+
const keys = Array.from(await tree.keys());
|
|
14
14
|
return keys.length;
|
|
15
15
|
}
|
|
16
16
|
|
package/src/builtins/@inline.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Tree, isPlainObject } from "@weborigami/async-tree";
|
|
1
2
|
import { compile } from "@weborigami/language";
|
|
2
3
|
import unpackText from "../builtins/@loaders/txt.js";
|
|
3
4
|
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
@@ -28,7 +29,17 @@ export default async function inline(input) {
|
|
|
28
29
|
inputDocument = await unpackText(input);
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
// If the input document is a plain object or AsyncTree, we'll have it
|
|
33
|
+
// included in scope for the evaluated expression. We ignore other kinds of
|
|
34
|
+
// treelike inputs for this test: in particular, a Buffer will be interpreted
|
|
35
|
+
// as a tree, but we don't want to put a Buffer in scope.
|
|
36
|
+
const attachedData =
|
|
37
|
+
isPlainObject(inputDocument) || Tree.isAsyncTree(inputDocument)
|
|
38
|
+
? inputDocument
|
|
39
|
+
: null;
|
|
40
|
+
|
|
31
41
|
const templateFn = await unpackOrigamiExpression(inputDocument, {
|
|
42
|
+
attachedData,
|
|
32
43
|
compiler: compile.templateDocument,
|
|
33
44
|
});
|
|
34
45
|
const templateResult = await templateFn(inputDocument);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import exifParser from "exif-parser";
|
|
2
|
+
|
|
3
|
+
const exifDateTags = [
|
|
4
|
+
"ModifyDate",
|
|
5
|
+
"MDPrepDate",
|
|
6
|
+
"DateTimeOriginal",
|
|
7
|
+
"CreateDate",
|
|
8
|
+
"PreviewDateTime",
|
|
9
|
+
"GPSDateStamp",
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Load Exif data from a JPEG file.
|
|
14
|
+
*
|
|
15
|
+
* @type {import("@weborigami/language").FileUnpackFunction}
|
|
16
|
+
*/
|
|
17
|
+
export default async function unpackJpeg(buffer, options) {
|
|
18
|
+
const parser = exifParser.create(buffer);
|
|
19
|
+
parser.enableTagNames(true);
|
|
20
|
+
parser.enableSimpleValues(true);
|
|
21
|
+
const parsed = await parser.parse();
|
|
22
|
+
|
|
23
|
+
// The exif-parser `enableSimpleValues` option should convert dates to
|
|
24
|
+
// JavaScript Date objects, but that doesn't seem to work. Ensure dates are
|
|
25
|
+
// Date objects.
|
|
26
|
+
const exif = parsed.tags;
|
|
27
|
+
for (const tag of exifDateTags) {
|
|
28
|
+
if (typeof exif[tag] === "number") {
|
|
29
|
+
exif[tag] = new Date(exif[tag] * 1000);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = {
|
|
34
|
+
height: parsed.imageSize.height,
|
|
35
|
+
width: parsed.imageSize.width,
|
|
36
|
+
exif,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Promote some Exif properties to the top level.
|
|
40
|
+
const tagsToPromote = {
|
|
41
|
+
ImageDescription: "caption",
|
|
42
|
+
ModifyDate: "modified",
|
|
43
|
+
Orientation: "orientation",
|
|
44
|
+
};
|
|
45
|
+
for (const [tag, key] of Object.entries(tagsToPromote)) {
|
|
46
|
+
if (exif[tag] !== undefined) {
|
|
47
|
+
result[key] = exif[tag];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Add aspect ratio for use with `aspect-ratio` CSS.
|
|
52
|
+
result.aspectRatio = result.width / result.height;
|
|
53
|
+
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import * as utilities from "../../common/utilities.js";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Load a file as JSON.
|
|
3
5
|
*
|
|
4
6
|
* @type {import("@weborigami/language").FileUnpackFunction}
|
|
5
7
|
*/
|
|
6
8
|
export default function unpackJson(input) {
|
|
7
|
-
|
|
9
|
+
const json = utilities.toString(input);
|
|
10
|
+
if (!json) {
|
|
11
|
+
throw new Error("Tried to parse something as JSON but it wasn't text.");
|
|
12
|
+
}
|
|
13
|
+
return JSON.parse(json);
|
|
8
14
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Scope } from "@weborigami/language";
|
|
2
|
-
import * as compile from "../../../../language/src/compiler/compile.js";
|
|
1
|
+
import { Scope, compile, symbols } from "@weborigami/language";
|
|
3
2
|
import processUnpackedContent from "../../common/processUnpackedContent.js";
|
|
4
3
|
import * as utilities from "../../common/utilities.js";
|
|
5
4
|
import builtins from "../@builtins.js";
|
|
@@ -13,10 +12,11 @@ export default async function unpackOrigamiExpression(
|
|
|
13
12
|
inputDocument,
|
|
14
13
|
options = {}
|
|
15
14
|
) {
|
|
15
|
+
const attachedData = options.attachedData;
|
|
16
16
|
const parent =
|
|
17
17
|
options.parent ??
|
|
18
18
|
/** @type {any} */ (inputDocument).parent ??
|
|
19
|
-
/** @type {any} */ (inputDocument)[
|
|
19
|
+
/** @type {any} */ (inputDocument)[symbols.parent];
|
|
20
20
|
|
|
21
21
|
// Construct an object to represent the source code.
|
|
22
22
|
const sourceName = options.key;
|
|
@@ -41,5 +41,5 @@ export default async function unpackOrigamiExpression(
|
|
|
41
41
|
const parentScope = parent ? Scope.getScope(parent) : builtins;
|
|
42
42
|
let content = await fn.call(parentScope);
|
|
43
43
|
|
|
44
|
-
return processUnpackedContent(content, parent,
|
|
44
|
+
return processUnpackedContent(content, parent, attachedData);
|
|
45
45
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import TextDocument from "../../common/TextDocument.js";
|
|
2
2
|
import { evaluateYaml } from "../../common/serialize.js";
|
|
3
|
+
import * as utilities from "../../common/utilities.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Load a file as text document with possible front matter.
|
|
@@ -16,7 +17,10 @@ import { evaluateYaml } from "../../common/serialize.js";
|
|
|
16
17
|
*/
|
|
17
18
|
export default async function unpackText(input, options = {}) {
|
|
18
19
|
const parent = options.parent ?? null;
|
|
19
|
-
const text =
|
|
20
|
+
const text = utilities.toString(input);
|
|
21
|
+
if (!text) {
|
|
22
|
+
throw new Error("Tried to treat something as text but it wasn't text.");
|
|
23
|
+
}
|
|
20
24
|
const regex =
|
|
21
25
|
/^(---\r?\n(?<frontText>[\s\S]*?\r?\n)---\r?\n)(?<body>[\s\S]*$)/;
|
|
22
26
|
const match = regex.exec(text);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import processUnpackedContent from "../../common/processUnpackedContent.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Load a .js file as module's default export or exports.
|
|
5
|
+
*
|
|
6
|
+
* @type {import("@weborigami/language").FileUnpackFunction}
|
|
7
|
+
*/
|
|
8
|
+
export default async function unpackWasm(buffer, options = {}) {
|
|
9
|
+
const wasmModule = await WebAssembly.instantiate(buffer);
|
|
10
|
+
return processUnpackedContent(wasmModule.instance.exports, options.parent);
|
|
11
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as YAMLModule from "yaml";
|
|
2
2
|
import processUnpackedContent from "../../common/processUnpackedContent.js";
|
|
3
3
|
import { evaluateYaml } from "../../common/serialize.js";
|
|
4
|
+
import * as utilities from "../../common/utilities.js";
|
|
4
5
|
|
|
5
6
|
// See notes at serialize.js
|
|
6
7
|
// @ts-ignore
|
|
@@ -13,6 +14,10 @@ const YAML = YAMLModule.default ?? YAMLModule.YAML;
|
|
|
13
14
|
*/
|
|
14
15
|
export default async function unpackYaml(input, options = {}) {
|
|
15
16
|
const parent = options.parent ?? null;
|
|
16
|
-
const
|
|
17
|
+
const yaml = utilities.toString(input);
|
|
18
|
+
if (!yaml) {
|
|
19
|
+
throw new Error("Tried to parse something as YAML but it wasn't text.");
|
|
20
|
+
}
|
|
21
|
+
const data = await evaluateYaml(yaml, options.parent);
|
|
17
22
|
return processUnpackedContent(data, parent);
|
|
18
23
|
}
|
package/src/builtins/@node.js
CHANGED
|
@@ -2,10 +2,21 @@ import path from "node:path";
|
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import url from "node:url";
|
|
4
4
|
|
|
5
|
+
// Patch process.env to be a plain object. Among other things, this lets us dump
|
|
6
|
+
// the complete environment to the terminal with `ori @node/process/env`.
|
|
7
|
+
const patchedProcess = Object.create(null, {
|
|
8
|
+
...Object.getOwnPropertyDescriptors(process),
|
|
9
|
+
env: {
|
|
10
|
+
value: function () {
|
|
11
|
+
return Object.assign({}, process.env);
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
5
16
|
const node = {
|
|
6
17
|
Buffer,
|
|
7
18
|
path,
|
|
8
|
-
process,
|
|
19
|
+
process: patchedProcess,
|
|
9
20
|
url,
|
|
10
21
|
};
|
|
11
22
|
|
package/src/builtins/@ori.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tree, getRealmObjectPrototype } from "@weborigami/async-tree";
|
|
2
|
-
import
|
|
2
|
+
import { compile } from "@weborigami/language";
|
|
3
3
|
import builtins from "../builtins/@builtins.js";
|
|
4
4
|
import { toYaml } from "../common/serialize.js";
|
|
5
5
|
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
@@ -73,13 +73,13 @@ async function formatResult(result) {
|
|
|
73
73
|
text = result;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
// If the result is
|
|
76
|
+
// If the result is treelike, attach it to the text output.
|
|
77
77
|
if (Tree.isTreelike(result)) {
|
|
78
78
|
if (typeof text === "string") {
|
|
79
79
|
// @ts-ignore
|
|
80
80
|
text = new String(text);
|
|
81
81
|
}
|
|
82
|
-
/** @type {any} */ (text).unpack = () =>
|
|
82
|
+
/** @type {any} */ (text).unpack = () => result;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
return text;
|
package/src/builtins/@rss.js
CHANGED
|
@@ -18,7 +18,7 @@ export default async function rss(jsonFeedTree) {
|
|
|
18
18
|
parts.push("rss.xml");
|
|
19
19
|
const rssUrl = parts.join("/");
|
|
20
20
|
|
|
21
|
-
const itemsRss = items?.map((story) => itemRss(story)).join("
|
|
21
|
+
const itemsRss = items?.map((story) => itemRss(story)).join("") ?? [];
|
|
22
22
|
|
|
23
23
|
return `<?xml version="1.0" ?>
|
|
24
24
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
|
@@ -27,7 +27,7 @@ export default async function rss(jsonFeedTree) {
|
|
|
27
27
|
<title>${title}</title>
|
|
28
28
|
<link>${home_page_url}</link>
|
|
29
29
|
<description>${description}</description>
|
|
30
|
-
|
|
30
|
+
${itemsRss}</channel>
|
|
31
31
|
</rss>`;
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -36,12 +36,14 @@ function itemRss(jsonFeedItem) {
|
|
|
36
36
|
// RSS wants dates in RFC-822.
|
|
37
37
|
const date = date_published?.toUTCString() ?? null;
|
|
38
38
|
const dateElement = date ? ` <pubDate>${date}</pubDate>\n` : "";
|
|
39
|
+
const guidElement = id ? ` <guid>${id}</guid>\n` : "";
|
|
40
|
+
const contentElement = content_html
|
|
41
|
+
? ` <description><![CDATA[${content_html}]]></description>\n`
|
|
42
|
+
: "";
|
|
39
43
|
return ` <item>
|
|
40
|
-
|
|
44
|
+
${dateElement} <title>${title}</title>
|
|
41
45
|
<link>${url}</link>
|
|
42
|
-
|
|
43
|
-
<description><![CDATA[${content_html}]]></description>
|
|
44
|
-
</item>
|
|
46
|
+
${guidElement}${contentElement} </item>
|
|
45
47
|
`;
|
|
46
48
|
}
|
|
47
49
|
|
|
@@ -27,7 +27,7 @@ export default function CommandsModulesTransform(Base) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
async keys() {
|
|
30
|
-
const keys =
|
|
30
|
+
const keys = Array.from(await super.keys());
|
|
31
31
|
// If we find a key like "foo.js", then return "foo" as the key.
|
|
32
32
|
return keys.map((key) =>
|
|
33
33
|
key.endsWith(".js") ? path.basename(key, ".js") : key
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isStringLike } from "@weborigami/async-tree";
|
|
2
|
+
import { symbols } from "@weborigami/language";
|
|
2
3
|
import { toYaml } from "./serialize.js";
|
|
3
4
|
import * as utilities from "./utilities.js";
|
|
4
5
|
|
|
@@ -22,7 +23,7 @@ export default class TextDocument {
|
|
|
22
23
|
constructor(data, parent) {
|
|
23
24
|
Object.assign(this, data);
|
|
24
25
|
if (parent) {
|
|
25
|
-
this[
|
|
26
|
+
this[symbols.parent] = parent;
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -10,18 +10,20 @@ import builtins from "../builtins/@builtins.js";
|
|
|
10
10
|
*
|
|
11
11
|
* @param {any} content
|
|
12
12
|
* @param {AsyncTree|null} parent
|
|
13
|
-
* @param {any} [
|
|
13
|
+
* @param {any} [attachedData]
|
|
14
14
|
* @returns
|
|
15
15
|
*/
|
|
16
|
-
export default function processUnpackedContent(content, parent,
|
|
16
|
+
export default function processUnpackedContent(content, parent, attachedData) {
|
|
17
17
|
if (typeof content === "function") {
|
|
18
18
|
// Wrap the function such to add ambients to the scope.
|
|
19
19
|
const fn = content;
|
|
20
20
|
|
|
21
21
|
// Use the parent's scope, adding any attached data.
|
|
22
22
|
const parentScope = parent ? Scope.getScope(parent) : builtins;
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
|
|
24
|
+
// If there's attached data, include it in the scope.
|
|
25
|
+
const extendedScope = attachedData
|
|
26
|
+
? new Scope(attachedData, parentScope)
|
|
25
27
|
: parentScope;
|
|
26
28
|
|
|
27
29
|
const boundFn = fn.bind(extendedScope);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
|
|
2
2
|
export const keySymbol: unique symbol;
|
|
3
|
-
export const parentSymbol: unique symbol;
|
|
4
3
|
export function hasNonPrintableCharacters(text: string): boolean;
|
|
5
4
|
export function isTransformApplied(Transform: Function, object: any): boolean;
|
|
6
5
|
export function replaceExtension(key: string, sourceExtension: string, resultExtension: string): string;
|
package/src/common/utilities.js
CHANGED
|
@@ -30,8 +30,6 @@ export function isTransformApplied(Transform, obj) {
|
|
|
30
30
|
|
|
31
31
|
export const keySymbol = Symbol("key");
|
|
32
32
|
|
|
33
|
-
export const parentSymbol = Symbol("parent");
|
|
34
|
-
|
|
35
33
|
/**
|
|
36
34
|
* If the given key ends in the source extension (which will generally include a
|
|
37
35
|
* period), replace that extension with the result extension (which again should
|