@weborigami/origami 0.0.49 → 0.0.51

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.
Files changed (61) hide show
  1. package/exports/buildExports.js +2 -2
  2. package/exports/exports.js +28 -15
  3. package/package.json +4 -4
  4. package/src/builtins/@addNextPrevious.js +18 -7
  5. package/src/builtins/{@arrows.js → @arrowsMap.js} +7 -7
  6. package/src/builtins/@changes.js +46 -0
  7. package/src/builtins/@clean.js +19 -0
  8. package/src/builtins/@constructor.js +17 -0
  9. package/src/builtins/@crawl.js +2 -2
  10. package/src/builtins/@deepMap.js +19 -0
  11. package/src/builtins/@deepMapFn.js +25 -0
  12. package/src/builtins/{@mergeDeep.js → @deepMerge.js} +7 -7
  13. package/src/builtins/@deepTake.js +21 -0
  14. package/src/builtins/@deepTakeFn.js +22 -0
  15. package/src/builtins/{@valuesDeep.js → @deepValues.js} +6 -5
  16. package/src/builtins/@files.js +14 -1
  17. package/src/builtins/@group.js +20 -0
  18. package/src/builtins/@groupFn.js +34 -0
  19. package/src/builtins/@if.js +2 -1
  20. package/src/builtins/@image/format.js +10 -31
  21. package/src/builtins/@image/formatFn.js +15 -0
  22. package/src/builtins/@image/resize.js +7 -28
  23. package/src/builtins/@image/resizeFn.js +14 -0
  24. package/src/builtins/@invoke.js +1 -1
  25. package/src/builtins/@json.js +5 -1
  26. package/src/builtins/@jsonParse.js +9 -0
  27. package/src/builtins/{@count.js → @length.js} +2 -5
  28. package/src/builtins/@map.js +7 -178
  29. package/src/builtins/@mapFn.js +145 -0
  30. package/src/builtins/@mdHtml.js +2 -0
  31. package/src/builtins/@mdTree.js +69 -0
  32. package/src/builtins/@merge.js +21 -1
  33. package/src/builtins/@naturalOrder.js +1 -0
  34. package/src/builtins/@paginate.js +18 -0
  35. package/src/builtins/@paginateFn.js +61 -0
  36. package/src/builtins/@redirect.js +10 -1
  37. package/src/builtins/@regexMatch.js +5 -0
  38. package/src/builtins/{@makeParser.js → @regexMatchFn.js} +1 -1
  39. package/src/builtins/@sitemap.js +4 -4
  40. package/src/builtins/@sort.js +10 -7
  41. package/src/builtins/@sortFn.js +58 -0
  42. package/src/builtins/@take.js +3 -17
  43. package/src/builtins/@takeFn.js +21 -0
  44. package/src/builtins/@tree.js +2 -14
  45. package/src/builtins/@yaml.js +4 -0
  46. package/src/builtins/@yamlParse.js +10 -0
  47. package/src/builtins/map.d.ts +1 -1
  48. package/src/common/ShuffleTransform.js +3 -3
  49. package/src/common/{arrowFunctionsMap.js → arrowsMapFn.js} +3 -3
  50. package/src/common/serialize.js +1 -10
  51. package/src/misc/explore.ori +7 -7
  52. package/src/misc/treeDot.js +2 -2
  53. package/src/builtins/@apply.js +0 -6
  54. package/src/builtins/@groupBy.js +0 -37
  55. package/src/builtins/@isAsyncTree.js +0 -17
  56. package/src/builtins/@mapDeep.js +0 -71
  57. package/src/builtins/@new.js +0 -6
  58. package/src/builtins/@parse/json.js +0 -9
  59. package/src/builtins/@parse/yaml.js +0 -10
  60. package/src/builtins/@sortBy.js +0 -37
  61. package/src/builtins/@with.js +0 -22
@@ -1,8 +1,17 @@
1
1
  export default function redirect(url, options = { permanent: false }) {
2
- return new Response("ok", {
2
+ const response = new Response("ok", {
3
3
  headers: {
4
4
  Location: url,
5
5
  },
6
6
  status: options.permanent ? 301 : 307,
7
7
  });
8
+ /** @type {any} */ (response).pack = () => `<!DOCTYPE html>
9
+ <html>
10
+ <head>
11
+ <meta charset="utf-8" />
12
+ <meta http-equiv="refresh" content="0;url=${url}" />
13
+ </head>
14
+ </html>
15
+ `;
16
+ return response;
8
17
  }
@@ -0,0 +1,5 @@
1
+ import regexMatchFn from "./@regexMatchFn.js";
2
+
3
+ export default function regexMatch(text, regex) {
4
+ return regexMatchFn(regex)(text);
5
+ }
@@ -1,6 +1,6 @@
1
1
  const parsers = {};
2
2
 
3
- export default function makeParser(text) {
3
+ export default function regexParseFn(text) {
4
4
  if (!parsers[text]) {
5
5
  const regexp = new RegExp(text);
6
6
  parsers[text] = (input) => input.match(regexp)?.groups;
@@ -3,13 +3,13 @@ import builtins from "./@builtins.js";
3
3
  import paths from "./@paths.js";
4
4
  import fileTypeOrigami from "./ori_handler.js";
5
5
 
6
- const templateText = `=\`<?xml version="1.0" encoding="UTF-8"?>
6
+ const templateText = `(urls) => \`<?xml version="1.0" encoding="UTF-8"?>
7
7
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
8
- \${ @map(=\`
8
+ \${ @map(urls, (url) => \`
9
9
  <url>
10
- <loc>\${ _ }</loc>
10
+ <loc>\${ url }</loc>
11
11
  </url>
12
- \`)(_) }
12
+ \`) }
13
13
  </urlset>
14
14
  \`
15
15
  `;
@@ -1,20 +1,23 @@
1
- import { sortNatural } from "@weborigami/async-tree";
2
1
  import getTreeArgument from "../misc/getTreeArgument.js";
2
+ import sortFn from "./@sortFn.js";
3
3
 
4
4
  /**
5
- * Return a new tree with the original's keys sorted in natural sort order.
5
+ * Return a new tree with the original's keys sorted.
6
6
  *
7
7
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
8
8
  * @typedef {import("@weborigami/async-tree").Treelike} Treelike
9
- * @typedef {import("../../index.ts").Invocable} Invocable
9
+ * @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
10
+ * @typedef {{ compare?: (a: any, b: any) => number, sortKey?: ValueKeyFn }}
11
+ * SortOptions
10
12
  *
11
13
  * @this {AsyncTree|null}
12
14
  * @param {Treelike} [treelike]
15
+ * @param {ValueKeyFn|SortOptions} [options]
13
16
  */
14
- export default async function sort(treelike) {
17
+ export default async function sortBuiltin(treelike, options) {
15
18
  const tree = await getTreeArgument(this, arguments, treelike, "@sort");
16
- return sortNatural()(tree);
19
+ return sortFn.call(this, options)(tree);
17
20
  }
18
21
 
19
- sort.usage = `@sort <tree>\tReturn a new tree with the original's keys sorted`;
20
- sort.documentation = "https://weborigami.org/cli/builtins.html#@sort";
22
+ sortBuiltin.usage = `@sort <tree>, [options]\tReturn a new tree with the original's keys sorted`;
23
+ sortBuiltin.documentation = "https://weborigami.org/builtins/@sort.html";
@@ -0,0 +1,58 @@
1
+ import { sortFn } 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 transform function that sorts a tree's keys using a comparison
8
+ * function.
9
+ *
10
+ * If the `options` include a `sortKey` function, that will be invoked for each
11
+ * key in the tree to produce a sort key. If no `sortKey` function is provided,
12
+ * the original keys will be used as sort keys.
13
+ *
14
+ * If the `options` include a `compare` function, that will be used to compare
15
+ * sort keys.
16
+ *
17
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
18
+ * @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
19
+ * @typedef {{ compare?: (a: any, b: any) => number, sortKey?: ValueKeyFn }}
20
+ * SortOptions
21
+ *
22
+ * @this {AsyncTree|null}
23
+ * @param {ValueKeyFn|SortOptions} [options]
24
+ */
25
+ export default function sortFnBuiltin(options) {
26
+ assertScopeIsDefined(this);
27
+ const scope = this;
28
+
29
+ if (typeof options === "function") {
30
+ // Take the function as the `sortKey` option
31
+ options = { sortKey: options };
32
+ }
33
+
34
+ const compare = options?.compare;
35
+ let extendedSortKeyFn;
36
+ if (options?.sortKey) {
37
+ const originalSortKey = toFunction(options?.sortKey);
38
+ extendedSortKeyFn = async (key, tree) => {
39
+ const value = await tree.get(key);
40
+ const sortKey = await originalSortKey.call(scope, value, key);
41
+ return sortKey;
42
+ };
43
+ }
44
+
45
+ const fn = sortFn({
46
+ compare,
47
+ sortKey: extendedSortKeyFn,
48
+ });
49
+
50
+ return (treelike) => {
51
+ const sorted = fn(treelike);
52
+ const scoped = Scope.treeWithScope(sorted, scope);
53
+ return scoped;
54
+ };
55
+ }
56
+
57
+ sortFnBuiltin.usage = `@sortFn [sortFn]\tReturn a function that sorts a tree`;
58
+ sortFnBuiltin.documentation = "https://weborigami.org/builtins/@sortFn.html";
@@ -1,33 +1,19 @@
1
- import { Scope } from "@weborigami/language";
2
1
  import getTreeArgument from "../misc/getTreeArgument.js";
2
+ import takeFn from "./@takeFn.js";
3
3
 
4
4
  /**
5
5
  * Given a tree, take the first n items from it.
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
  * @param {number} n
12
13
  */
13
14
  export default async function take(treelike, n) {
14
15
  const tree = await getTreeArgument(this, arguments, treelike, "@take");
15
-
16
- /** @type {AsyncTree} */
17
- let takeTree = {
18
- async keys() {
19
- const keys = Array.from(await tree.keys());
20
- return keys.slice(0, n);
21
- },
22
-
23
- async get(key) {
24
- return tree.get(key);
25
- },
26
- };
27
-
28
- takeTree = Scope.treeWithScope(takeTree, this);
29
-
30
- return takeTree;
16
+ return takeFn.call(this, n)(tree);
31
17
  }
32
18
 
33
19
  take.usage = `@take tree, n\tReturn the first n items from tree`;
@@ -0,0 +1,21 @@
1
+ import { takeFn } from "@weborigami/async-tree";
2
+ import { Scope } from "@weborigami/language";
3
+ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
4
+
5
+ /**
6
+ * Limit the number of keys to the indicated count.
7
+ *
8
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
+ *
10
+ * @this {AsyncTree|null}
11
+ * @param {number} count
12
+ */
13
+ export default function takeFnBuiltin(count) {
14
+ assertScopeIsDefined(this, "takeFn");
15
+ const scope = this;
16
+ return (treelike) => {
17
+ const taken = takeFn(count)(treelike);
18
+ const scoped = Scope.treeWithScope(taken, scope);
19
+ return scoped;
20
+ };
21
+ }
@@ -1,16 +1,4 @@
1
- import getTreeArgument from "../misc/getTreeArgument.js";
2
-
3
1
  /**
4
- * Cast the indicated treelike to a tree.
5
- *
6
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
7
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
8
- * @this {AsyncTree|null}
9
- * @param {Treelike} [treelike]
2
+ * Tree utilities functions
10
3
  */
11
- export default async function tree(treelike) {
12
- return getTreeArgument(this, arguments, treelike, "@tree");
13
- }
14
-
15
- tree.usage = `@tree <treelike>\tConvert JSON, YAML, function, or plain object to a tree`;
16
- tree.documentation = "https://weborigami.org/cli/builtins.html#tree";
4
+ export { Tree as default } from "@weborigami/async-tree";
@@ -1,4 +1,5 @@
1
1
  /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
+ import { isUnpackable } from "@weborigami/async-tree";
2
3
  import YAML from "yaml";
3
4
  import * as serialize from "../common/serialize.js";
4
5
  import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
@@ -21,6 +22,9 @@ export default async function toYaml(obj) {
21
22
  if (obj === undefined) {
22
23
  return undefined;
23
24
  }
25
+ if (isUnpackable(obj)) {
26
+ obj = await obj.unpack();
27
+ }
24
28
  const value = await serialize.toJsonValue(obj);
25
29
  return YAML.stringify(value);
26
30
  }
@@ -0,0 +1,10 @@
1
+ import * as serialize from "../common/serialize.js";
2
+ import { toString } from "../common/utilities.js";
3
+
4
+ export default async function yamlParse(input) {
5
+ const text = toString(input);
6
+ return text ? serialize.parseYaml(text) : undefined;
7
+ }
8
+
9
+ yamlParse.usage = `@yamlParse <text>\tParse text as YAML`;
10
+ yamlParse.documentation = "https://weborigami.org/builtins/@yamlParse.html";
@@ -4,7 +4,7 @@ import { AsyncTree } from "@weborigami/types";
4
4
  type TreeMapOptions = {
5
5
  deep?: boolean;
6
6
  description?: string;
7
- extensions?: string;
7
+ extension?: string;
8
8
  inverseKey?: KeyFn;
9
9
  key?: ValueKeyFn;
10
10
  needsSourceValue?: boolean;
@@ -19,10 +19,10 @@ export default function ShuffleTransform(Base) {
19
19
  * Performs a Fisher-Yates shuffle. From http://sedition.com/perl/javascript-fy.html
20
20
  */
21
21
  function shuffle(array) {
22
- var i = array.length;
22
+ let i = array.length;
23
23
  while (--i >= 0) {
24
- var j = Math.floor(Math.random() * (i + 1));
25
- var temp = array[i];
24
+ const j = Math.floor(Math.random() * (i + 1));
25
+ const temp = array[i];
26
26
  array[i] = array[j];
27
27
  array[j] = temp;
28
28
  }
@@ -1,9 +1,9 @@
1
- import { cachedKeyFunctions, map } from "@weborigami/async-tree";
1
+ import { cachedKeyFunctions, mapFn } from "@weborigami/async-tree";
2
2
  import { toFunction } from "./utilities.js";
3
3
 
4
- export default function arrowFunctionsMap() {
4
+ export default function arrowsMapFn() {
5
5
  const deep = true;
6
- return map({
6
+ return mapFn({
7
7
  deep,
8
8
  description: "arrowFunctions",
9
9
  value: valueFn,
@@ -5,12 +5,7 @@
5
5
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
6
6
  */
7
7
 
8
- import {
9
- Tree,
10
- isPlainObject,
11
- isStringLike,
12
- isUnpackable,
13
- } from "@weborigami/async-tree";
8
+ import { Tree, isPlainObject, isStringLike } from "@weborigami/async-tree";
14
9
  import { OrigamiTree } from "@weborigami/language";
15
10
  import * as YAMLModule from "yaml";
16
11
  import yamlOrigamiTag from "../misc/yamlOrigamiTag.js";
@@ -145,10 +140,6 @@ export async function toValue(input, jsonValuesOnly = false) {
145
140
  } else {
146
141
  return input;
147
142
  }
148
- } else if (isUnpackable(input)) {
149
- // Unpack first, then convert to JSON value.
150
- const unpacked = await input.unpack();
151
- return toValue(unpacked);
152
143
  } else if (isStringLike(input) && !(input instanceof Array)) {
153
144
  return String(input);
154
145
  } else if (Tree.isTreelike(input)) {
@@ -1,4 +1,4 @@
1
- =`<!DOCTYPE html>
1
+ (scope) => `<!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
@@ -16,16 +16,16 @@
16
16
  <button id="buttonSVG">SVG</button>
17
17
  <button id="buttonYAML">YAML</button>
18
18
  </div>
19
- {{ @map(=`
19
+ ${ @map(scope, (scopeTree) => `
20
20
  <ul>
21
- <h2>${ _/name }</h2>
22
- {{ @map(=`
21
+ <h2>${ scopeTree/name }</h2>
22
+ ${ @map(scopeTree/keys, (key) => `
23
23
  <li>
24
- <a href="./!@explore/${ _ }" target="frame">${ _ }</a>
24
+ <a href="./!@explore/${ key }" target="frame">${ key }</a>
25
25
  </li>
26
- `)(_/keys) }}
26
+ `) }
27
27
  </ul>
28
- `)(_) }}
28
+ `) }
29
29
  </nav>
30
30
  <iframe id="frame" name="frame"></iframe>
31
31
  </body>
@@ -78,10 +78,10 @@ async function statements(tree, nodePath, nodeLabel, options) {
78
78
  } else {
79
79
  const label = isStringLike(value)
80
80
  ? String(value)
81
- : value != null
81
+ : value !== undefined
82
82
  ? await serialize.toYaml(value)
83
83
  : "";
84
- if (value == null) {
84
+ if (value === undefined) {
85
85
  isError = true;
86
86
  }
87
87
  nodes[key] = { label };
@@ -1,6 +0,0 @@
1
- /**
2
- * @this {import("@weborigami/types").AsyncTree|null}
3
- */
4
- export default async function apply(target, fn) {
5
- return fn.call(this, target);
6
- }
@@ -1,37 +0,0 @@
1
- import { groupBy } from "@weborigami/async-tree";
2
- import { Scope } from "@weborigami/language";
3
- import addValueKeyToScope from "../common/addValueKeyToScope.js";
4
- import { toFunction } from "../common/utilities.js";
5
- import getTreeArgument from "../misc/getTreeArgument.js";
6
-
7
- /**
8
- * Return a new tree with the values from the original tree in groups.
9
- * The groups are determined by the given function.
10
- *
11
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
12
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
13
- * @typedef {import("../../index.ts").Invocable} Invocable
14
- *
15
- * @this {AsyncTree|null}
16
- * @param {Treelike} treelike
17
- * @param {Invocable} groupKeyFn
18
- */
19
- export default async function groupByBuiltin(treelike, groupKeyFn) {
20
- const tree = await getTreeArgument(this, arguments, treelike, "@groupBy");
21
-
22
- const fn = toFunction(groupKeyFn);
23
- const baseScope = Scope.getScope(this);
24
- async function extendedGroupKeyFn(value, key, tree) {
25
- const scope = addValueKeyToScope(baseScope, value, key);
26
- const sortKey = await fn.call(scope, value, key);
27
- return sortKey;
28
- }
29
-
30
- const grouped = await groupBy(extendedGroupKeyFn)(tree);
31
- const scoped = Scope.treeWithScope(grouped, this);
32
- return scoped;
33
- }
34
-
35
- groupByBuiltin.usage = `@groupBy <tree>, [groupKeyFn]\tReturn a new tree with the original's values grouped`;
36
- groupByBuiltin.documentation =
37
- "https://weborigami.org/cli/builtins.html#@group";
@@ -1,17 +0,0 @@
1
- /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
-
3
- import { Tree } from "@weborigami/async-tree";
4
-
5
- /**
6
- * Return true if the value is an async tree.
7
- *
8
- * @this {AsyncTree|null}
9
- * @param {any} value
10
- */
11
- export default function isAsyncTree(value) {
12
- return Tree.isAsyncTree(value);
13
- }
14
-
15
- isAsyncTree.usage = `@isAsyncTree <value>\tReturn true for an async tree`;
16
- isAsyncTree.documentation =
17
- "https://weborigami.org/cli/builtins.html#isAsyncTree";
@@ -1,71 +0,0 @@
1
- import { isPlainObject } from "@weborigami/async-tree";
2
- import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
3
- import treeMap from "./@map.js";
4
-
5
- /**
6
- * Map a hierarchical tree of keys and values to a new tree of keys and values.
7
- *
8
- * @typedef {import("@weborigami/async-tree").KeyFn} KeyFn
9
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
10
- * @typedef {import("@weborigami/async-tree").ValueKeyFn} ValueKeyFn
11
- * @typedef {import("@weborigami/async-tree").TreeTransform} TreeTransform
12
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
13
- *
14
- * @typedef {{ deep?: boolean, description?: string, extension?: string,
15
- * extensions?: string, inverseKey?: KeyFn, key?: ValueKeyFn, keyMap?:
16
- * ValueKeyFn, needsSourceValue?: boolean, value?: ValueKeyFn, valueMap?:
17
- * ValueKeyFn }} MapOptionsDictionary
18
- *
19
- * @typedef {ValueKeyFn|MapOptionsDictionary} OptionsOrValueFn
20
- *
21
- * @overload
22
- * @param {Treelike} source
23
- * @param {OptionsOrValueFn} instructions
24
- * @returns {AsyncTree}
25
- *
26
- * @overload
27
- * @param {OptionsOrValueFn} instructions
28
- * @returns {TreeTransform}
29
- *
30
- * @this {AsyncTree|null}
31
- * @param {Treelike|OptionsOrValueFn} param1
32
- * @param {OptionsOrValueFn} [param2]
33
- */
34
- export default function mapDeep(param1, param2) {
35
- assertScopeIsDefined(this, "mapDeep");
36
-
37
- // Identify whether the map instructions are the first parameter or the
38
- // second.
39
- if (arguments.length === 1) {
40
- // One argument, which is a dictionary or function.
41
- /** @type {MapOptionsDictionary} */
42
- const options = isPlainObject(param1)
43
- ? // Dictionary
44
- { ...param1, deep: true }
45
- : // Function
46
- { deep: true, value: param1 };
47
- const transform = treeMap.call(this, options);
48
- return transform;
49
- } else {
50
- // Two arguments, second is a dictionary or function.
51
- /** @type {Treelike} */
52
- const source = param1;
53
- /** @type {MapOptionsDictionary} */
54
- const options = isPlainObject(param2)
55
- ? // Dictionary
56
- { ...param2, deep: true }
57
- : // Function
58
- { deep: true, value: param2 };
59
-
60
- // We go through some type gymnastics to convince TypeScript that the return
61
- // value is an AsyncTree. Using `.call()` with the overloaded `@map`
62
- // function seems to confuse TypeScript into thinking the call will return a
63
- // TreeTransform.
64
-
65
- /** @type {AsyncTree} */
66
- let tree;
67
- // @ts-ignore
68
- tree = treeMap.call(this, source, options);
69
- return tree;
70
- }
71
- }
@@ -1,6 +0,0 @@
1
- export default function newBuiltin(constructor, ...args) {
2
- return Reflect.construct(constructor, args);
3
- }
4
-
5
- newBuiltin.usage = "@new <classFn>\tCreate a new instance of the given class";
6
- newBuiltin.documentation = "https://weborigami.org/language/@new.html";
@@ -1,9 +0,0 @@
1
- import { toString } from "../../common/utilities.js";
2
-
3
- export default async function parseJson(input) {
4
- const text = toString(input);
5
- return text ? JSON.parse(text) : undefined;
6
- }
7
-
8
- parseJson.usage = `parseJson <text>\tParse text as JSON`;
9
- parseJson.documentation = "https://weborigami.org/cli/builtins.html#parseJson";
@@ -1,10 +0,0 @@
1
- import * as serialize from "../../common/serialize.js";
2
- import { toString } from "../../common/utilities.js";
3
-
4
- export default async function parseYaml(input) {
5
- const text = toString(input);
6
- return text ? serialize.parseYaml(text) : undefined;
7
- }
8
-
9
- parseYaml.usage = `parseYaml <text>\tParse text as YAML (including JSON)`;
10
- parseYaml.documentation = "https://weborigami.org/cli/builtins.html#parseYaml";
@@ -1,37 +0,0 @@
1
- import { sortBy } from "@weborigami/async-tree";
2
- import { Scope } from "@weborigami/language";
3
- import addValueKeyToScope from "../common/addValueKeyToScope.js";
4
- import { toFunction } from "../common/utilities.js";
5
- import getTreeArgument from "../misc/getTreeArgument.js";
6
-
7
- /**
8
- * Return a new tree with the original's keys sorted using the given function to
9
- * obtain a sort key for each value in the tree.
10
- *
11
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
12
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
13
- * @typedef {import("../../index.ts").Invocable} Invocable
14
- *
15
- * @this {AsyncTree|null}
16
- * @param {Treelike} treelike
17
- * @param {Invocable} sortKeyFn
18
- */
19
- export default async function sortByBuiltin(treelike, sortKeyFn) {
20
- const tree = await getTreeArgument(this, arguments, treelike, "@sortBy");
21
-
22
- const fn = toFunction(sortKeyFn);
23
- const baseScope = Scope.getScope(this);
24
- async function extendedSortKeyFn(key, tree) {
25
- const value = await tree.get(key);
26
- const scope = addValueKeyToScope(baseScope, value, key);
27
- const sortKey = await fn.call(scope, value, key);
28
- return sortKey;
29
- }
30
-
31
- const sorted = sortBy(extendedSortKeyFn)(tree);
32
- const scoped = Scope.treeWithScope(sorted, this);
33
- return scoped;
34
- }
35
-
36
- sortByBuiltin.usage = `@sortBy <tree>, [sortKeyFn]\tReturn a new tree with the original's keys sorted`;
37
- sortByBuiltin.documentation = "https://weborigami.org/cli/builtins.html#@sort";
@@ -1,22 +0,0 @@
1
- import { Tree } 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
- *
8
- * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
- * @typedef {import("@weborigami/async-tree").Treelike} Treelike
10
- * @typedef {import("../../index.ts").Invocable} Invocable
11
- *
12
- * @this {AsyncTree|null}
13
- * @param {Treelike} treelike
14
- * @param {Invocable} invocable
15
- */
16
- export default function withTree(treelike, invocable) {
17
- assertScopeIsDefined(this, "with");
18
- const tree = Tree.from(treelike);
19
- const fn = toFunction(invocable);
20
- const scope = new Scope(tree, this);
21
- return fn.call(scope);
22
- }