@weborigami/origami 0.0.72 → 0.1.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/main.js +12 -0
- package/package.json +5 -7
- package/src/builtins.js +62 -0
- package/src/builtinsTree.js +36 -0
- package/src/calc/calc.js +61 -0
- package/src/cli/cli.js +6 -4
- package/src/{misc → common}/assertTreeIsDefined.js +4 -1
- package/src/common/constructHref.js +20 -0
- package/src/common/constructSiteTree.js +34 -0
- package/src/common/fetchAndHandleExtension.js +26 -0
- package/src/{misc → common}/getTreeArgument.js +11 -5
- package/src/common/processUnpackedContent.js +4 -13
- package/src/common/utilities.d.ts +0 -1
- package/src/common/utilities.js +3 -30
- package/src/deprecated.js +140 -0
- package/src/{common → dev}/ExplorableSiteTransform.js +1 -1
- package/src/{misc → dev}/OriCommandTransform.js +2 -2
- package/src/{builtins/@code.js → dev/code.js} +2 -2
- package/src/{builtins/@debug.js → dev/debug.js} +4 -7
- package/src/dev/dev.js +9 -0
- package/src/{builtins/@explore.js → dev/explore.js} +22 -28
- package/src/{misc → dev}/explore.js.inline +4 -4
- package/src/{misc → dev}/explore.ori +3 -3
- package/src/{builtins/@log.js → dev/log.js} +1 -1
- package/src/{builtins/@serve.js → dev/serve.js} +5 -8
- package/src/{builtins/@svg.js → dev/svg.js} +9 -6
- package/src/{misc → dev}/treeDot.js +0 -3
- package/src/{builtins/@watch.js → dev/watch.js} +8 -6
- package/src/handlers/handlerExports.js +16 -0
- package/src/handlers/handlers.js +37 -0
- package/src/{builtins → handlers}/js.handler.js +1 -1
- package/src/{builtins → handlers}/json.handler.js +9 -1
- package/src/handlers/mjs.handler.js +2 -0
- package/src/{builtins → handlers}/ori.handler.js +5 -7
- package/src/{builtins → handlers}/oridocument.handler.js +1 -1
- package/src/{builtins → handlers}/wasm.handler.js +1 -1
- package/src/{builtins → handlers}/yaml.handler.js +8 -1
- package/src/handlers/yml.handler.js +2 -0
- package/src/help/help.js +103 -0
- package/src/help/help.yaml +425 -0
- package/src/{builtins/@image → image}/format.js +2 -2
- package/src/{builtins/@image → image}/formatFn.js +1 -1
- package/src/image/image.js +2 -0
- package/src/{builtins/@image → image}/resize.js +2 -2
- package/src/{builtins/@image → image}/resizeFn.js +1 -1
- package/src/internal.js +24 -0
- package/src/{builtins/@js.js → js.js} +7 -6
- package/src/{builtins/@node.js → node.js} +1 -6
- package/src/{builtins/@basename.js → origami/basename.js} +2 -2
- package/src/{builtins/@config.js → origami/config.js} +1 -4
- package/src/{builtins/@json.js → origami/json.js} +2 -5
- package/src/{builtins/@jsonParse.js → origami/jsonParse.js} +0 -3
- package/src/{builtins/@once.js → origami/once.js} +2 -2
- package/src/{builtins/@ori.js → origami/ori.js} +8 -9
- package/src/origami/origami.js +29 -0
- package/src/{builtins/@pack.js → origami/pack.js} +2 -2
- package/src/{builtins/@project.js → origami/project.js} +18 -16
- package/src/{builtins/@regexMatch.js → origami/regexMatch.js} +1 -1
- package/src/origami/repeat.js +5 -0
- package/src/{builtins/@shell.js → origami/shell.js} +0 -3
- package/src/{builtins/@stdin.js → origami/stdin.js} +0 -3
- package/src/{builtins/@string.js → origami/string.js} +2 -2
- package/src/{builtins/@unpack.js → origami/unpack.js} +2 -2
- package/src/{builtins/@yaml.js → origami/yaml.js} +2 -5
- package/src/{builtins/@yamlParse.js → origami/yamlParse.js} +0 -3
- package/src/protocols/explore.js +19 -0
- package/src/{builtins/@files.js → protocols/files.js} +2 -5
- package/src/protocols/http.js +18 -0
- package/src/protocols/https.js +18 -0
- package/src/protocols/httpstree.js +19 -0
- package/src/protocols/httptree.js +19 -0
- package/src/protocols/inherited.js +18 -0
- package/src/protocols/new.js +42 -0
- package/src/{builtins/@package.js → protocols/package.js} +2 -2
- package/src/protocols/scope.js +14 -0
- package/src/server/constructResponse.js +5 -5
- package/src/{builtins/@siteAudit.js → site/audit.js} +4 -4
- package/src/{builtins/@crawl.js → site/crawler/crawl.js} +3 -6
- package/src/{crawler → site/crawler}/findPaths.js +2 -3
- package/src/{crawler → site/crawler}/utilities.js +2 -3
- package/src/{builtins/@index.js → site/index.js} +2 -5
- package/src/{builtins/@jsonKeys.js → site/jsonKeys.js} +5 -5
- package/src/{builtins/@rss.js → site/rss.js} +2 -5
- package/src/site/site.js +9 -0
- package/src/{builtins/@sitemap.js → site/sitemap.js} +8 -12
- package/src/{builtins/@static.js → site/static.js} +7 -7
- package/src/{builtins/@document.js → text/document.js} +2 -2
- package/src/{builtins/@inline.js → text/inline.js} +10 -13
- package/src/{builtins/@mdHtml.js → text/mdHtml.js} +7 -10
- package/src/text/origamiHighlightDefinition.js +53 -0
- package/src/text/text.js +4 -0
- package/src/{builtins/@addNextPrevious.js → tree/addNextPrevious.js} +7 -2
- package/src/{builtins/@cache.js → tree/cache.js} +2 -5
- package/src/{builtins/@clean.js → tree/clear.js} +4 -4
- package/src/{builtins/@concat.js → tree/concat.js} +2 -5
- package/src/{builtins/@copy.js → tree/copy.js} +3 -10
- package/src/{builtins/@deepMapFn.js → tree/deepMap.js} +13 -6
- package/src/{builtins/@deepMerge.js → tree/deepMerge.js} +4 -7
- package/src/{builtins/@deepReverse.js → tree/deepReverse.js} +8 -2
- package/src/tree/deepTake.js +26 -0
- package/src/{builtins/@deepValues.js → tree/deepValues.js} +2 -6
- package/src/{builtins/@defineds.js → tree/defineds.js} +7 -2
- package/src/{builtins/@filter.js → tree/filter.js} +3 -6
- package/src/{builtins/@first.js → tree/first.js} +2 -5
- package/src/{builtins/@fnTree.js → tree/fromFn.js} +3 -6
- package/src/{builtins/@globs.js → tree/globs.js} +3 -6
- package/src/tree/group.js +26 -0
- package/src/{builtins/@inners.js → tree/inners.js} +2 -5
- package/src/{builtins/@keys.js → tree/keys.js} +2 -5
- package/src/{builtins/@length.js → tree/length.js} +2 -2
- package/src/{builtins → tree}/map.d.ts +3 -6
- package/src/tree/map.js +154 -0
- package/src/{builtins/@mapFn.js → tree/mapFn.js} +14 -6
- package/src/{builtins/@match.js → tree/match.js} +2 -5
- package/src/{builtins/@merge.js → tree/merge.js} +2 -5
- package/src/tree/paginate.js +61 -0
- package/src/{builtins/@parent.js → tree/parent.js} +2 -5
- package/src/{builtins/@plain.js → tree/plain.js} +2 -5
- package/src/{builtins/@reverse.js → tree/reverse.js} +2 -5
- package/src/{builtins/@setDeep.js → tree/setDeep.js} +0 -3
- package/src/{builtins/@shuffle.js → tree/shuffle.js} +3 -9
- package/src/{builtins/@sortFn.js → tree/sort.js} +12 -17
- package/src/tree/take.js +19 -0
- package/src/tree/tree.js +49 -0
- package/src/{builtins/@values.js → tree/values.js} +2 -5
- package/exports/PathTransform.d.ts +0 -5
- package/exports/PathTransform.js +0 -20
- package/exports/buildExports.js +0 -112
- package/exports/exports.js +0 -148
- package/src/builtins/@builtins.js +0 -15
- package/src/builtins/@deepMap.js +0 -19
- package/src/builtins/@deepTake.js +0 -21
- package/src/builtins/@deepTakeFn.js +0 -21
- package/src/builtins/@equals.js +0 -6
- package/src/builtins/@exploreSite.js +0 -16
- package/src/builtins/@false.js +0 -1
- package/src/builtins/@fetch.js +0 -7
- package/src/builtins/@group.js +0 -20
- package/src/builtins/@groupFn.js +0 -33
- package/src/builtins/@help.js +0 -49
- package/src/builtins/@http.js +0 -19
- package/src/builtins/@https.js +0 -19
- package/src/builtins/@if.js +0 -28
- package/src/builtins/@inherited.js +0 -17
- package/src/builtins/@map.js +0 -19
- package/src/builtins/@math.js +0 -17
- package/src/builtins/@not.js +0 -6
- package/src/builtins/@or.js +0 -6
- package/src/builtins/@paginate.js +0 -18
- package/src/builtins/@paginateFn.js +0 -58
- package/src/builtins/@repeat.js +0 -8
- package/src/builtins/@sort.js +0 -23
- package/src/builtins/@table.js +0 -69
- package/src/builtins/@take.js +0 -20
- package/src/builtins/@takeFn.js +0 -20
- package/src/builtins/@tree.js +0 -4
- package/src/builtins/@treeHttp.js +0 -19
- package/src/builtins/@treeHttps.js +0 -19
- package/src/builtins/@true.js +0 -1
- package/src/builtins/mjs.handler.js +0 -2
- package/src/builtins/yml.handler.js +0 -2
- package/src/builtins/~.js +0 -9
- package/src/cli/showUsage.js +0 -86
- package/src/common/CommandModulesTransform.d.ts +0 -5
- package/src/common/CommandModulesTransform.js +0 -39
- package/src/common/arrowsMapFn.js +0 -35
- package/src/misc/origamiHighlightDefinition.js +0 -36
- /package/src/{misc → common}/assertTreeIsDefined.d.ts +0 -0
- /package/src/{common → dev}/ExplorableSiteTransform.d.ts +0 -0
- /package/src/{misc → dev}/OriCommandTransform.d.ts +0 -0
- /package/src/{builtins/@breakpoint.js → dev/breakpoint.js} +0 -0
- /package/src/{builtins/@changes.js → dev/changes.js} +0 -0
- /package/src/{misc → dev}/explore.css +0 -0
- /package/src/{builtins → handlers}/css.handler.js +0 -0
- /package/src/{builtins → handlers}/htm.handler.js +0 -0
- /package/src/{builtins → handlers}/html.handler.js +0 -0
- /package/src/{builtins → handlers}/jpeg.handler.js +0 -0
- /package/src/{builtins → handlers}/jpg.handler.js +0 -0
- /package/src/{builtins → handlers}/md.handler.js +0 -0
- /package/src/{builtins → handlers}/txt.handler.js +0 -0
- /package/src/{builtins → handlers}/xhtml.handler.js +0 -0
- /package/src/{builtins/@naturalOrder.js → origami/naturalOrder.js} +0 -0
- /package/src/{builtins/@post.js → origami/post.js} +0 -0
- /package/src/{builtins/@regexMatchFn.js → origami/regexMatchFn.js} +0 -0
- /package/src/{builtins/@slash.js → origami/slash.js} +0 -0
- /package/src/{builtins/@version.js → origami/version.js} +0 -0
- /package/src/{crawler → site/crawler}/crawlResources.js +0 -0
- /package/src/{builtins/@redirect.js → site/redirect.js} +0 -0
- /package/src/{builtins/@slug.js → site/slug.js} +0 -0
- /package/src/{builtins/@indent.js → text/indent.js} +0 -0
- /package/src/{common → tree}/FilterTree.js +0 -0
- /package/src/{common → tree}/GlobTree.js +0 -0
- /package/src/{common → tree}/ShuffleTransform.js +0 -0
- /package/src/{builtins/@calendarTree.js → tree/calendar.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import getTreeArgument from "../
|
|
1
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Return the number of keys in the tree.
|
|
@@ -9,7 +9,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
9
9
|
* @param {Treelike} [treelike]
|
|
10
10
|
*/
|
|
11
11
|
export default async function length(treelike) {
|
|
12
|
-
const tree = await getTreeArgument(this, arguments, treelike, "
|
|
12
|
+
const tree = await getTreeArgument(this, arguments, treelike, "tree:length");
|
|
13
13
|
const keys = Array.from(await tree.keys());
|
|
14
14
|
return keys.length;
|
|
15
15
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TreeMapOptions as AsyncTreeMapOptions, Treelike, TreeTransform, ValueKeyFn } from "@weborigami/async-tree";
|
|
2
2
|
import { AsyncTree } from "@weborigami/types";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/* Add more properties to TreeMapOptions */
|
|
5
|
+
type TreeMapOptions = AsyncTreeMapOptions &{
|
|
6
6
|
description?: string;
|
|
7
7
|
extension?: string;
|
|
8
|
-
inverseKey?: KeyFn;
|
|
9
|
-
key?: ValueKeyFn;
|
|
10
8
|
needsSourceValue?: boolean;
|
|
11
|
-
value?: ValueKeyFn;
|
|
12
9
|
};
|
|
13
10
|
|
|
14
11
|
export default function treeMap(options: ValueKeyFn | TreeMapOptions): TreeTransform;
|
package/src/tree/map.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cachedKeyFunctions,
|
|
3
|
+
isPlainObject,
|
|
4
|
+
keyFunctionsForExtensions,
|
|
5
|
+
map as mapTransform,
|
|
6
|
+
} from "@weborigami/async-tree";
|
|
7
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
8
|
+
import { toFunction } from "../common/utilities.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Map a hierarchical tree of keys and values to a new tree of keys and values.
|
|
12
|
+
*
|
|
13
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
14
|
+
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
15
|
+
* @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
|
|
16
|
+
* @typedef {import("./map.js").TreeMapOptions} TreeMapOptions
|
|
17
|
+
*
|
|
18
|
+
* @this {AsyncTree|null}
|
|
19
|
+
* @param {Treelike} treelike
|
|
20
|
+
* @param {ValueKeyFn|TreeMapOptions} operation
|
|
21
|
+
*/
|
|
22
|
+
export default async function map(treelike, operation) {
|
|
23
|
+
// The tree we're going to map
|
|
24
|
+
const source = await getTreeArgument(this, arguments, treelike, "tree:map");
|
|
25
|
+
// The tree in which the map operation happens
|
|
26
|
+
const context = this;
|
|
27
|
+
|
|
28
|
+
const options = extendedOptions(context, operation);
|
|
29
|
+
const mapped = mapTransform(source, options);
|
|
30
|
+
mapped.parent = context;
|
|
31
|
+
return mapped;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Return a function that transforms a tree of keys and values to a new tree of
|
|
36
|
+
* keys and values.
|
|
37
|
+
*
|
|
38
|
+
* @param {AsyncTree|null} context
|
|
39
|
+
* @param {ValueKeyFn|TreeMapOptions} operation
|
|
40
|
+
*/
|
|
41
|
+
function extendedOptions(context, operation) {
|
|
42
|
+
// Identify whether the map instructions take the form of a value function or
|
|
43
|
+
// a dictionary of options.
|
|
44
|
+
/** @type {TreeMapOptions} */
|
|
45
|
+
let options;
|
|
46
|
+
/** @type {ValueKeyFn|undefined} */
|
|
47
|
+
let valueFn;
|
|
48
|
+
if (isPlainObject(operation)) {
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
options = operation;
|
|
51
|
+
if (`value` in options && !options.value) {
|
|
52
|
+
throw new TypeError(`map: The value function is not defined.`);
|
|
53
|
+
}
|
|
54
|
+
valueFn = options?.value;
|
|
55
|
+
} else if (
|
|
56
|
+
typeof operation === "function" ||
|
|
57
|
+
typeof (/** @type {any} */ (operation)?.unpack) === "function"
|
|
58
|
+
) {
|
|
59
|
+
valueFn = operation;
|
|
60
|
+
options = {};
|
|
61
|
+
} else {
|
|
62
|
+
throw new TypeError(
|
|
63
|
+
`map: You must specify a value function or options dictionary as the first parameter.`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const { deep, extension, needsSourceValue } = options;
|
|
68
|
+
const description = options.description ?? `map ${extension ?? ""}`;
|
|
69
|
+
const keyFn = options.key;
|
|
70
|
+
const inverseKeyFn = options.inverseKey;
|
|
71
|
+
|
|
72
|
+
if (extension && (keyFn || inverseKeyFn)) {
|
|
73
|
+
throw new TypeError(
|
|
74
|
+
`map: You can't specify extensions and also a key or inverseKey function`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let extendedValueFn;
|
|
79
|
+
if (valueFn) {
|
|
80
|
+
const resolvedValueFn = toFunction(valueFn);
|
|
81
|
+
// Have the value function run in this tree.
|
|
82
|
+
extendedValueFn = resolvedValueFn.bind(context);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Extend the key functions to run in this tree.
|
|
86
|
+
let extendedKeyFn;
|
|
87
|
+
let extendedInverseKeyFn;
|
|
88
|
+
if (extension) {
|
|
89
|
+
let { resultExtension, sourceExtension } = parseExtensions(extension);
|
|
90
|
+
const keyFns = keyFunctionsForExtensions({
|
|
91
|
+
resultExtension,
|
|
92
|
+
sourceExtension,
|
|
93
|
+
});
|
|
94
|
+
extendedKeyFn = keyFns.key;
|
|
95
|
+
extendedInverseKeyFn = keyFns.inverseKey;
|
|
96
|
+
} else if (keyFn) {
|
|
97
|
+
const resolvedKeyFn = toFunction(keyFn);
|
|
98
|
+
async function keyWithValueFn(sourceKey, sourceTree) {
|
|
99
|
+
const sourceValue = await sourceTree.get(sourceKey);
|
|
100
|
+
const resultKey = await resolvedKeyFn(sourceValue, sourceKey, sourceTree);
|
|
101
|
+
return resultKey;
|
|
102
|
+
}
|
|
103
|
+
const keyFns = cachedKeyFunctions(keyWithValueFn, deep);
|
|
104
|
+
extendedKeyFn = keyFns.key;
|
|
105
|
+
extendedInverseKeyFn = keyFns.inverseKey;
|
|
106
|
+
} else {
|
|
107
|
+
// Use sidecar keyFn/inverseKey functions if the valueFn defines them.
|
|
108
|
+
extendedKeyFn = /** @type {any} */ (valueFn)?.key;
|
|
109
|
+
extendedInverseKeyFn = /** @type {any} */ (valueFn)?.inverseKey;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
deep,
|
|
114
|
+
description,
|
|
115
|
+
inverseKey: extendedInverseKeyFn,
|
|
116
|
+
key: extendedKeyFn,
|
|
117
|
+
needsSourceValue,
|
|
118
|
+
value: extendedValueFn,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Given a string specifying an extension or a mapping of one extension to another,
|
|
124
|
+
* return the source and result extensions.
|
|
125
|
+
*
|
|
126
|
+
* Syntax:
|
|
127
|
+
* foo
|
|
128
|
+
* foo→bar Unicode Rightwards Arrow
|
|
129
|
+
* foo->bar hyphen and greater-than sign
|
|
130
|
+
*
|
|
131
|
+
* @param {string} specifier
|
|
132
|
+
*/
|
|
133
|
+
function parseExtensions(specifier) {
|
|
134
|
+
const lowercase = specifier?.toLowerCase() ?? "";
|
|
135
|
+
const extensionRegex =
|
|
136
|
+
/^((?<sourceExtension>\.?\S*)\s*(→|->)\s*(?<resultExtension>\.?\S*))|(?<extension>\.?\S*)$/;
|
|
137
|
+
const match = lowercase.match(extensionRegex);
|
|
138
|
+
if (!match) {
|
|
139
|
+
// Shouldn't happen because the regex is exhaustive.
|
|
140
|
+
throw new Error(`map: Invalid extension specifier "${specifier}".`);
|
|
141
|
+
}
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
const { extension, resultExtension, sourceExtension } = match.groups;
|
|
144
|
+
if (extension) {
|
|
145
|
+
// foo
|
|
146
|
+
return {
|
|
147
|
+
resultExtension: extension,
|
|
148
|
+
sourceExtension: extension,
|
|
149
|
+
};
|
|
150
|
+
} else {
|
|
151
|
+
// foo→bar
|
|
152
|
+
return { resultExtension, sourceExtension };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
cachedKeyFunctions,
|
|
3
3
|
isPlainObject,
|
|
4
4
|
keyFunctionsForExtensions,
|
|
5
|
-
|
|
5
|
+
map,
|
|
6
6
|
} from "@weborigami/async-tree";
|
|
7
|
+
import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
|
|
7
8
|
import { toFunction } from "../common/utilities.js";
|
|
8
|
-
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Return a function that transforms a tree of keys and values to a new tree of
|
|
@@ -14,7 +14,7 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
|
14
14
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
15
15
|
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
16
16
|
* @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
|
|
17
|
-
* @typedef {import("./map.
|
|
17
|
+
* @typedef {import("./map.js").TreeMapOptions} TreeMapOptions
|
|
18
18
|
*
|
|
19
19
|
* @this {AsyncTree|null}
|
|
20
20
|
* @param {ValueKeyFn|TreeMapOptions} operation
|
|
@@ -100,17 +100,25 @@ export default function mapFnBuiltin(operation) {
|
|
|
100
100
|
extendedInverseKeyFn = /** @type {any} */ (valueFn)?.inverseKey;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
const fn = mapFn({
|
|
103
|
+
// const fn = mapFn({
|
|
104
|
+
// deep,
|
|
105
|
+
// description,
|
|
106
|
+
// inverseKey: extendedInverseKeyFn,
|
|
107
|
+
// key: extendedKeyFn,
|
|
108
|
+
// needsSourceValue,
|
|
109
|
+
// value: extendedValueFn,
|
|
110
|
+
// });
|
|
111
|
+
const temp = {
|
|
104
112
|
deep,
|
|
105
113
|
description,
|
|
106
114
|
inverseKey: extendedInverseKeyFn,
|
|
107
115
|
key: extendedKeyFn,
|
|
108
116
|
needsSourceValue,
|
|
109
117
|
value: extendedValueFn,
|
|
110
|
-
}
|
|
118
|
+
};
|
|
111
119
|
|
|
112
120
|
return (treelike) => {
|
|
113
|
-
const mapped =
|
|
121
|
+
const mapped = map(treelike, temp);
|
|
114
122
|
mapped.parent = tree;
|
|
115
123
|
return mapped;
|
|
116
124
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tree } from "@weborigami/async-tree";
|
|
2
|
-
import assertTreeIsDefined from "../
|
|
2
|
+
import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Return a tree with the indicated keys (if provided).
|
|
@@ -24,7 +24,7 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
|
24
24
|
* @param {Treelike} [keys]
|
|
25
25
|
*/
|
|
26
26
|
export default function match(pattern, resultFn, keys = []) {
|
|
27
|
-
assertTreeIsDefined(this, "match");
|
|
27
|
+
assertTreeIsDefined(this, "tree:match");
|
|
28
28
|
let regex;
|
|
29
29
|
if (typeof pattern === "string") {
|
|
30
30
|
// Convert the simple pattern format into a regular expression.
|
|
@@ -77,6 +77,3 @@ export default function match(pattern, resultFn, keys = []) {
|
|
|
77
77
|
|
|
78
78
|
return result;
|
|
79
79
|
}
|
|
80
|
-
|
|
81
|
-
match.usage = `@match <pattern>, <fn>, [<keys>]\tMatches simple patterns or regular expressions`;
|
|
82
|
-
match.documentation = "https://weborigami.org/language/@match.html";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isPlainObject, isUnpackable, merge } from "@weborigami/async-tree";
|
|
2
|
-
import assertTreeIsDefined from "../
|
|
2
|
+
import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Create a tree that's the result of merging the given trees.
|
|
@@ -11,7 +11,7 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
|
11
11
|
* @param {(Treelike|null)[]} trees
|
|
12
12
|
*/
|
|
13
13
|
export default async function treeMerge(...trees) {
|
|
14
|
-
assertTreeIsDefined(this, "merge");
|
|
14
|
+
assertTreeIsDefined(this, "tree:merge");
|
|
15
15
|
|
|
16
16
|
// Filter out null or undefined trees.
|
|
17
17
|
/** @type {Treelike[]}
|
|
@@ -39,6 +39,3 @@ export default async function treeMerge(...trees) {
|
|
|
39
39
|
const result = merge(...unpacked);
|
|
40
40
|
return result;
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
treeMerge.usage = `@merge <...trees>\tMerge the given trees`;
|
|
44
|
-
treeMerge.documentation = "https://weborigami.org/cli/builtins.html#@merge";
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Return a new grouping of the treelike's values into chunks of the specified
|
|
5
|
+
* size.
|
|
6
|
+
*
|
|
7
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
8
|
+
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
9
|
+
*
|
|
10
|
+
* @this {AsyncTree|null}
|
|
11
|
+
* @param {Treelike} [treelike]
|
|
12
|
+
* @param {number} [size=10]
|
|
13
|
+
*/
|
|
14
|
+
export default async function paginate(treelike, size = 10) {
|
|
15
|
+
const tree = await getTreeArgument(
|
|
16
|
+
this,
|
|
17
|
+
arguments,
|
|
18
|
+
treelike,
|
|
19
|
+
"tree:paginate"
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const keys = Array.from(await tree.keys());
|
|
23
|
+
const pageCount = Math.ceil(keys.length / size);
|
|
24
|
+
|
|
25
|
+
const paginated = {
|
|
26
|
+
async get(pageKey) {
|
|
27
|
+
// Note: page numbers are 1-based.
|
|
28
|
+
const pageNumber = Number(pageKey);
|
|
29
|
+
if (Number.isNaN(pageNumber)) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const nextPage = pageNumber + 1 <= pageCount ? pageNumber + 1 : null;
|
|
33
|
+
const previousPage = pageNumber - 1 >= 1 ? pageNumber - 1 : null;
|
|
34
|
+
const items = {};
|
|
35
|
+
for (
|
|
36
|
+
let index = (pageNumber - 1) * size;
|
|
37
|
+
index < Math.min(keys.length, pageNumber * size);
|
|
38
|
+
index++
|
|
39
|
+
) {
|
|
40
|
+
const key = keys[index];
|
|
41
|
+
items[key] = await tree.get(keys[index]);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
items,
|
|
46
|
+
nextPage,
|
|
47
|
+
pageCount,
|
|
48
|
+
pageNumber,
|
|
49
|
+
previousPage,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
async keys() {
|
|
54
|
+
// Return an array from 1..totalPages
|
|
55
|
+
return Array.from({ length: pageCount }, (_, index) => index + 1);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
paginated.parent = this;
|
|
60
|
+
return paginated;
|
|
61
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import getTreeArgument from "../
|
|
1
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns the parent of the current tree.
|
|
@@ -10,9 +10,6 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
10
10
|
* @param {Treelike} [treelike]
|
|
11
11
|
*/
|
|
12
12
|
export default async function parent(treelike) {
|
|
13
|
-
const tree = await getTreeArgument(this, arguments, treelike, "
|
|
13
|
+
const tree = await getTreeArgument(this, arguments, treelike, "tree:parent");
|
|
14
14
|
return tree.parent;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
parent.usage = `@parent\tThe parent of the current tree`;
|
|
18
|
-
parent.documentation = "https://weborigami.org/cli/builtins.html#parent";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tree } from "@weborigami/async-tree";
|
|
2
|
-
import getTreeArgument from "../
|
|
2
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Return the interior nodes of the tree.
|
|
@@ -10,9 +10,6 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
10
10
|
* @param {Treelike} [treelike]
|
|
11
11
|
*/
|
|
12
12
|
export default async function plain(treelike) {
|
|
13
|
-
const tree = await getTreeArgument(this, arguments, treelike, "
|
|
13
|
+
const tree = await getTreeArgument(this, arguments, treelike, "tree:plain");
|
|
14
14
|
return Tree.plain(tree);
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
plain.usage = `@plain <tree>\tA plain JavaScript object representation of the tree`;
|
|
18
|
-
plain.documentation = "https://weborigami.org/cli/builtins.html#plain";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { reverse } from "@weborigami/async-tree";
|
|
2
|
-
import getTreeArgument from "../
|
|
2
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Reverse the order of the top-level keys in the tree.
|
|
@@ -11,10 +11,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
11
11
|
* @param {Treelike} [treelike]
|
|
12
12
|
*/
|
|
13
13
|
export default async function reverseBuiltin(treelike) {
|
|
14
|
-
const tree = await getTreeArgument(this, arguments, treelike, "
|
|
14
|
+
const tree = await getTreeArgument(this, arguments, treelike, "tree:reverse");
|
|
15
15
|
const reversed = reverse(tree);
|
|
16
16
|
return reversed;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
reverseBuiltin.usage = `@reverse <tree>\tReverses the order of the tree's top-level keys`;
|
|
20
|
-
reverseBuiltin.documentation = "https://weborigami.org/builtins/@reverse.html";
|
|
@@ -47,6 +47,3 @@ async function applyUpdateForKey(source, target, key) {
|
|
|
47
47
|
// Copy the value from the source to the target.
|
|
48
48
|
await target.set(key, sourceValue);
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
setDeep.usage = `@setDeep <target>, <source>\tApplies the source tree to the target`;
|
|
52
|
-
setDeep.documentation = "https://weborigami.org/cli/builtins.html#setDeep";
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
default as ShuffleTransform,
|
|
3
|
-
shuffle,
|
|
4
|
-
} from "../common/ShuffleTransform.js";
|
|
1
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
5
2
|
import { transformObject } from "../common/utilities.js";
|
|
6
|
-
import
|
|
3
|
+
import { default as ShuffleTransform, shuffle } from "./ShuffleTransform.js";
|
|
7
4
|
|
|
8
5
|
/**
|
|
9
6
|
* Return a new tree with the original's keys shuffled
|
|
@@ -26,9 +23,6 @@ export default async function shuffleTree(treelike) {
|
|
|
26
23
|
shuffle(array);
|
|
27
24
|
return array;
|
|
28
25
|
}
|
|
29
|
-
const tree = await getTreeArgument(this, arguments, treelike, "
|
|
26
|
+
const tree = await getTreeArgument(this, arguments, treelike, "tree:shuffle");
|
|
30
27
|
return transformObject(ShuffleTransform, tree);
|
|
31
28
|
}
|
|
32
|
-
|
|
33
|
-
shuffleTree.usage = `@shuffle <tree>\tReturn a new tree with the original's keys shuffled`;
|
|
34
|
-
shuffleTree.documentation = "https://weborigami.org/cli/builtins.html#shuffle";
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sort as sortTransform } from "@weborigami/async-tree";
|
|
2
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
2
3
|
import { toFunction } from "../common/utilities.js";
|
|
3
|
-
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Return a
|
|
7
|
-
* function.
|
|
6
|
+
* Return a new tree with the original's keys sorted.
|
|
8
7
|
*
|
|
9
8
|
* If the `options` include a `sortKey` function, that will be invoked for each
|
|
10
9
|
* key in the tree to produce a sort key. If no `sortKey` function is provided,
|
|
@@ -14,16 +13,17 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
|
14
13
|
* sort keys.
|
|
15
14
|
*
|
|
16
15
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
16
|
+
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
17
17
|
* @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
|
|
18
18
|
* @typedef {{ compare?: (a: any, b: any) => number, sortKey?: ValueKeyFn }}
|
|
19
19
|
* SortOptions
|
|
20
20
|
*
|
|
21
21
|
* @this {AsyncTree|null}
|
|
22
|
-
* @param {
|
|
22
|
+
* @param {Treelike} [treelike]
|
|
23
|
+
* @param {SortOptions|ValueKeyFn} [options]
|
|
23
24
|
*/
|
|
24
|
-
export default function
|
|
25
|
-
|
|
26
|
-
const parent = this;
|
|
25
|
+
export default async function sortBuiltin(treelike, options) {
|
|
26
|
+
const tree = await getTreeArgument(this, arguments, treelike, "tree:sort");
|
|
27
27
|
|
|
28
28
|
if (typeof options === "function") {
|
|
29
29
|
// Take the function as the `sortKey` option
|
|
@@ -34,6 +34,7 @@ export default function sortFnBuiltin(options) {
|
|
|
34
34
|
let extendedSortKeyFn;
|
|
35
35
|
if (options?.sortKey) {
|
|
36
36
|
const originalSortKey = toFunction(options?.sortKey);
|
|
37
|
+
const parent = this;
|
|
37
38
|
extendedSortKeyFn = async (key, tree) => {
|
|
38
39
|
const value = await tree.get(key);
|
|
39
40
|
const sortKey = await originalSortKey.call(parent, value, key);
|
|
@@ -41,17 +42,11 @@ export default function sortFnBuiltin(options) {
|
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
const
|
|
45
|
+
const sorted = await sortTransform(tree, {
|
|
45
46
|
compare,
|
|
46
47
|
sortKey: extendedSortKeyFn,
|
|
47
48
|
});
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
sorted.parent = parent;
|
|
52
|
-
return sorted;
|
|
53
|
-
};
|
|
50
|
+
sorted.parent = this;
|
|
51
|
+
return sorted;
|
|
54
52
|
}
|
|
55
|
-
|
|
56
|
-
sortFnBuiltin.usage = `@sortFn [sortFn]\tReturn a function that sorts a tree`;
|
|
57
|
-
sortFnBuiltin.documentation = "https://weborigami.org/builtins/@sortFn.html";
|
package/src/tree/take.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { take as takeTransform } from "@weborigami/async-tree";
|
|
2
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Given a tree, take the first n items from it.
|
|
6
|
+
*
|
|
7
|
+
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
8
|
+
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
9
|
+
*
|
|
10
|
+
* @this {AsyncTree|null}
|
|
11
|
+
* @param {Treelike} treelike
|
|
12
|
+
* @param {number} count
|
|
13
|
+
*/
|
|
14
|
+
export default async function take(treelike, count) {
|
|
15
|
+
const tree = await getTreeArgument(this, arguments, treelike, "tree:take");
|
|
16
|
+
const taken = await takeTransform(tree, count);
|
|
17
|
+
taken.parent = this;
|
|
18
|
+
return taken;
|
|
19
|
+
}
|
package/src/tree/tree.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Tree } from "@weborigami/async-tree";
|
|
2
|
+
export { default as addNextPrevious } from "./addNextPrevious.js";
|
|
3
|
+
export { default as cache } from "./cache.js";
|
|
4
|
+
export { default as calendar } from "./calendar.js";
|
|
5
|
+
export { default as clear } from "./clear.js";
|
|
6
|
+
export { default as concat } from "./concat.js";
|
|
7
|
+
export { default as copy } from "./copy.js";
|
|
8
|
+
export { default as deepMap } from "./deepMap.js";
|
|
9
|
+
export { default as deepMerge } from "./deepMerge.js";
|
|
10
|
+
export { default as deepReverse } from "./deepReverse.js";
|
|
11
|
+
export { default as deepTake } from "./deepTake.js";
|
|
12
|
+
export { default as deepValues } from "./deepValues.js";
|
|
13
|
+
export { default as defineds } from "./defineds.js";
|
|
14
|
+
export { default as filter } from "./filter.js";
|
|
15
|
+
export { default as first } from "./first.js";
|
|
16
|
+
export { default as fromFn } from "./fromFn.js";
|
|
17
|
+
export { default as globs } from "./globs.js";
|
|
18
|
+
export { default as group } from "./group.js";
|
|
19
|
+
export { default as inners } from "./inners.js";
|
|
20
|
+
export { default as keys } from "./keys.js";
|
|
21
|
+
export { default as length } from "./length.js";
|
|
22
|
+
export { default as map } from "./map.js";
|
|
23
|
+
export { default as match } from "./match.js";
|
|
24
|
+
export { default as merge } from "./merge.js";
|
|
25
|
+
export { default as paginate } from "./paginate.js";
|
|
26
|
+
export { default as parent } from "./parent.js";
|
|
27
|
+
export { default as plain } from "./plain.js";
|
|
28
|
+
export { default as reverse } from "./reverse.js";
|
|
29
|
+
export { default as setDeep } from "./setDeep.js";
|
|
30
|
+
export { default as shuffle } from "./shuffle.js";
|
|
31
|
+
export { default as sort } from "./sort.js";
|
|
32
|
+
export { default as take } from "./take.js";
|
|
33
|
+
export { default as values } from "./values.js";
|
|
34
|
+
|
|
35
|
+
export const assign = Tree.assign;
|
|
36
|
+
export const entries = Tree.entries;
|
|
37
|
+
export const forEach = Tree.forEach;
|
|
38
|
+
export const from = Tree.from;
|
|
39
|
+
export const has = Tree.has;
|
|
40
|
+
export const isAsyncMutableTree = Tree.isAsyncMutableTree;
|
|
41
|
+
export const isAsyncTree = Tree.isAsyncTree;
|
|
42
|
+
export const isTraversable = Tree.isTraversable;
|
|
43
|
+
export const isTreelike = Tree.isTreelike;
|
|
44
|
+
export const mapReduce = Tree.mapReduce;
|
|
45
|
+
export const paths = Tree.paths;
|
|
46
|
+
export const remove = Tree.remove;
|
|
47
|
+
export const traverse = Tree.traverse;
|
|
48
|
+
export const traverseOrThrow = Tree.traverseOrThrow;
|
|
49
|
+
export const traversePath = Tree.traversePath;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tree } from "@weborigami/async-tree";
|
|
2
|
-
import getTreeArgument from "../
|
|
2
|
+
import getTreeArgument from "../common/getTreeArgument.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Return the interior nodes of the tree.
|
|
@@ -10,9 +10,6 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
10
10
|
* @param {Treelike} [treelike]
|
|
11
11
|
*/
|
|
12
12
|
export default async function values(treelike) {
|
|
13
|
-
const tree = await getTreeArgument(this, arguments, treelike, "
|
|
13
|
+
const tree = await getTreeArgument(this, arguments, treelike, "tree:values");
|
|
14
14
|
return Tree.values(tree);
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
values.usage = `@values <tree>\tThe top-level values in the tree`;
|
|
18
|
-
values.documentation = "https://weborigami.org/cli/builtins.html#values";
|
package/exports/PathTransform.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { trailingSlash } from "@weborigami/async-tree";
|
|
2
|
-
|
|
3
|
-
export default function PathTransform(Base) {
|
|
4
|
-
return class Path extends Base {
|
|
5
|
-
async get(key) {
|
|
6
|
-
let value = await super.get(key);
|
|
7
|
-
if (typeof value === "object" && value !== null) {
|
|
8
|
-
// @ts-ignore
|
|
9
|
-
const path = this[PathTransform.pathKey]
|
|
10
|
-
? // @ts-ignore
|
|
11
|
-
`${trailingSlash.add(this[PathTransform.pathKey])}${key}`
|
|
12
|
-
: key;
|
|
13
|
-
value[PathTransform.pathKey] = path;
|
|
14
|
-
}
|
|
15
|
-
return value;
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
PathTransform.pathKey = Symbol("path");
|