@weborigami/origami 0.0.49 → 0.0.50
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/buildExports.js +2 -2
- package/exports/exports.js +27 -14
- package/package.json +4 -4
- package/src/builtins/@addNextPrevious.js +18 -7
- package/src/builtins/{@arrows.js → @arrowsMap.js} +7 -7
- package/src/builtins/@changes.js +46 -0
- package/src/builtins/@clean.js +19 -0
- package/src/builtins/@constructor.js +17 -0
- package/src/builtins/@crawl.js +2 -2
- package/src/builtins/@deepMap.js +19 -0
- package/src/builtins/@deepMapFn.js +25 -0
- package/src/builtins/{@mergeDeep.js → @deepMerge.js} +7 -7
- package/src/builtins/@deepTake.js +21 -0
- package/src/builtins/@deepTakeFn.js +22 -0
- package/src/builtins/{@valuesDeep.js → @deepValues.js} +6 -5
- package/src/builtins/@files.js +14 -1
- package/src/builtins/@group.js +20 -0
- package/src/builtins/@groupFn.js +30 -0
- package/src/builtins/@if.js +2 -1
- package/src/builtins/@image/format.js +10 -31
- package/src/builtins/@image/formatFn.js +15 -0
- package/src/builtins/@image/resize.js +7 -28
- package/src/builtins/@image/resizeFn.js +14 -0
- package/src/builtins/@invoke.js +1 -1
- package/src/builtins/@json.js +5 -1
- package/src/builtins/@jsonParse.js +9 -0
- package/src/builtins/@map.js +7 -178
- package/src/builtins/@mapFn.js +143 -0
- package/src/builtins/@mdHtml.js +2 -0
- package/src/builtins/@mdTree.js +69 -0
- package/src/builtins/@naturalOrder.js +1 -0
- package/src/builtins/@paginate.js +18 -0
- package/src/builtins/@paginateFn.js +61 -0
- package/src/builtins/@redirect.js +10 -1
- package/src/builtins/@regexParse.js +5 -0
- package/src/builtins/{@makeParser.js → @regexParseFn.js} +1 -1
- package/src/builtins/@sitemap.js +4 -4
- package/src/builtins/@sort.js +10 -7
- package/src/builtins/@sortFn.js +58 -0
- package/src/builtins/@take.js +3 -17
- package/src/builtins/@takeFn.js +21 -0
- package/src/builtins/@tree.js +2 -14
- package/src/builtins/@yaml.js +4 -0
- package/src/builtins/@yamlParse.js +10 -0
- package/src/builtins/map.d.ts +1 -1
- package/src/common/ShuffleTransform.js +3 -3
- package/src/common/{arrowFunctionsMap.js → arrowsMapFn.js} +3 -3
- package/src/common/serialize.js +1 -10
- package/src/misc/explore.ori +7 -7
- package/src/builtins/@apply.js +0 -6
- package/src/builtins/@groupBy.js +0 -37
- package/src/builtins/@isAsyncTree.js +0 -17
- package/src/builtins/@mapDeep.js +0 -71
- package/src/builtins/@new.js +0 -6
- package/src/builtins/@parse/json.js +0 -9
- package/src/builtins/@parse/yaml.js +0 -10
- package/src/builtins/@sortBy.js +0 -37
- package/src/builtins/@with.js +0 -22
package/exports/buildExports.js
CHANGED
|
@@ -103,11 +103,11 @@ function exportStatements(src) {
|
|
|
103
103
|
const withPaths = transformObject(PathTransform, src);
|
|
104
104
|
|
|
105
105
|
// Map each source file to an export statement.
|
|
106
|
-
const mapped = map({
|
|
106
|
+
const mapped = map(withPaths, {
|
|
107
107
|
deep: true,
|
|
108
108
|
value: exportStatementForCode,
|
|
109
109
|
...keyFunctionsForExtensions({ sourceExtension: "js" }),
|
|
110
|
-
})
|
|
110
|
+
});
|
|
111
111
|
|
|
112
112
|
return mapped;
|
|
113
113
|
}
|
package/exports/exports.js
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
// This file is generated by running buildExports.js -- do not edit by hand.
|
|
2
2
|
export { default as addNextPrevious } from "../src/builtins/@addNextPrevious.js";
|
|
3
|
-
export { default as
|
|
4
|
-
export { default as arrows } from "../src/builtins/@arrows.js";
|
|
3
|
+
export { default as arrowsMap } from "../src/builtins/@arrowsMap.js";
|
|
5
4
|
export { default as basename } from "../src/builtins/@basename.js";
|
|
6
5
|
export { default as builtins } from "../src/builtins/@builtins.js";
|
|
7
6
|
export { default as cache } from "../src/builtins/@cache.js";
|
|
7
|
+
export { default as changes } from "../src/builtins/@changes.js";
|
|
8
|
+
export { default as clean } from "../src/builtins/@clean.js";
|
|
8
9
|
export { default as concat } from "../src/builtins/@concat.js";
|
|
9
10
|
export { default as config } from "../src/builtins/@config.js";
|
|
11
|
+
export { default as constructor } from "../src/builtins/@constructor.js";
|
|
10
12
|
export { default as copy } from "../src/builtins/@copy.js";
|
|
11
13
|
export { default as count } from "../src/builtins/@count.js";
|
|
12
14
|
export { default as crawl } from "../src/builtins/@crawl.js";
|
|
13
15
|
export { default as debug } from "../src/builtins/@debug.js";
|
|
16
|
+
export { default as deepMap } from "../src/builtins/@deepMap.js";
|
|
17
|
+
export { default as deepMapFn } from "../src/builtins/@deepMapFn.js";
|
|
18
|
+
export { default as deepMerge } from "../src/builtins/@deepMerge.js";
|
|
19
|
+
export { default as deepTake } from "../src/builtins/@deepTake.js";
|
|
20
|
+
export { default as deepTakeFn } from "../src/builtins/@deepTakeFn.js";
|
|
21
|
+
export { default as deepValues } from "../src/builtins/@deepValues.js";
|
|
14
22
|
export { default as defineds } from "../src/builtins/@defineds.js";
|
|
15
23
|
export { default as document } from "../src/builtins/@document.js";
|
|
16
24
|
export { default as equals } from "../src/builtins/@equals.js";
|
|
@@ -22,31 +30,34 @@ export { default as filter } from "../src/builtins/@filter.js";
|
|
|
22
30
|
export { default as first } from "../src/builtins/@first.js";
|
|
23
31
|
export { default as fnTree } from "../src/builtins/@fnTree.js";
|
|
24
32
|
export { default as globs } from "../src/builtins/@globs.js";
|
|
25
|
-
export { default as
|
|
33
|
+
export { default as group } from "../src/builtins/@group.js";
|
|
34
|
+
export { default as groupFn } from "../src/builtins/@groupFn.js";
|
|
26
35
|
export { default as help } from "../src/builtins/@help.js";
|
|
27
36
|
export { default as http } from "../src/builtins/@http.js";
|
|
28
37
|
export { default as https } from "../src/builtins/@https.js";
|
|
29
38
|
export { default as if } from "../src/builtins/@if.js";
|
|
30
39
|
export { default as imageFormat } from "../src/builtins/@image/format.js";
|
|
40
|
+
export { default as imageFormatFn } from "../src/builtins/@image/formatFn.js";
|
|
31
41
|
export { default as imageResize } from "../src/builtins/@image/resize.js";
|
|
42
|
+
export { default as imageResizeFn } from "../src/builtins/@image/resizeFn.js";
|
|
32
43
|
export { default as index } from "../src/builtins/@index.js";
|
|
33
44
|
export { default as inherited } from "../src/builtins/@inherited.js";
|
|
34
45
|
export { default as inline } from "../src/builtins/@inline.js";
|
|
35
46
|
export { default as inners } from "../src/builtins/@inners.js";
|
|
36
47
|
export { default as invoke } from "../src/builtins/@invoke.js";
|
|
37
|
-
export { default as isAsyncTree } from "../src/builtins/@isAsyncTree.js";
|
|
38
48
|
export { default as js } from "../src/builtins/@js.js";
|
|
39
49
|
export { default as json } from "../src/builtins/@json.js";
|
|
50
|
+
export { default as jsonParse } from "../src/builtins/@jsonParse.js";
|
|
40
51
|
export { default as keys } from "../src/builtins/@keys.js";
|
|
41
52
|
export { default as keysJson } from "../src/builtins/@keysJson.js";
|
|
42
|
-
export { default as makeParser } from "../src/builtins/@makeParser.js";
|
|
43
53
|
export { default as map } from "../src/builtins/@map.js";
|
|
44
|
-
export { default as
|
|
54
|
+
export { default as mapFn } from "../src/builtins/@mapFn.js";
|
|
45
55
|
export { default as match } from "../src/builtins/@match.js";
|
|
46
56
|
export { default as mdHtml } from "../src/builtins/@mdHtml.js";
|
|
57
|
+
export { default as mdTree } from "../src/builtins/@mdTree.js";
|
|
47
58
|
export { default as merge } from "../src/builtins/@merge.js";
|
|
48
|
-
export { default as mergeDeep } from "../src/builtins/@mergeDeep.js";
|
|
49
59
|
export { default as mkdir } from "../src/builtins/@mkdir.js";
|
|
60
|
+
export * from "../src/builtins/@naturalOrder.js";
|
|
50
61
|
export { default as node } from "../src/builtins/@node.js";
|
|
51
62
|
export { default as not } from "../src/builtins/@not.js";
|
|
52
63
|
export { default as once } from "../src/builtins/@once.js";
|
|
@@ -54,14 +65,16 @@ export { default as or } from "../src/builtins/@or.js";
|
|
|
54
65
|
export { default as ori } from "../src/builtins/@ori.js";
|
|
55
66
|
export { default as pack } from "../src/builtins/@pack.js";
|
|
56
67
|
export { default as package } from "../src/builtins/@package.js";
|
|
68
|
+
export { default as paginate } from "../src/builtins/@paginate.js";
|
|
69
|
+
export { default as paginateFn } from "../src/builtins/@paginateFn.js";
|
|
57
70
|
export { default as parent } from "../src/builtins/@parent.js";
|
|
58
|
-
export { default as parseJson } from "../src/builtins/@parse/json.js";
|
|
59
|
-
export { default as parseYaml } from "../src/builtins/@parse/yaml.js";
|
|
60
71
|
export { default as paths } from "../src/builtins/@paths.js";
|
|
61
72
|
export { default as perf } from "../src/builtins/@perf.js";
|
|
62
73
|
export { default as plain } from "../src/builtins/@plain.js";
|
|
63
74
|
export { default as project } from "../src/builtins/@project.js";
|
|
64
75
|
export { default as redirect } from "../src/builtins/@redirect.js";
|
|
76
|
+
export { default as regexParse } from "../src/builtins/@regexParse.js";
|
|
77
|
+
export { default as regexParseFn } from "../src/builtins/@regexParseFn.js";
|
|
65
78
|
export { default as repeat } from "../src/builtins/@repeat.js";
|
|
66
79
|
export { default as reverse } from "../src/builtins/@reverse.js";
|
|
67
80
|
export { default as rss } from "../src/builtins/@rss.js";
|
|
@@ -76,22 +89,22 @@ export { default as shuffle } from "../src/builtins/@shuffle.js";
|
|
|
76
89
|
export { default as sitemap } from "../src/builtins/@sitemap.js";
|
|
77
90
|
export { default as slug } from "../src/builtins/@slug.js";
|
|
78
91
|
export { default as sort } from "../src/builtins/@sort.js";
|
|
79
|
-
export { default as
|
|
92
|
+
export { default as sortFn } from "../src/builtins/@sortFn.js";
|
|
80
93
|
export { default as static } from "../src/builtins/@static.js";
|
|
81
94
|
export { default as stdin } from "../src/builtins/@stdin.js";
|
|
82
95
|
export { default as string } from "../src/builtins/@string.js";
|
|
83
96
|
export { default as svg } from "../src/builtins/@svg.js";
|
|
84
97
|
export { default as table } from "../src/builtins/@table.js";
|
|
85
98
|
export { default as take } from "../src/builtins/@take.js";
|
|
86
|
-
export { default as
|
|
99
|
+
export { default as takeFn } from "../src/builtins/@takeFn.js";
|
|
100
|
+
export * from "../src/builtins/@tree.js";
|
|
87
101
|
export { default as treeHttp } from "../src/builtins/@treeHttp.js";
|
|
88
102
|
export { default as treeHttps } from "../src/builtins/@treeHttps.js";
|
|
89
103
|
export { default as unpack } from "../src/builtins/@unpack.js";
|
|
90
104
|
export { default as values } from "../src/builtins/@values.js";
|
|
91
|
-
export { default as valuesDeep } from "../src/builtins/@valuesDeep.js";
|
|
92
105
|
export { default as watch } from "../src/builtins/@watch.js";
|
|
93
|
-
export { default as with } from "../src/builtins/@with.js";
|
|
94
106
|
export { default as yaml } from "../src/builtins/@yaml.js";
|
|
107
|
+
export { default as yamlParse } from "../src/builtins/@yamlParse.js";
|
|
95
108
|
export { default as homeFiles } from "../src/builtins/~.js";
|
|
96
109
|
export { default as csshandler } from "../src/builtins/css_handler.js";
|
|
97
110
|
export { default as htmhandler } from "../src/builtins/htm_handler.js";
|
|
@@ -111,7 +124,7 @@ export { default as ymlhandler } from "../src/builtins/yml_handler.js";
|
|
|
111
124
|
export { default as defaultModuleExport } from "../src/cli/defaultModuleExport.js";
|
|
112
125
|
export { default as showUsage } from "../src/cli/showUsage.js";
|
|
113
126
|
export { default as addValueKeyToScope } from "../src/common/addValueKeyToScope.js";
|
|
114
|
-
export { default as
|
|
127
|
+
export { default as arrowsMapFn } from "../src/common/arrowsMapFn.js";
|
|
115
128
|
export { default as CommandModulesTransform } from "../src/common/CommandModulesTransform.js";
|
|
116
129
|
export { default as ConstantTree } from "../src/common/ConstantTree.js";
|
|
117
130
|
export { default as documentObject } from "../src/common/documentObject.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/origami",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.50",
|
|
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.4.5"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@weborigami/async-tree": "0.0.
|
|
21
|
-
"@weborigami/language": "0.0.
|
|
22
|
-
"@weborigami/types": "0.0.
|
|
20
|
+
"@weborigami/async-tree": "0.0.50",
|
|
21
|
+
"@weborigami/language": "0.0.50",
|
|
22
|
+
"@weborigami/types": "0.0.50",
|
|
23
23
|
"exif-parser": "0.1.12",
|
|
24
24
|
"graphviz-wasm": "3.0.2",
|
|
25
25
|
"highlight.js": "11.9.0",
|
|
@@ -9,7 +9,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
9
9
|
* @this {AsyncTree|null}
|
|
10
10
|
* @param {import("@weborigami/async-tree").Treelike} treelike
|
|
11
11
|
*/
|
|
12
|
-
export default async function
|
|
12
|
+
export default async function addNextPrevious(treelike) {
|
|
13
13
|
const tree = await getTreeArgument(this, arguments, treelike, "@sequence");
|
|
14
14
|
let keys;
|
|
15
15
|
return Object.create(tree, {
|
|
@@ -17,13 +17,19 @@ export default async function sequence(treelike) {
|
|
|
17
17
|
value: async (key) => {
|
|
18
18
|
let value = await tree.get(key);
|
|
19
19
|
|
|
20
|
-
if (
|
|
20
|
+
if (value === undefined) {
|
|
21
|
+
return undefined;
|
|
22
|
+
} else if (Tree.isTreelike(value)) {
|
|
21
23
|
value = await Tree.plain(value);
|
|
22
24
|
} else if (typeof value === "object") {
|
|
23
25
|
// Clone value to avoid modifying the original object.
|
|
24
26
|
value = { ...value };
|
|
27
|
+
} else if (typeof value === "string") {
|
|
28
|
+
// Upgrade text nodes to objects.
|
|
29
|
+
value = { "@text": value };
|
|
25
30
|
} else {
|
|
26
|
-
|
|
31
|
+
// Upgrade other scalar types to objects.
|
|
32
|
+
value = { "@data": value };
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
if (keys === undefined) {
|
|
@@ -36,10 +42,15 @@ export default async function sequence(treelike) {
|
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
// Extend value with nextKey/previousKey properties.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
45
|
+
const nextKey = keys[index + 1];
|
|
46
|
+
if (nextKey) {
|
|
47
|
+
value.nextKey = nextKey;
|
|
48
|
+
}
|
|
49
|
+
const previousKey = keys[index - 1];
|
|
50
|
+
if (previousKey) {
|
|
51
|
+
value.previousKey = previousKey;
|
|
52
|
+
}
|
|
53
|
+
return value;
|
|
43
54
|
},
|
|
44
55
|
writable: true,
|
|
45
56
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Scope, functionResultsMap } from "@weborigami/language";
|
|
2
|
-
import
|
|
2
|
+
import arrowsMapFn from "../common/arrowsMapFn.js";
|
|
3
3
|
import { keySymbol } from "../common/utilities.js";
|
|
4
4
|
import getTreeArgument from "../misc/getTreeArgument.js";
|
|
5
5
|
import builtins from "./@builtins.js";
|
|
@@ -12,14 +12,14 @@ import builtins from "./@builtins.js";
|
|
|
12
12
|
* @this {AsyncTree|null}
|
|
13
13
|
* @param {Treelike} [treelike]
|
|
14
14
|
*/
|
|
15
|
-
export default async function
|
|
16
|
-
const tree = await getTreeArgument(this, arguments, treelike, "
|
|
17
|
-
const mapped = functionResultsMap(
|
|
15
|
+
export default async function arrowsMap(treelike) {
|
|
16
|
+
const tree = await getTreeArgument(this, arguments, treelike, "arrowsMap");
|
|
17
|
+
const mapped = functionResultsMap(arrowsMapFn()(tree));
|
|
18
18
|
const scope = this ?? builtins;
|
|
19
19
|
const scoped = Scope.treeWithScope(mapped, scope);
|
|
20
|
-
scoped[keySymbol] = "@
|
|
20
|
+
scoped[keySymbol] = "@arrowsMap";
|
|
21
21
|
return scoped;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
arrowsMap.usage = `@arrowsMap <obj>\tInterpret arrow keys in the tree as function calls`;
|
|
25
|
+
arrowsMap.documentation = "https://weborigami.org/language/@arrowsMap.html";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Tree } from "@weborigami/async-tree";
|
|
2
|
+
|
|
3
|
+
// Given an old tree and a new tree, return a tree of changes indicated
|
|
4
|
+
// by the values: "added", "changed", or "deleted".
|
|
5
|
+
export default async function changes(oldTreelike, newTreelike) {
|
|
6
|
+
const oldTree = Tree.from(oldTreelike);
|
|
7
|
+
const newTree = Tree.from(newTreelike);
|
|
8
|
+
|
|
9
|
+
const oldKeys = Array.from(await oldTree.keys());
|
|
10
|
+
const newKeys = Array.from(await newTree.keys());
|
|
11
|
+
|
|
12
|
+
const result = {};
|
|
13
|
+
|
|
14
|
+
for (const key of oldKeys) {
|
|
15
|
+
if (!newKeys.includes(key)) {
|
|
16
|
+
result[key] = "deleted";
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const oldValue = await oldTree.get(key);
|
|
21
|
+
const newValue = await newTree.get(key);
|
|
22
|
+
|
|
23
|
+
if (Tree.isAsyncTree(oldValue) && Tree.isAsyncTree(newValue)) {
|
|
24
|
+
const treeChanges = await changes(oldValue, newValue);
|
|
25
|
+
if (Object.keys(treeChanges).length > 0) {
|
|
26
|
+
result[key] = treeChanges;
|
|
27
|
+
}
|
|
28
|
+
} else if (oldValue?.toString && newValue?.toString) {
|
|
29
|
+
const oldText = oldValue.toString();
|
|
30
|
+
const newText = newValue.toString();
|
|
31
|
+
if (oldText !== newText) {
|
|
32
|
+
result[key] = "changed";
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
result[key] = "changed";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
for (const key of newKeys) {
|
|
40
|
+
if (!oldKeys.includes(key)) {
|
|
41
|
+
result[key] = "added";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Tree } from "@weborigami/async-tree";
|
|
2
|
+
import getTreeArgument from "../misc/getTreeArgument.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
6
|
+
*
|
|
7
|
+
* @this {AsyncTree|null}
|
|
8
|
+
* @param {import("@weborigami/async-tree").Treelike} treelike
|
|
9
|
+
*/
|
|
10
|
+
export default async function clean(treelike) {
|
|
11
|
+
const tree = await getTreeArgument(this, arguments, treelike, "@sequence");
|
|
12
|
+
if (!Tree.isAsyncMutableTree(tree)) {
|
|
13
|
+
throw new TypeError("@clean: the given tree is read-only.");
|
|
14
|
+
}
|
|
15
|
+
const keys = Array.from(await tree.keys());
|
|
16
|
+
const promises = keys.map((key) => tree.set(key, undefined));
|
|
17
|
+
await Promise.all(promises);
|
|
18
|
+
return tree;
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ops } from "@weborigami/language";
|
|
2
|
+
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
6
|
+
*
|
|
7
|
+
* @this {AsyncTree|null}
|
|
8
|
+
* @param {...any} keys
|
|
9
|
+
*/
|
|
10
|
+
export default function constructor(...keys) {
|
|
11
|
+
assertScopeIsDefined(this, "constructor");
|
|
12
|
+
const scope = this;
|
|
13
|
+
if (!scope) {
|
|
14
|
+
throw new Error("@constructor requires a non-null scope.");
|
|
15
|
+
}
|
|
16
|
+
return ops.constructor.call(scope, ...keys);
|
|
17
|
+
}
|
package/src/builtins/@crawl.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DeepObjectTree,
|
|
3
3
|
Tree,
|
|
4
|
+
deepMerge,
|
|
4
5
|
isPlainObject,
|
|
5
6
|
keysFromPath,
|
|
6
|
-
mergeDeep,
|
|
7
7
|
} from "@weborigami/async-tree";
|
|
8
8
|
import { InvokeFunctionsTransform, Scope, extname } from "@weborigami/language";
|
|
9
9
|
import * as utilities from "../common/utilities.js";
|
|
@@ -93,7 +93,7 @@ export default async function crawl(treelike, baseHref) {
|
|
|
93
93
|
// for something already, that's better than a function that will get that
|
|
94
94
|
// value.
|
|
95
95
|
/** @type {AsyncTree} */
|
|
96
|
-
let result =
|
|
96
|
+
let result = deepMerge(
|
|
97
97
|
new DeepObjectTree(cache),
|
|
98
98
|
new (InvokeFunctionsTransform(DeepObjectTree))(resources)
|
|
99
99
|
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
2
|
+
import deepMapFn from "./@deepMapFn.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Shorthand for calling `@map` with `deep: true` option.
|
|
6
|
+
*
|
|
7
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
8
|
+
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
9
|
+
* @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
|
|
10
|
+
* @typedef {import("./map.d.ts").TreeMapOptions} TreeMapOptions
|
|
11
|
+
*
|
|
12
|
+
* @this {AsyncTree|null}
|
|
13
|
+
* @param {Treelike} source
|
|
14
|
+
* @param {ValueKeyFn|TreeMapOptions} operation
|
|
15
|
+
*/
|
|
16
|
+
export default function deepMap(source, operation) {
|
|
17
|
+
assertScopeIsDefined(this, "deepMap");
|
|
18
|
+
return deepMapFn.call(this, operation)(source);
|
|
19
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isPlainObject } from "@weborigami/async-tree";
|
|
2
|
+
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
3
|
+
import mapFn from "./@mapFn.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shorthand for calling `@mapFn` with `deep: true` option.
|
|
7
|
+
*
|
|
8
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
9
|
+
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
10
|
+
* @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
|
|
11
|
+
* @typedef {import("./map.d.ts").TreeMapOptions} TreeMapOptions
|
|
12
|
+
*
|
|
13
|
+
* @this {AsyncTree|null}
|
|
14
|
+
* @param {ValueKeyFn|TreeMapOptions} operation
|
|
15
|
+
*/
|
|
16
|
+
export default function deepMapFn(operation) {
|
|
17
|
+
assertScopeIsDefined(this, "deepMap");
|
|
18
|
+
/** @type {TreeMapOptions} */
|
|
19
|
+
const options = isPlainObject(operation)
|
|
20
|
+
? // Dictionary
|
|
21
|
+
{ ...operation, deep: true }
|
|
22
|
+
: // Function
|
|
23
|
+
{ deep: true, value: operation };
|
|
24
|
+
return mapFn.call(this, options);
|
|
25
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deepMerge } from "@weborigami/async-tree";
|
|
2
2
|
import { Scope } from "@weborigami/language";
|
|
3
3
|
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
4
4
|
|
|
@@ -10,8 +10,8 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
10
10
|
* @this {AsyncTree|null}
|
|
11
11
|
* @param {Treelike[]} trees
|
|
12
12
|
*/
|
|
13
|
-
export default async function
|
|
14
|
-
assertScopeIsDefined(this, "
|
|
13
|
+
export default async function treedeepMerge(...trees) {
|
|
14
|
+
assertScopeIsDefined(this, "deepMerge");
|
|
15
15
|
// Filter out null or undefined trees.
|
|
16
16
|
const filtered = trees.filter((tree) => tree);
|
|
17
17
|
|
|
@@ -30,7 +30,7 @@ export default async function treeMergeDeep(...trees) {
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
// Merge the trees.
|
|
33
|
-
const result =
|
|
33
|
+
const result = deepMerge(...scopedTrees);
|
|
34
34
|
|
|
35
35
|
// Give the overall mixed tree a scope that includes the component trees and
|
|
36
36
|
// the current scope.
|
|
@@ -39,6 +39,6 @@ export default async function treeMergeDeep(...trees) {
|
|
|
39
39
|
return result;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"https://weborigami.org/cli/builtins.html#
|
|
42
|
+
treedeepMerge.usage = `@deepMerge <...trees>\tMerge the given trees deeply`;
|
|
43
|
+
treedeepMerge.documentation =
|
|
44
|
+
"https://weborigami.org/cli/builtins.html#deepMerge";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import getTreeArgument from "../misc/getTreeArgument.js";
|
|
2
|
+
import deepTakeFn from "./@deepTakeFn.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns a function that traverses a tree deeply and returns the values of the
|
|
6
|
+
* first `count` keys.
|
|
7
|
+
*
|
|
8
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
9
|
+
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
10
|
+
*
|
|
11
|
+
* @this {AsyncTree|null}
|
|
12
|
+
* @param {Treelike} treelike
|
|
13
|
+
* @param {number} n
|
|
14
|
+
*/
|
|
15
|
+
export default async function deepTake(treelike, n) {
|
|
16
|
+
const tree = await getTreeArgument(this, arguments, treelike, "@deepTake");
|
|
17
|
+
return deepTakeFn.call(this, n)(tree);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
deepTake.usage = `@deepTake tree, n\tReturn the first n values from the deep tree`;
|
|
21
|
+
deepTake.documentation = "https://weborigami.org/builtins/deepTake.html";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { deepTakeFn } from "@weborigami/async-tree";
|
|
2
|
+
import { Scope } from "@weborigami/language";
|
|
3
|
+
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns a function that traverses a tree deeply and returns the values of the
|
|
7
|
+
* first `count` keys.
|
|
8
|
+
*
|
|
9
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
10
|
+
*
|
|
11
|
+
* @this {AsyncTree|null}
|
|
12
|
+
* @param {number} count
|
|
13
|
+
*/
|
|
14
|
+
export default function deepTakeFnBuiltin(count) {
|
|
15
|
+
assertScopeIsDefined(this, "deepTakeFn");
|
|
16
|
+
const scope = this;
|
|
17
|
+
return async (treelike) => {
|
|
18
|
+
const taken = await deepTakeFn(count)(treelike);
|
|
19
|
+
const scoped = Scope.treeWithScope(taken, scope);
|
|
20
|
+
return scoped;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deepValues } from "@weborigami/async-tree";
|
|
2
2
|
import getTreeArgument from "../misc/getTreeArgument.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -6,14 +6,15 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
6
6
|
*
|
|
7
7
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
8
8
|
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
9
|
+
*
|
|
9
10
|
* @this {AsyncTree|null}
|
|
10
11
|
* @param {Treelike} [treelike]
|
|
11
12
|
*/
|
|
12
|
-
export default async function
|
|
13
|
+
export default async function deepValuesBuiltin(treelike) {
|
|
13
14
|
const tree = await getTreeArgument(this, arguments, treelike, "@valuesDeep");
|
|
14
|
-
return
|
|
15
|
+
return deepValues(tree);
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
deepValuesBuiltin.usage = `@valuesDeep <tree>\tThe in-order tree values as a flat array`;
|
|
19
|
+
deepValuesBuiltin.documentation =
|
|
19
20
|
"https://weborigami.org/cli/builtins.html#valuesDeep";
|
package/src/builtins/@files.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OrigamiFiles, Scope } from "@weborigami/language";
|
|
2
|
+
import os from "node:os";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import process from "node:process";
|
|
4
5
|
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
@@ -11,7 +12,19 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
11
12
|
*/
|
|
12
13
|
export default async function files(...keys) {
|
|
13
14
|
assertScopeIsDefined(this, "files");
|
|
14
|
-
|
|
15
|
+
|
|
16
|
+
// If path begins with `~`, treat it relative to the home directory.
|
|
17
|
+
// Otherwise, treat it relative to the current working directory.
|
|
18
|
+
let relativePath = keys.join(path.sep);
|
|
19
|
+
let basePath;
|
|
20
|
+
if (relativePath.startsWith("~")) {
|
|
21
|
+
basePath = os.homedir();
|
|
22
|
+
relativePath = relativePath.slice(2);
|
|
23
|
+
} else {
|
|
24
|
+
basePath = process.cwd();
|
|
25
|
+
}
|
|
26
|
+
const resolved = path.resolve(basePath, relativePath);
|
|
27
|
+
|
|
15
28
|
/** @type {AsyncTree} */
|
|
16
29
|
let result = new OrigamiFiles(resolved);
|
|
17
30
|
result = Scope.treeWithScope(result, this);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import getTreeArgument from "../misc/getTreeArgument.js";
|
|
2
|
+
import groupFn from "./@groupFn.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Map a tree to a new tree with the values from the original tree grouped by
|
|
6
|
+
* the given function.
|
|
7
|
+
*
|
|
8
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
9
|
+
*
|
|
10
|
+
* @this {AsyncTree|null}
|
|
11
|
+
* @param {import("@weborigami/async-tree").Treelike} treelike
|
|
12
|
+
* @param {import("../../index.ts").Invocable} groupKey
|
|
13
|
+
*/
|
|
14
|
+
export default async function groupBuiltin(treelike, groupKey) {
|
|
15
|
+
const tree = await getTreeArgument(this, arguments, treelike, "@sort");
|
|
16
|
+
return groupFn.call(this, groupKey)(tree);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
groupBuiltin.usage = `@group <tree>, <fn>\tGroup a tree's values using the given function`;
|
|
20
|
+
groupBuiltin.documentation = "https://weborigami.org/builtins/@group.html";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { groupFn } from "@weborigami/async-tree";
|
|
2
|
+
import { Scope } from "@weborigami/language";
|
|
3
|
+
import { toFunction } from "../common/utilities.js";
|
|
4
|
+
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Return a function that maps a tree to a new tree with the values from the
|
|
8
|
+
* original tree grouped by the given function.
|
|
9
|
+
*
|
|
10
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
11
|
+
*
|
|
12
|
+
* @this {AsyncTree|null}
|
|
13
|
+
* @param {import("../../index.ts").Invocable} groupKey
|
|
14
|
+
*/
|
|
15
|
+
export default function groupFnBuiltin(groupKey) {
|
|
16
|
+
assertScopeIsDefined(this);
|
|
17
|
+
const scope = this;
|
|
18
|
+
const groupKeyFn = toFunction(groupKey);
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
const fn = groupFn(groupKeyFn);
|
|
21
|
+
return async (treelike) => {
|
|
22
|
+
const grouped = await fn(treelike);
|
|
23
|
+
const scoped = Scope.treeWithScope(grouped, scope);
|
|
24
|
+
return scoped;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
groupFnBuiltin.usage = `@groupBy <tree>, [groupKeyFn]\tReturn a new tree with the original's values grouped`;
|
|
29
|
+
groupFnBuiltin.documentation =
|
|
30
|
+
"https://weborigami.org/cli/builtins.html#@group";
|
package/src/builtins/@if.js
CHANGED
|
@@ -16,7 +16,8 @@ export default async function ifCommand(value, trueResult, falseResult) {
|
|
|
16
16
|
condition = keys.length > 0;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
// 0 is true, null/undefined/false is false
|
|
20
|
+
let result = condition || condition === 0 ? trueResult : falseResult;
|
|
20
21
|
if (typeof result === "function") {
|
|
21
22
|
result = await result.call(this);
|
|
22
23
|
}
|
|
@@ -1,39 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assertScopeIsDefined from "../../misc/assertScopeIsDefined.js";
|
|
2
|
+
import imageFormatFn from "./formatFn.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Return the image in a different format.
|
|
5
6
|
*
|
|
6
7
|
* @this {import("@weborigami/types").AsyncTree|null}
|
|
7
8
|
*
|
|
8
|
-
* @
|
|
9
|
-
*
|
|
10
|
-
* @
|
|
11
|
-
*
|
|
12
|
-
* @param {any}
|
|
13
|
-
* @returns {(buffer: Buffer) => Promise<Buffer>}
|
|
14
|
-
*
|
|
15
|
-
* @overload
|
|
16
|
-
* @param {Buffer} param1
|
|
17
|
-
* @param {any} param2
|
|
18
|
-
* @param {any} param3
|
|
19
|
-
* @returns {Promise<Buffer>}
|
|
9
|
+
* @this {import("@weborigami/types").AsyncTree|null}
|
|
10
|
+
* @param {Buffer} buffer
|
|
11
|
+
* @param {keyof import("sharp").FormatEnum|import("sharp").AvailableFormatInfo}
|
|
12
|
+
* format
|
|
13
|
+
* @param {any} options
|
|
20
14
|
*/
|
|
21
|
-
export default function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let format;
|
|
25
|
-
let options;
|
|
26
|
-
if (param1 instanceof Buffer) {
|
|
27
|
-
buffer = param1;
|
|
28
|
-
format = param2;
|
|
29
|
-
options = param3;
|
|
30
|
-
} else {
|
|
31
|
-
format = param1;
|
|
32
|
-
options = param2;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const transform = (buffer) =>
|
|
36
|
-
sharp(buffer).toFormat(format, options).toBuffer();
|
|
37
|
-
|
|
38
|
-
return buffer ? transform(buffer) : transform;
|
|
15
|
+
export default async function imageFormat(buffer, format, options) {
|
|
16
|
+
assertScopeIsDefined(this, "image/format");
|
|
17
|
+
return imageFormatFn.call(this, format, options)(buffer);
|
|
39
18
|
}
|