@weborigami/origami 0.6.0 → 0.6.1
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/package.json +3 -3
- package/src/common/serialize.js +4 -10
- package/src/dev/copy.js +71 -55
- package/src/dev/crawler/crawl.js +2 -2
- package/src/dev/help.yaml +12 -0
- package/src/origami/jsonKeys.js +3 -1
- package/src/origami/ori.js +11 -0
- package/src/origami/sitemap.js +1 -1
- package/src/origami/unpack.js +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/origami",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
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.9.3"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@weborigami/async-tree": "0.6.
|
|
20
|
+
"@weborigami/async-tree": "0.6.1",
|
|
21
21
|
"@weborigami/json-feed-to-rss": "1.0.0",
|
|
22
|
-
"@weborigami/language": "0.6.
|
|
22
|
+
"@weborigami/language": "0.6.1",
|
|
23
23
|
"css-tree": "3.1.0",
|
|
24
24
|
"graphviz-wasm": "3.0.2",
|
|
25
25
|
"highlight.js": "11.11.1",
|
package/src/common/serialize.js
CHANGED
|
@@ -5,12 +5,7 @@
|
|
|
5
5
|
* @typedef {import("@weborigami/async-tree").SyncOrAsyncMap} SyncOrAsyncMap
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
castArraylike,
|
|
10
|
-
SyncMap,
|
|
11
|
-
toPlainValue,
|
|
12
|
-
trailingSlash,
|
|
13
|
-
} from "@weborigami/async-tree";
|
|
8
|
+
import { castArraylike, toPlainValue } from "@weborigami/async-tree";
|
|
14
9
|
import * as YAMLModule from "yaml";
|
|
15
10
|
|
|
16
11
|
// The "yaml" package doesn't seem to provide a default export that the browser can
|
|
@@ -26,10 +21,9 @@ export function parseYaml(text) {
|
|
|
26
21
|
return YAML.parse(text);
|
|
27
22
|
}
|
|
28
23
|
|
|
29
|
-
function reduceToMap(
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
return castArraylike(keys, values, (entries) => new SyncMap(entries));
|
|
24
|
+
function reduceToMap(map) {
|
|
25
|
+
// createFn parameter returns as map as is
|
|
26
|
+
return castArraylike(map, (result) => result);
|
|
33
27
|
}
|
|
34
28
|
|
|
35
29
|
/**
|
package/src/dev/copy.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AsyncMap,
|
|
3
|
+
getTreeArgument,
|
|
4
|
+
SyncMap,
|
|
5
|
+
Tree,
|
|
6
|
+
} from "@weborigami/async-tree";
|
|
2
7
|
import { formatError } from "@weborigami/language";
|
|
3
8
|
import process, { stdout } from "node:process";
|
|
4
|
-
import { transformObject } from "../common/utilities.js";
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
@@ -13,75 +17,87 @@ export default async function copy(source, target) {
|
|
|
13
17
|
const sourceTree = await getTreeArgument(source, "copy", { position: 0 });
|
|
14
18
|
let targetTree = await getTreeArgument(target, "copy", { position: 1 });
|
|
15
19
|
|
|
20
|
+
let progressTree;
|
|
16
21
|
if (stdout.isTTY) {
|
|
17
|
-
targetTree
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
countCopied = 0;
|
|
22
|
+
progressTree = showSetProgress(targetTree, {
|
|
23
|
+
copied: 0,
|
|
24
|
+
total: 0,
|
|
25
|
+
});
|
|
26
|
+
} else {
|
|
27
|
+
progressTree = targetTree;
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
await Tree.assign(
|
|
30
|
+
await Tree.assign(progressTree, sourceTree);
|
|
27
31
|
|
|
28
32
|
if (stdout.isTTY) {
|
|
29
33
|
process.stdout.clearLine(0);
|
|
30
34
|
process.stdout.cursorTo(0);
|
|
31
|
-
copyRoot = null;
|
|
32
|
-
countFiles = null;
|
|
33
|
-
countCopied = null;
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// Wrap the source tree to show progress on set() operations. Handle both sync
|
|
39
|
+
// and async trees. All child trees will share the same counts object.
|
|
40
|
+
function showSetProgress(source, counts) {
|
|
41
|
+
function showProgress() {
|
|
42
|
+
process.stdout.clearLine(0);
|
|
43
|
+
process.stdout.cursorTo(0);
|
|
44
|
+
process.stdout.write(`Copied ${counts.copied} of ${counts.total}`);
|
|
45
|
+
}
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
countFiles++;
|
|
45
|
-
copyRoot.showProgress();
|
|
46
|
-
let result;
|
|
47
|
-
try {
|
|
48
|
-
result = await super.set(...args);
|
|
49
|
-
countCopied++;
|
|
50
|
-
} catch (/** @type {any} */ error) {
|
|
51
|
-
console.error(formatError(error));
|
|
52
|
-
}
|
|
53
|
-
copyRoot.showProgress();
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
47
|
+
const isSync = source instanceof Map;
|
|
48
|
+
const MapClass = isSync ? SyncMap : AsyncMap;
|
|
49
|
+
const iteratorKey = isSync ? Symbol.iterator : Symbol.asyncIterator;
|
|
56
50
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
const progressTree = Object.assign(new MapClass(), {
|
|
52
|
+
delete: source.delete.bind(source),
|
|
53
|
+
keys: source.keys.bind(source),
|
|
54
|
+
[iteratorKey]: source[iteratorKey].bind(source),
|
|
55
|
+
|
|
56
|
+
// Wrap get() to apply progress tracking
|
|
57
|
+
get(key) {
|
|
58
|
+
return awaitIfPromise(source.get(key), (value) => {
|
|
59
|
+
return Tree.isMap(value) ? showSetProgress(value, counts) : value;
|
|
60
|
+
});
|
|
61
|
+
},
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
copyRoot.showProgress();
|
|
70
|
-
let result;
|
|
63
|
+
// Wrap set() to show progress
|
|
64
|
+
set(key, value) {
|
|
65
|
+
counts.total++;
|
|
66
|
+
showProgress();
|
|
71
67
|
try {
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
const setResult = source.set(key, value);
|
|
69
|
+
return awaitIfPromise(setResult, () => {
|
|
70
|
+
counts.copied++;
|
|
71
|
+
showProgress();
|
|
72
|
+
return progressTree;
|
|
73
|
+
});
|
|
74
74
|
} catch (/** @type {any} */ error) {
|
|
75
75
|
console.error(formatError(error));
|
|
76
|
+
return progressTree;
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (typeof source.child === "function") {
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
progressTree.child = async function (key) {
|
|
84
|
+
counts.total++;
|
|
85
|
+
showProgress();
|
|
86
|
+
const childResult = source.child(key);
|
|
87
|
+
return awaitIfPromise(childResult, (child) => {
|
|
88
|
+
counts.copied++;
|
|
89
|
+
showProgress();
|
|
90
|
+
return showSetProgress(child, counts);
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return progressTree;
|
|
96
|
+
}
|
|
80
97
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
};
|
|
98
|
+
// Helper function that awaits a value if it's a Promise, then gives it to the
|
|
99
|
+
// function; otherwise calls the function directly. This helps us write code
|
|
100
|
+
// that can handle both sync and async values.
|
|
101
|
+
function awaitIfPromise(value, fn) {
|
|
102
|
+
return value instanceof Promise ? value.then(fn) : fn(value);
|
|
87
103
|
}
|
package/src/dev/crawler/crawl.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
ObjectMap,
|
|
3
3
|
Tree,
|
|
4
4
|
getTreeArgument,
|
|
5
5
|
keysFromPath,
|
|
@@ -53,7 +53,7 @@ export default async function crawlBuiltin(maplike, baseHref) {
|
|
|
53
53
|
// for something already, that's better than a function that will get that
|
|
54
54
|
// value.
|
|
55
55
|
const result = Tree.deepMerge(
|
|
56
|
-
new
|
|
56
|
+
new ObjectMap(cache, { deep: true }),
|
|
57
57
|
await Tree.invokeFunctions(resources)
|
|
58
58
|
);
|
|
59
59
|
return result;
|
package/src/dev/help.yaml
CHANGED
|
@@ -178,6 +178,9 @@ Tree:
|
|
|
178
178
|
calendar:
|
|
179
179
|
args: (options)
|
|
180
180
|
description: Return a tree structure for years/months/days
|
|
181
|
+
child:
|
|
182
|
+
args: (tree, key)
|
|
183
|
+
description: Returns the indicated child node, creating it if necessary
|
|
181
184
|
clear:
|
|
182
185
|
args: (map)
|
|
183
186
|
description: Remove all values from the map
|
|
@@ -235,6 +238,9 @@ Tree:
|
|
|
235
238
|
inners:
|
|
236
239
|
args: (tree)
|
|
237
240
|
description: The tree's interior nodes
|
|
241
|
+
invokeFunctions:
|
|
242
|
+
args: (map)
|
|
243
|
+
description: Getting a map value invokes it if it's a function
|
|
238
244
|
isMap:
|
|
239
245
|
args: (object)
|
|
240
246
|
description: True if object is a map
|
|
@@ -283,6 +289,9 @@ Tree:
|
|
|
283
289
|
plain:
|
|
284
290
|
args: (tree)
|
|
285
291
|
description: Render the tree as a plain JavaScript object
|
|
292
|
+
reduce:
|
|
293
|
+
args: (tree, reduceFn)
|
|
294
|
+
description: Reduce the tree to a single value
|
|
286
295
|
regExpKeys:
|
|
287
296
|
args: (tree)
|
|
288
297
|
description: A tree whose keys are regular expression strings
|
|
@@ -295,6 +304,9 @@ Tree:
|
|
|
295
304
|
scope:
|
|
296
305
|
args: (tree)
|
|
297
306
|
description: A merged view of the tree and its ancestors
|
|
307
|
+
set:
|
|
308
|
+
args: (map, key, value)
|
|
309
|
+
description: Set the value for the key in the map
|
|
298
310
|
shuffle:
|
|
299
311
|
args: (map)
|
|
300
312
|
description: Shuffle the keys of the map
|
package/src/origami/jsonKeys.js
CHANGED
package/src/origami/ori.js
CHANGED
|
@@ -48,6 +48,17 @@ export default async function ori(expression, options = {}) {
|
|
|
48
48
|
// Execute
|
|
49
49
|
let result = await fn();
|
|
50
50
|
|
|
51
|
+
// if (result === undefined) {
|
|
52
|
+
// // Was the code a path traversal?
|
|
53
|
+
// const wasTraversal =
|
|
54
|
+
// fn.code[0] === ops.unpack ||
|
|
55
|
+
// (fn.code[0] instanceof Array && fn.code[0][0] === ops.scope);
|
|
56
|
+
// if (wasTraversal) {
|
|
57
|
+
// // Yes, probably an error
|
|
58
|
+
// console.warn(`ori: warning: undefined ${highlightError(expression)}`);
|
|
59
|
+
// }
|
|
60
|
+
// }
|
|
61
|
+
|
|
51
62
|
// If result was a function, execute it.
|
|
52
63
|
if (typeof result === "function") {
|
|
53
64
|
result = await result();
|
package/src/origami/sitemap.js
CHANGED
|
@@ -14,7 +14,7 @@ const templateText = `(urls) => \`<?xml version="1.0" encoding="UTF-8"?>
|
|
|
14
14
|
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
15
15
|
*
|
|
16
16
|
* @param {Maplike} maplike
|
|
17
|
-
* @param {{
|
|
17
|
+
* @param {{ base?: string }} options
|
|
18
18
|
* @returns {Promise<string>}
|
|
19
19
|
*/
|
|
20
20
|
export default async function sitemap(maplike, options = {}) {
|
package/src/origami/unpack.js
CHANGED