@weborigami/origami 0.5.8 → 0.6.0
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 +11 -12
- package/src/cli/cli.js +1 -1
- package/src/common/assertTreeIsDefined.js +1 -1
- package/src/common/documentObject.js +1 -8
- package/src/common/serialize.d.ts +4 -4
- package/src/common/serialize.js +20 -24
- package/src/dev/ExplorableSiteTransform.js +6 -4
- package/src/dev/OriCommandTransform.js +4 -4
- package/src/dev/changes.js +9 -9
- package/src/dev/code.js +0 -1
- package/src/dev/copy.js +32 -6
- package/src/dev/crawler/audit.js +5 -6
- package/src/dev/crawler/crawl.js +10 -11
- package/src/dev/crawler/crawlResources.js +1 -1
- package/src/dev/debug.js +12 -10
- package/src/dev/explore.js +4 -5
- package/src/dev/help.js +0 -1
- package/src/dev/help.yaml +57 -54
- package/src/dev/serve.js +4 -5
- package/src/dev/svg.js +4 -5
- package/src/dev/treeDot.js +6 -6
- package/src/dev/watch.js +8 -8
- package/src/origami/csv.js +1 -1
- package/src/origami/document.js +0 -1
- package/src/origami/indexPage.js +7 -8
- package/src/origami/inline.js +0 -1
- package/src/origami/json.js +0 -1
- package/src/origami/jsonKeys.js +29 -18
- package/src/origami/once.js +0 -1
- package/src/origami/ori.js +2 -3
- package/src/origami/pack.js +0 -1
- package/src/origami/post.js +1 -1
- package/src/origami/rss.js +2 -3
- package/src/origami/sitemap.js +9 -19
- package/src/origami/static.js +44 -19
- package/src/origami/yaml.js +0 -1
- package/src/server/constructResponse.js +6 -6
- package/src/server/server.js +9 -9
- package/src/common/getTreeArgument.js +0 -67
package/src/dev/help.yaml
CHANGED
|
@@ -167,8 +167,8 @@ Tree:
|
|
|
167
167
|
description: Work with trees of files and data
|
|
168
168
|
commands:
|
|
169
169
|
addNextPrevious:
|
|
170
|
-
args: (
|
|
171
|
-
description: Add next/previous fields to the
|
|
170
|
+
args: (map)
|
|
171
|
+
description: Add next/previous fields to the map's values
|
|
172
172
|
assign:
|
|
173
173
|
args: (target, source)
|
|
174
174
|
description: Apply key/values from source to target
|
|
@@ -179,8 +179,8 @@ Tree:
|
|
|
179
179
|
args: (options)
|
|
180
180
|
description: Return a tree structure for years/months/days
|
|
181
181
|
clear:
|
|
182
|
-
args: (
|
|
183
|
-
description: Remove all values from the
|
|
182
|
+
args: (map)
|
|
183
|
+
description: Remove all values from the map
|
|
184
184
|
constant:
|
|
185
185
|
args: (value)
|
|
186
186
|
description: Return a deep tree with a single constant value
|
|
@@ -203,68 +203,65 @@ Tree:
|
|
|
203
203
|
args: (tree)
|
|
204
204
|
description: The in-order leaf values of the tree
|
|
205
205
|
delete:
|
|
206
|
-
args: (
|
|
207
|
-
description: Delete the value for the key from
|
|
206
|
+
args: (map, key)
|
|
207
|
+
description: Delete the value for the key from map
|
|
208
208
|
entries:
|
|
209
|
-
args: (
|
|
210
|
-
description: The
|
|
209
|
+
args: (map)
|
|
210
|
+
description: The map's [key, value] pairs
|
|
211
211
|
filter:
|
|
212
|
-
args: (
|
|
213
|
-
description: Filter
|
|
212
|
+
args: (tree, options)
|
|
213
|
+
description: Filter a tree by a condition
|
|
214
214
|
first:
|
|
215
|
-
args: (
|
|
216
|
-
description: The first value in the
|
|
215
|
+
args: (map)
|
|
216
|
+
description: The first value in the map
|
|
217
217
|
forEach:
|
|
218
|
-
args: (
|
|
218
|
+
args: (map, fn)
|
|
219
219
|
description: Apply fn to each (value, key)
|
|
220
220
|
from:
|
|
221
221
|
args: (object, options)
|
|
222
|
-
description: Create a
|
|
222
|
+
description: Create a map from an object
|
|
223
223
|
globKeys:
|
|
224
224
|
args: (patterns)
|
|
225
225
|
description: A tree whose keys can include glob wildcard patterns
|
|
226
226
|
groupBy:
|
|
227
|
-
args: (
|
|
228
|
-
description: A new
|
|
227
|
+
args: (map, fn)
|
|
228
|
+
description: A new map with values grouped by the function
|
|
229
229
|
has:
|
|
230
|
-
args: (
|
|
231
|
-
description: True if key exists in
|
|
230
|
+
args: (map, key)
|
|
231
|
+
description: True if key exists in map
|
|
232
232
|
indent:
|
|
233
233
|
args: "`…`"
|
|
234
234
|
description: Tagged template literal for normalizing indentation
|
|
235
235
|
inners:
|
|
236
236
|
args: (tree)
|
|
237
237
|
description: The tree's interior nodes
|
|
238
|
-
|
|
238
|
+
isMap:
|
|
239
|
+
args: (object)
|
|
240
|
+
description: True if object is a map
|
|
241
|
+
isMaplike:
|
|
239
242
|
args: (object)
|
|
240
|
-
description: True if object
|
|
241
|
-
|
|
243
|
+
description: True if object can be coerced to a tree
|
|
244
|
+
isReadOnlyMap:
|
|
242
245
|
args: (object)
|
|
243
|
-
description: True if object is
|
|
246
|
+
description: True if object is a read-only map
|
|
244
247
|
isTraversable:
|
|
245
248
|
args: (object)
|
|
246
249
|
description: True if object is traversable
|
|
247
|
-
isTreelike:
|
|
248
|
-
args: (object)
|
|
249
|
-
description: True if object can be coerced to a tree
|
|
250
250
|
json:
|
|
251
251
|
args: (tree)
|
|
252
252
|
description: Render the tree in JSON format
|
|
253
253
|
keys:
|
|
254
|
-
args: (
|
|
255
|
-
description: The keys of the
|
|
256
|
-
length:
|
|
257
|
-
args: (tree)
|
|
258
|
-
description: The tree's size (number of keys)
|
|
254
|
+
args: (map)
|
|
255
|
+
description: The keys of the map
|
|
259
256
|
map:
|
|
260
|
-
args: (
|
|
261
|
-
description: Create a new
|
|
257
|
+
args: (source, options)
|
|
258
|
+
description: Create a new map by transforming keys and/or values
|
|
262
259
|
mapExtension:
|
|
263
|
-
args: (
|
|
264
|
-
description:
|
|
260
|
+
args: (source, ext, options)
|
|
261
|
+
description: Create a new map by transforming extensions
|
|
265
262
|
mapReduce:
|
|
266
263
|
args: (tree, mapFn, reduceFn)
|
|
267
|
-
description: Map values and reduce them
|
|
264
|
+
description: Map the keys and/or values in a tree and reduce them
|
|
268
265
|
mask:
|
|
269
266
|
args: (source, mask)
|
|
270
267
|
description: Return the source tree with only the keys in the mask
|
|
@@ -272,11 +269,11 @@ Tree:
|
|
|
272
269
|
args: (pattern, fn, [keys])
|
|
273
270
|
description: Matches simple patterns or regular expressions
|
|
274
271
|
merge:
|
|
275
|
-
args: (...
|
|
276
|
-
description: Return a new tree merging the given
|
|
272
|
+
args: (...maps)
|
|
273
|
+
description: Return a new tree merging the given maps
|
|
277
274
|
paginate:
|
|
278
|
-
args: (
|
|
279
|
-
description: Group the
|
|
275
|
+
args: (map, [n])
|
|
276
|
+
description: Group the map's values into fixed-size sets
|
|
280
277
|
parent:
|
|
281
278
|
args: (tree)
|
|
282
279
|
description: The parent of the given tree node
|
|
@@ -290,23 +287,29 @@ Tree:
|
|
|
290
287
|
args: (tree)
|
|
291
288
|
description: A tree whose keys are regular expression strings
|
|
292
289
|
reverse:
|
|
293
|
-
args: (
|
|
294
|
-
description: Reverse the order of the
|
|
290
|
+
args: (map)
|
|
291
|
+
description: Reverse the order of the map's keys
|
|
295
292
|
root:
|
|
296
293
|
args: (tree)
|
|
297
294
|
description: The root node of the given tree
|
|
298
|
-
|
|
299
|
-
args: (target, source)
|
|
300
|
-
description: Applies the source tree to the target
|
|
301
|
-
shuffle:
|
|
295
|
+
scope:
|
|
302
296
|
args: (tree)
|
|
303
|
-
description:
|
|
297
|
+
description: A merged view of the tree and its ancestors
|
|
298
|
+
shuffle:
|
|
299
|
+
args: (map)
|
|
300
|
+
description: Shuffle the keys of the map
|
|
301
|
+
size:
|
|
302
|
+
args: (map)
|
|
303
|
+
description: The map's size (number of keys)
|
|
304
304
|
sort:
|
|
305
|
-
args: (
|
|
306
|
-
description: A new
|
|
305
|
+
args: (map, options)
|
|
306
|
+
description: A new map with its keys sorted
|
|
307
|
+
sync:
|
|
308
|
+
args: (tree)
|
|
309
|
+
description: Awaits all asynchronous values in the tree
|
|
307
310
|
take:
|
|
308
|
-
args: (
|
|
309
|
-
description: The first n values in the
|
|
311
|
+
args: (map, n)
|
|
312
|
+
description: The first n values in the map
|
|
310
313
|
text:
|
|
311
314
|
args: "`…`"
|
|
312
315
|
description: Tagged template literal for rendering trees
|
|
@@ -320,8 +323,8 @@ Tree:
|
|
|
320
323
|
args: (tree, path)
|
|
321
324
|
description: Traverse a slash-separated path
|
|
322
325
|
values:
|
|
323
|
-
args: (
|
|
324
|
-
description: The
|
|
326
|
+
args: (map)
|
|
327
|
+
description: The map's values
|
|
325
328
|
withKeys:
|
|
326
|
-
args: (
|
|
327
|
-
description: Use the given keys for the
|
|
329
|
+
args: (map, keys)
|
|
330
|
+
description: Use the given keys for the map
|
package/src/dev/serve.js
CHANGED
|
@@ -11,14 +11,13 @@ const defaultPort = 5000;
|
|
|
11
11
|
/**
|
|
12
12
|
* Start a local web server for the indicated tree.
|
|
13
13
|
*
|
|
14
|
-
* @typedef {import("@weborigami/
|
|
15
|
-
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
14
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
16
15
|
*
|
|
17
|
-
* @param {
|
|
16
|
+
* @param {Maplike} maplike
|
|
18
17
|
* @param {number} [port]
|
|
19
18
|
*/
|
|
20
|
-
export default async function serve(
|
|
21
|
-
let tree = await getTreeArgument(
|
|
19
|
+
export default async function serve(maplike, port) {
|
|
20
|
+
let tree = await getTreeArgument(maplike, "serve");
|
|
22
21
|
|
|
23
22
|
if (!isTransformApplied(ExplorableSiteTransform, tree)) {
|
|
24
23
|
tree = transformObject(ExplorableSiteTransform, tree);
|
package/src/dev/svg.js
CHANGED
|
@@ -8,19 +8,18 @@ let graphvizLoaded = false;
|
|
|
8
8
|
/**
|
|
9
9
|
* Render a tree visually in SVG format.
|
|
10
10
|
*
|
|
11
|
-
* @typedef {import("@weborigami/
|
|
12
|
-
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
11
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
13
12
|
* @typedef {import("@weborigami/async-tree").PlainObject} PlainObject
|
|
14
13
|
*
|
|
15
|
-
* @param {
|
|
14
|
+
* @param {Maplike} maplike
|
|
16
15
|
* @param {PlainObject} [options]
|
|
17
16
|
*/
|
|
18
|
-
export default async function svg(
|
|
17
|
+
export default async function svg(maplike, options = {}) {
|
|
19
18
|
if (!graphvizLoaded) {
|
|
20
19
|
await graphviz.loadWASM();
|
|
21
20
|
graphvizLoaded = true;
|
|
22
21
|
}
|
|
23
|
-
const tree = await getTreeArgument(
|
|
22
|
+
const tree = await getTreeArgument(maplike, "svg", { deep: true });
|
|
24
23
|
const dotText = await dot(tree, options);
|
|
25
24
|
if (dotText === undefined) {
|
|
26
25
|
return undefined;
|
package/src/dev/treeDot.js
CHANGED
|
@@ -12,14 +12,14 @@ import { getDescriptor } from "../common/utilities.js";
|
|
|
12
12
|
/**
|
|
13
13
|
* Render a tree in DOT format.
|
|
14
14
|
*
|
|
15
|
-
* @typedef {import("@weborigami/async-tree").
|
|
15
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
16
16
|
* @typedef {import("@weborigami/async-tree").PlainObject} PlainObject
|
|
17
17
|
*
|
|
18
|
-
* @param {
|
|
18
|
+
* @param {Maplike} maplike
|
|
19
19
|
* @param {PlainObject} [options]
|
|
20
20
|
*/
|
|
21
|
-
export default async function dot(
|
|
22
|
-
const tree = await getTreeArgument(
|
|
21
|
+
export default async function dot(maplike, options = {}) {
|
|
22
|
+
const tree = await getTreeArgument(maplike, "treeDot", { deep: true });
|
|
23
23
|
const rootLabel = getDescriptor(tree) ?? "";
|
|
24
24
|
const treeArcs = await statements(tree, "", rootLabel, options);
|
|
25
25
|
return `digraph g {
|
|
@@ -48,7 +48,7 @@ async function statements(tree, nodePath, nodeLabel, options) {
|
|
|
48
48
|
|
|
49
49
|
// Draw edges and collect labels for the nodes they lead to.
|
|
50
50
|
let nodes = new Map();
|
|
51
|
-
for (const key of await
|
|
51
|
+
for (const key of await Tree.keys(tree)) {
|
|
52
52
|
const destPath = nodePath ? `${trailingSlash.add(nodePath)}${key}` : key;
|
|
53
53
|
const labelUrl = createLinks ? `; labelURL="${destPath}"` : "";
|
|
54
54
|
const arc = ` "${nodePath}" -> "${destPath}" [label="${key}"${labelUrl}];`;
|
|
@@ -67,7 +67,7 @@ async function statements(tree, nodePath, nodeLabel, options) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const expandable =
|
|
70
|
-
value instanceof Array || isPlainObject(value) || Tree.
|
|
70
|
+
value instanceof Array || isPlainObject(value) || Tree.isMap(value);
|
|
71
71
|
if (expandable) {
|
|
72
72
|
const subtree = Tree.from(value);
|
|
73
73
|
const subStatements = await statements(subtree, destPath, null, options);
|
package/src/dev/watch.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConstantMap, getTreeArgument, Tree } from "@weborigami/async-tree";
|
|
2
2
|
import { formatError, moduleCache } from "@weborigami/language";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Let a tree (e.g., of files) respond to changes.
|
|
6
6
|
*
|
|
7
|
+
* @typedef {import("@weborigami/async-tree").AsyncMap} AsyncMap
|
|
7
8
|
* @typedef {import("@weborigami/async-tree").Invocable} Invocable
|
|
8
|
-
* @typedef {import("@weborigami/async-tree").
|
|
9
|
-
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
9
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
10
10
|
*
|
|
11
|
-
* @param {
|
|
11
|
+
* @param {Maplike} maplike
|
|
12
12
|
* @param {Invocable} [fn]
|
|
13
|
-
* @returns {Promise<
|
|
13
|
+
* @returns {Promise<Map|AsyncMap>}
|
|
14
14
|
*/
|
|
15
|
-
export default async function watch(
|
|
16
|
-
const container = await getTreeArgument(
|
|
15
|
+
export default async function watch(maplike, fn) {
|
|
16
|
+
const container = await getTreeArgument(maplike, "watch");
|
|
17
17
|
|
|
18
18
|
// Watch the indicated tree.
|
|
19
19
|
await /** @type {any} */ (container).watch?.();
|
|
@@ -58,7 +58,7 @@ async function evaluateTree(parent, fn) {
|
|
|
58
58
|
message = `Warning: watch expression did not return a tree`;
|
|
59
59
|
}
|
|
60
60
|
console.warn(message);
|
|
61
|
-
tree =
|
|
61
|
+
tree = new ConstantMap(message);
|
|
62
62
|
return tree;
|
|
63
63
|
}
|
|
64
64
|
|
package/src/origami/csv.js
CHANGED
|
@@ -3,7 +3,7 @@ import { isUnpackable, toPlainValue } from "@weborigami/async-tree";
|
|
|
3
3
|
/**
|
|
4
4
|
* Render the object as text in CSV format.
|
|
5
5
|
*
|
|
6
|
-
* The object should a
|
|
6
|
+
* The object should a maplike object such as an array. The output will include
|
|
7
7
|
* a header row with field names taken from the first item in the tree/array.
|
|
8
8
|
*
|
|
9
9
|
* @param {any} object
|
package/src/origami/document.js
CHANGED
package/src/origami/indexPage.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { getTreeArgument } from "@weborigami/async-tree";
|
|
1
|
+
import { getTreeArgument, Tree } from "@weborigami/async-tree";
|
|
2
2
|
import { getDescriptor } from "../common/utilities.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Return a default index.html page for the current tree.
|
|
6
6
|
*
|
|
7
|
-
* @typedef {import("@weborigami/
|
|
8
|
-
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
7
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
9
8
|
*
|
|
10
|
-
* @param {
|
|
9
|
+
* @param {Maplike} maplike
|
|
11
10
|
* @param {string} [basePath]
|
|
12
11
|
*/
|
|
13
|
-
export default async function indexPage(
|
|
14
|
-
const tree = await getTreeArgument(
|
|
15
|
-
const
|
|
12
|
+
export default async function indexPage(maplike, basePath) {
|
|
13
|
+
const tree = await getTreeArgument(maplike, "svg");
|
|
14
|
+
const treeKeys = await Tree.keys(tree);
|
|
16
15
|
|
|
17
16
|
// Skip system-ish files that start with a period. Also skip `index.html`.
|
|
18
|
-
const filtered =
|
|
17
|
+
const filtered = treeKeys.filter(
|
|
19
18
|
(key) => !(key.startsWith?.(".") || key === "index.html")
|
|
20
19
|
);
|
|
21
20
|
|
package/src/origami/inline.js
CHANGED
package/src/origami/json.js
CHANGED
package/src/origami/jsonKeys.js
CHANGED
|
@@ -1,36 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AsyncMap,
|
|
3
|
+
Tree,
|
|
4
|
+
getTreeArgument,
|
|
5
|
+
jsonKeys,
|
|
6
|
+
} from "@weborigami/async-tree";
|
|
2
7
|
|
|
3
8
|
/**
|
|
4
9
|
* Expose .keys.json for a tree.
|
|
5
10
|
*
|
|
6
|
-
* @typedef {import("@weborigami/
|
|
7
|
-
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
11
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
8
12
|
*
|
|
9
|
-
* @param {
|
|
10
|
-
* @returns {Promise<
|
|
13
|
+
* @param {Maplike} maplike
|
|
14
|
+
* @returns {Promise<AsyncMap>}
|
|
11
15
|
*/
|
|
12
|
-
export default async function jsonKeysBuiltin(
|
|
13
|
-
const
|
|
14
|
-
return
|
|
16
|
+
export default async function jsonKeysBuiltin(maplike) {
|
|
17
|
+
const source = await getTreeArgument(maplike, "jsonKeys");
|
|
18
|
+
return jsonKeysMap(source);
|
|
15
19
|
}
|
|
16
20
|
|
|
17
|
-
function
|
|
18
|
-
|
|
21
|
+
function jsonKeysMap(source) {
|
|
22
|
+
const result = Object.assign(new AsyncMap(), {
|
|
23
|
+
description: "jsonKeys",
|
|
24
|
+
|
|
19
25
|
async get(key) {
|
|
20
|
-
let value = await
|
|
26
|
+
let value = await source.get(key);
|
|
21
27
|
if (value === undefined && key === ".keys.json") {
|
|
22
28
|
value = await jsonKeys.stringify(this);
|
|
23
|
-
} else if (Tree.
|
|
24
|
-
const subtree = Tree.from(value, { deep: true, parent:
|
|
25
|
-
value =
|
|
29
|
+
} else if (Tree.isMaplike(value)) {
|
|
30
|
+
const subtree = Tree.from(value, { deep: true, parent: result });
|
|
31
|
+
value = jsonKeysMap(subtree);
|
|
26
32
|
}
|
|
27
33
|
return value;
|
|
28
34
|
},
|
|
29
35
|
|
|
30
|
-
async keys() {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
async *keys() {
|
|
37
|
+
const treeKeys = new Set(await Tree.keys(source));
|
|
38
|
+
treeKeys.add(".keys.json");
|
|
39
|
+
yield* treeKeys;
|
|
34
40
|
},
|
|
41
|
+
|
|
42
|
+
source: source,
|
|
43
|
+
|
|
44
|
+
trailingSlashKeys: source.trailingSlashKeys,
|
|
35
45
|
});
|
|
46
|
+
return result;
|
|
36
47
|
}
|
package/src/origami/once.js
CHANGED
package/src/origami/ori.js
CHANGED
|
@@ -15,7 +15,6 @@ const TypedArray = Object.getPrototypeOf(Uint8Array);
|
|
|
15
15
|
* Parse an Origami expression, evaluate it in the context of a tree (provided
|
|
16
16
|
* by `this`), and return the result as text.
|
|
17
17
|
*
|
|
18
|
-
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
19
18
|
*
|
|
20
19
|
* @param {string} expression
|
|
21
20
|
*/
|
|
@@ -90,8 +89,8 @@ async function format(result) {
|
|
|
90
89
|
text = result;
|
|
91
90
|
}
|
|
92
91
|
|
|
93
|
-
// If the result is
|
|
94
|
-
if (Tree.
|
|
92
|
+
// If the result is maplike, attach it to the text output.
|
|
93
|
+
if (Tree.isMaplike(result)) {
|
|
95
94
|
if (typeof text === "string") {
|
|
96
95
|
// @ts-ignore
|
|
97
96
|
text = new String(text);
|
package/src/origami/pack.js
CHANGED
package/src/origami/post.js
CHANGED
|
@@ -18,7 +18,7 @@ export default async function post(url, data) {
|
|
|
18
18
|
if (isUnpackable(data)) {
|
|
19
19
|
data = await data.unpack();
|
|
20
20
|
}
|
|
21
|
-
if (Tree.
|
|
21
|
+
if (Tree.isMaplike(data)) {
|
|
22
22
|
const value = await toPlainValue(data);
|
|
23
23
|
body = JSON.stringify(value);
|
|
24
24
|
headers = {
|
package/src/origami/rss.js
CHANGED
|
@@ -2,10 +2,9 @@ import { getTreeArgument, Tree } from "@weborigami/async-tree";
|
|
|
2
2
|
import jsonFeedToRss from "@weborigami/json-feed-to-rss";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @typedef {import("@weborigami/
|
|
6
|
-
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
5
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
7
6
|
*
|
|
8
|
-
* @param {
|
|
7
|
+
* @param {Maplike} jsonFeed
|
|
9
8
|
* @param {any} options
|
|
10
9
|
*/
|
|
11
10
|
export default async function rss(jsonFeed, options = {}) {
|
package/src/origami/sitemap.js
CHANGED
|
@@ -11,32 +11,22 @@ const templateText = `(urls) => \`<?xml version="1.0" encoding="UTF-8"?>
|
|
|
11
11
|
`;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* @typedef {import("@weborigami/
|
|
15
|
-
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
14
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
16
15
|
*
|
|
17
|
-
* @param {
|
|
16
|
+
* @param {Maplike} maplike
|
|
18
17
|
* @param {{ assumeSlashes?: boolean, base?: string }} options
|
|
19
18
|
* @returns {Promise<string>}
|
|
20
19
|
*/
|
|
21
|
-
export default async function sitemap(
|
|
22
|
-
const tree = await getTreeArgument(
|
|
20
|
+
export default async function sitemap(maplike, options = {}) {
|
|
21
|
+
const tree = await getTreeArgument(maplike, "sitemap");
|
|
23
22
|
|
|
24
23
|
// We're only interested in keys that end in .html or with no extension.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
async keys() {
|
|
30
|
-
const keys = Array.from(await tree.keys());
|
|
31
|
-
return keys.filter((key) => test(key));
|
|
32
|
-
},
|
|
24
|
+
const filtered = await Tree.filter(
|
|
25
|
+
tree,
|
|
26
|
+
(value, key) => key.endsWith?.(".html") || !key.includes?.(".")
|
|
27
|
+
);
|
|
33
28
|
|
|
34
|
-
|
|
35
|
-
return test(key) ? tree.get(key) : undefined;
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const treePaths = await Tree.paths(filterTree, options);
|
|
29
|
+
const treePaths = await Tree.paths(filtered, options);
|
|
40
30
|
|
|
41
31
|
// For simplicity, we assume that HTML pages will end in .html.
|
|
42
32
|
// If the page is named index.html, we remove index.html from
|
package/src/origami/static.js
CHANGED
|
@@ -1,43 +1,68 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AsyncMap,
|
|
3
|
+
Tree,
|
|
4
|
+
getTreeArgument,
|
|
5
|
+
jsonKeys,
|
|
6
|
+
} from "@weborigami/async-tree";
|
|
2
7
|
import indexPage from "./indexPage.js";
|
|
3
8
|
|
|
4
9
|
/**
|
|
5
10
|
* Expose common static keys (index.html, .keys.json) for a tree.
|
|
6
11
|
*
|
|
7
|
-
* @typedef
|
|
8
|
-
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
12
|
+
* @typedef {import("@weborigami/async-tree").Maplike} Maplike
|
|
9
13
|
*
|
|
10
|
-
* @param {
|
|
11
|
-
* @returns {Promise<
|
|
14
|
+
* @param {Maplike} maplike
|
|
15
|
+
* @returns {Promise<AsyncMap>}
|
|
12
16
|
*/
|
|
13
|
-
export default async function staticBuiltin(
|
|
14
|
-
const
|
|
15
|
-
return
|
|
17
|
+
export default async function staticBuiltin(maplike) {
|
|
18
|
+
const source = await getTreeArgument(maplike, "static");
|
|
19
|
+
return staticMap(source);
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
// The name we'll register as a builtin
|
|
19
23
|
staticBuiltin.key = "static";
|
|
20
24
|
|
|
21
|
-
function
|
|
22
|
-
|
|
25
|
+
function staticMap(source) {
|
|
26
|
+
const result = Object.assign(new AsyncMap(), {
|
|
27
|
+
description: "static",
|
|
28
|
+
|
|
23
29
|
async get(key) {
|
|
24
|
-
let value = await
|
|
30
|
+
let value = await source.get(key);
|
|
25
31
|
if (value === undefined && key === "index.html") {
|
|
26
32
|
value = await indexPage(this);
|
|
27
33
|
} else if (value === undefined && key === ".keys.json") {
|
|
28
34
|
value = await jsonKeys.stringify(this);
|
|
29
|
-
} else if (Tree.
|
|
30
|
-
const subtree = Tree.from(value, { parent:
|
|
31
|
-
value =
|
|
35
|
+
} else if (Tree.isMaplike(value)) {
|
|
36
|
+
const subtree = Tree.from(value, { parent: result });
|
|
37
|
+
value = staticMap(subtree);
|
|
32
38
|
}
|
|
33
39
|
return value;
|
|
34
40
|
},
|
|
35
41
|
|
|
36
|
-
async keys() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
async *keys() {
|
|
43
|
+
let needsIndex = true;
|
|
44
|
+
let needsKeysJson = true;
|
|
45
|
+
for await (const key of source.keys()) {
|
|
46
|
+
if (key === "index.html") {
|
|
47
|
+
needsIndex = false;
|
|
48
|
+
}
|
|
49
|
+
if (key === ".keys.json") {
|
|
50
|
+
needsKeysJson = false;
|
|
51
|
+
}
|
|
52
|
+
yield key;
|
|
53
|
+
}
|
|
54
|
+
if (needsIndex) {
|
|
55
|
+
yield "index.html";
|
|
56
|
+
}
|
|
57
|
+
if (needsKeysJson) {
|
|
58
|
+
yield ".keys.json";
|
|
59
|
+
}
|
|
41
60
|
},
|
|
61
|
+
|
|
62
|
+
source: source,
|
|
63
|
+
|
|
64
|
+
trailingSlashKeys: source.trailingSlashKeys,
|
|
42
65
|
});
|
|
66
|
+
|
|
67
|
+
return result;
|
|
43
68
|
}
|
package/src/origami/yaml.js
CHANGED