@weborigami/origami 0.0.73 → 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.
Files changed (194) hide show
  1. package/main.js +12 -0
  2. package/package.json +5 -7
  3. package/src/builtins.js +62 -0
  4. package/src/builtinsTree.js +36 -0
  5. package/src/calc/calc.js +61 -0
  6. package/src/cli/cli.js +6 -4
  7. package/src/{misc → common}/assertTreeIsDefined.js +4 -1
  8. package/src/common/constructHref.js +20 -0
  9. package/src/common/constructSiteTree.js +34 -0
  10. package/src/common/fetchAndHandleExtension.js +26 -0
  11. package/src/{misc → common}/getTreeArgument.js +11 -5
  12. package/src/common/processUnpackedContent.js +4 -13
  13. package/src/common/utilities.d.ts +0 -1
  14. package/src/common/utilities.js +3 -30
  15. package/src/deprecated.js +140 -0
  16. package/src/{common → dev}/ExplorableSiteTransform.js +1 -1
  17. package/src/{misc → dev}/OriCommandTransform.js +2 -2
  18. package/src/{builtins/@code.js → dev/code.js} +2 -2
  19. package/src/{builtins/@debug.js → dev/debug.js} +4 -7
  20. package/src/dev/dev.js +9 -0
  21. package/src/{builtins/@explore.js → dev/explore.js} +22 -28
  22. package/src/{misc → dev}/explore.js.inline +4 -4
  23. package/src/{misc → dev}/explore.ori +3 -3
  24. package/src/{builtins/@log.js → dev/log.js} +1 -1
  25. package/src/{builtins/@serve.js → dev/serve.js} +5 -8
  26. package/src/{builtins/@svg.js → dev/svg.js} +9 -6
  27. package/src/{misc → dev}/treeDot.js +0 -3
  28. package/src/{builtins/@watch.js → dev/watch.js} +8 -6
  29. package/src/handlers/handlerExports.js +16 -0
  30. package/src/handlers/handlers.js +37 -0
  31. package/src/{builtins → handlers}/js.handler.js +1 -1
  32. package/src/{builtins → handlers}/json.handler.js +9 -1
  33. package/src/handlers/mjs.handler.js +2 -0
  34. package/src/{builtins → handlers}/ori.handler.js +5 -7
  35. package/src/{builtins → handlers}/oridocument.handler.js +1 -1
  36. package/src/{builtins → handlers}/wasm.handler.js +1 -1
  37. package/src/{builtins → handlers}/yaml.handler.js +8 -1
  38. package/src/handlers/yml.handler.js +2 -0
  39. package/src/help/help.js +103 -0
  40. package/src/help/help.yaml +425 -0
  41. package/src/{builtins/@image → image}/format.js +2 -2
  42. package/src/{builtins/@image → image}/formatFn.js +1 -1
  43. package/src/image/image.js +2 -0
  44. package/src/{builtins/@image → image}/resize.js +2 -2
  45. package/src/{builtins/@image → image}/resizeFn.js +1 -1
  46. package/src/internal.js +24 -0
  47. package/src/{builtins/@js.js → js.js} +7 -6
  48. package/src/{builtins/@node.js → node.js} +1 -6
  49. package/src/{builtins/@basename.js → origami/basename.js} +2 -2
  50. package/src/{builtins/@config.js → origami/config.js} +1 -4
  51. package/src/{builtins/@json.js → origami/json.js} +2 -5
  52. package/src/{builtins/@jsonParse.js → origami/jsonParse.js} +0 -3
  53. package/src/{builtins/@once.js → origami/once.js} +2 -2
  54. package/src/{builtins/@ori.js → origami/ori.js} +4 -7
  55. package/src/origami/origami.js +29 -0
  56. package/src/{builtins/@pack.js → origami/pack.js} +2 -2
  57. package/src/{builtins/@project.js → origami/project.js} +7 -11
  58. package/src/{builtins/@regexMatch.js → origami/regexMatch.js} +1 -1
  59. package/src/origami/repeat.js +5 -0
  60. package/src/{builtins/@shell.js → origami/shell.js} +0 -3
  61. package/src/{builtins/@stdin.js → origami/stdin.js} +0 -3
  62. package/src/{builtins/@string.js → origami/string.js} +2 -2
  63. package/src/{builtins/@unpack.js → origami/unpack.js} +2 -2
  64. package/src/{builtins/@yaml.js → origami/yaml.js} +2 -5
  65. package/src/{builtins/@yamlParse.js → origami/yamlParse.js} +0 -3
  66. package/src/protocols/explore.js +19 -0
  67. package/src/{builtins/@files.js → protocols/files.js} +2 -5
  68. package/src/protocols/http.js +18 -0
  69. package/src/protocols/https.js +18 -0
  70. package/src/protocols/httpstree.js +19 -0
  71. package/src/protocols/httptree.js +19 -0
  72. package/src/protocols/inherited.js +18 -0
  73. package/src/protocols/new.js +42 -0
  74. package/src/{builtins/@package.js → protocols/package.js} +2 -2
  75. package/src/protocols/scope.js +14 -0
  76. package/src/server/constructResponse.js +5 -5
  77. package/src/{builtins/@siteAudit.js → site/audit.js} +4 -4
  78. package/src/{builtins/@crawl.js → site/crawler/crawl.js} +3 -6
  79. package/src/{crawler → site/crawler}/findPaths.js +2 -3
  80. package/src/{crawler → site/crawler}/utilities.js +2 -3
  81. package/src/{builtins/@index.js → site/index.js} +2 -5
  82. package/src/{builtins/@jsonKeys.js → site/jsonKeys.js} +5 -5
  83. package/src/{builtins/@rss.js → site/rss.js} +2 -5
  84. package/src/site/site.js +9 -0
  85. package/src/{builtins/@sitemap.js → site/sitemap.js} +8 -12
  86. package/src/{builtins/@static.js → site/static.js} +7 -7
  87. package/src/{builtins/@document.js → text/document.js} +2 -2
  88. package/src/{builtins/@inline.js → text/inline.js} +10 -13
  89. package/src/{builtins/@mdHtml.js → text/mdHtml.js} +7 -10
  90. package/src/text/origamiHighlightDefinition.js +53 -0
  91. package/src/text/text.js +4 -0
  92. package/src/{builtins/@addNextPrevious.js → tree/addNextPrevious.js} +7 -2
  93. package/src/{builtins/@cache.js → tree/cache.js} +2 -5
  94. package/src/{builtins/@clean.js → tree/clear.js} +4 -4
  95. package/src/{builtins/@concat.js → tree/concat.js} +2 -5
  96. package/src/{builtins/@copy.js → tree/copy.js} +3 -10
  97. package/src/{builtins/@deepMapFn.js → tree/deepMap.js} +13 -6
  98. package/src/{builtins/@deepMerge.js → tree/deepMerge.js} +4 -7
  99. package/src/{builtins/@deepReverse.js → tree/deepReverse.js} +8 -2
  100. package/src/tree/deepTake.js +26 -0
  101. package/src/{builtins/@deepValues.js → tree/deepValues.js} +2 -6
  102. package/src/{builtins/@defineds.js → tree/defineds.js} +7 -2
  103. package/src/{builtins/@filter.js → tree/filter.js} +3 -6
  104. package/src/{builtins/@first.js → tree/first.js} +2 -5
  105. package/src/{builtins/@fnTree.js → tree/fromFn.js} +3 -6
  106. package/src/{builtins/@globs.js → tree/globs.js} +3 -6
  107. package/src/tree/group.js +26 -0
  108. package/src/{builtins/@inners.js → tree/inners.js} +2 -5
  109. package/src/{builtins/@keys.js → tree/keys.js} +2 -5
  110. package/src/{builtins/@length.js → tree/length.js} +2 -2
  111. package/src/{builtins → tree}/map.d.ts +3 -6
  112. package/src/tree/map.js +154 -0
  113. package/src/{builtins/@mapFn.js → tree/mapFn.js} +14 -6
  114. package/src/{builtins/@match.js → tree/match.js} +2 -5
  115. package/src/{builtins/@merge.js → tree/merge.js} +2 -5
  116. package/src/tree/paginate.js +61 -0
  117. package/src/{builtins/@parent.js → tree/parent.js} +2 -5
  118. package/src/{builtins/@plain.js → tree/plain.js} +2 -5
  119. package/src/{builtins/@reverse.js → tree/reverse.js} +2 -5
  120. package/src/{builtins/@setDeep.js → tree/setDeep.js} +0 -3
  121. package/src/{builtins/@shuffle.js → tree/shuffle.js} +3 -9
  122. package/src/{builtins/@sortFn.js → tree/sort.js} +12 -17
  123. package/src/tree/take.js +19 -0
  124. package/src/tree/tree.js +49 -0
  125. package/src/{builtins/@values.js → tree/values.js} +2 -5
  126. package/exports/PathTransform.d.ts +0 -5
  127. package/exports/PathTransform.js +0 -20
  128. package/exports/buildExports.js +0 -112
  129. package/exports/exports.js +0 -148
  130. package/src/builtins/@builtins.js +0 -15
  131. package/src/builtins/@deepMap.js +0 -19
  132. package/src/builtins/@deepTake.js +0 -21
  133. package/src/builtins/@deepTakeFn.js +0 -21
  134. package/src/builtins/@equals.js +0 -6
  135. package/src/builtins/@exploreSite.js +0 -16
  136. package/src/builtins/@false.js +0 -1
  137. package/src/builtins/@fetch.js +0 -7
  138. package/src/builtins/@group.js +0 -20
  139. package/src/builtins/@groupFn.js +0 -33
  140. package/src/builtins/@help.js +0 -49
  141. package/src/builtins/@http.js +0 -19
  142. package/src/builtins/@https.js +0 -19
  143. package/src/builtins/@if.js +0 -28
  144. package/src/builtins/@inherited.js +0 -17
  145. package/src/builtins/@map.js +0 -19
  146. package/src/builtins/@math.js +0 -17
  147. package/src/builtins/@not.js +0 -6
  148. package/src/builtins/@or.js +0 -6
  149. package/src/builtins/@paginate.js +0 -18
  150. package/src/builtins/@paginateFn.js +0 -58
  151. package/src/builtins/@repeat.js +0 -8
  152. package/src/builtins/@sort.js +0 -23
  153. package/src/builtins/@table.js +0 -69
  154. package/src/builtins/@take.js +0 -20
  155. package/src/builtins/@takeFn.js +0 -20
  156. package/src/builtins/@tree.js +0 -4
  157. package/src/builtins/@treeHttp.js +0 -19
  158. package/src/builtins/@treeHttps.js +0 -19
  159. package/src/builtins/@true.js +0 -1
  160. package/src/builtins/mjs.handler.js +0 -2
  161. package/src/builtins/yml.handler.js +0 -2
  162. package/src/builtins/~.js +0 -9
  163. package/src/cli/showUsage.js +0 -86
  164. package/src/common/CommandModulesTransform.d.ts +0 -5
  165. package/src/common/CommandModulesTransform.js +0 -39
  166. package/src/common/arrowsMapFn.js +0 -35
  167. package/src/misc/origamiHighlightDefinition.js +0 -36
  168. /package/src/{misc → common}/assertTreeIsDefined.d.ts +0 -0
  169. /package/src/{common → dev}/ExplorableSiteTransform.d.ts +0 -0
  170. /package/src/{misc → dev}/OriCommandTransform.d.ts +0 -0
  171. /package/src/{builtins/@breakpoint.js → dev/breakpoint.js} +0 -0
  172. /package/src/{builtins/@changes.js → dev/changes.js} +0 -0
  173. /package/src/{misc → dev}/explore.css +0 -0
  174. /package/src/{builtins → handlers}/css.handler.js +0 -0
  175. /package/src/{builtins → handlers}/htm.handler.js +0 -0
  176. /package/src/{builtins → handlers}/html.handler.js +0 -0
  177. /package/src/{builtins → handlers}/jpeg.handler.js +0 -0
  178. /package/src/{builtins → handlers}/jpg.handler.js +0 -0
  179. /package/src/{builtins → handlers}/md.handler.js +0 -0
  180. /package/src/{builtins → handlers}/txt.handler.js +0 -0
  181. /package/src/{builtins → handlers}/xhtml.handler.js +0 -0
  182. /package/src/{builtins/@naturalOrder.js → origami/naturalOrder.js} +0 -0
  183. /package/src/{builtins/@post.js → origami/post.js} +0 -0
  184. /package/src/{builtins/@regexMatchFn.js → origami/regexMatchFn.js} +0 -0
  185. /package/src/{builtins/@slash.js → origami/slash.js} +0 -0
  186. /package/src/{builtins/@version.js → origami/version.js} +0 -0
  187. /package/src/{crawler → site/crawler}/crawlResources.js +0 -0
  188. /package/src/{builtins/@redirect.js → site/redirect.js} +0 -0
  189. /package/src/{builtins/@slug.js → site/slug.js} +0 -0
  190. /package/src/{builtins/@indent.js → text/indent.js} +0 -0
  191. /package/src/{common → tree}/FilterTree.js +0 -0
  192. /package/src/{common → tree}/GlobTree.js +0 -0
  193. /package/src/{common → tree}/ShuffleTransform.js +0 -0
  194. /package/src/{builtins/@calendarTree.js → tree/calendar.js} +0 -0
@@ -1,5 +1,5 @@
1
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
1
2
  import documentObject from "../common/documentObject.js";
2
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
3
3
 
4
4
  /**
5
5
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
@@ -10,6 +10,6 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
10
10
  * @param {any} [data]
11
11
  */
12
12
  export default async function documentBuiltin(text, data) {
13
- assertTreeIsDefined(this, "document");
13
+ assertTreeIsDefined(this, "text:document");
14
14
  return documentObject(text, data);
15
15
  }
@@ -1,9 +1,9 @@
1
1
  import { isUnpackable, symbols } from "@weborigami/async-tree";
2
2
  import { compile } from "@weborigami/language";
3
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
4
  import documentObject from "../common/documentObject.js";
4
5
  import { toString } from "../common/utilities.js";
5
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
6
- import fileTypeOrigami from "./ori.handler.js";
6
+ import { oriHandler } from "../internal.js";
7
7
 
8
8
  /**
9
9
  * Inline any Origami expressions found inside ${...} placeholders in the input
@@ -16,7 +16,7 @@ import fileTypeOrigami from "./ori.handler.js";
16
16
  * @param {StringLike} input
17
17
  */
18
18
  export default async function inline(input) {
19
- assertTreeIsDefined(this, "inline");
19
+ assertTreeIsDefined(this, "text:inline");
20
20
 
21
21
  // Get the input text and any attached front matter.
22
22
  if (isUnpackable(input)) {
@@ -24,24 +24,21 @@ export default async function inline(input) {
24
24
  }
25
25
  const inputIsDocument = input["@text"] !== undefined;
26
26
  const origami = inputIsDocument ? input["@text"] : toString(input);
27
+ if (origami === null) {
28
+ return undefined;
29
+ }
27
30
 
28
31
  const parent =
29
32
  /** @type {any} */ (input).parent ?? input[symbols.parent] ?? this;
30
-
31
- // If the input document is a plain object, include it in scope for the
32
- // evaluated expression.
33
- const inputData = inputIsDocument ? input : null;
34
-
35
- const templateFn = await fileTypeOrigami.unpack(origami, {
36
- attachedData: inputData,
33
+ const templateFn = await oriHandler.unpack(origami, {
37
34
  compiler: compile.templateDocument,
38
35
  parent,
39
36
  });
37
+
38
+ const inputData = inputIsDocument ? input : null;
40
39
  const templateResult = await templateFn(inputData);
40
+
41
41
  return inputIsDocument
42
42
  ? documentObject(templateResult, inputData)
43
43
  : templateResult;
44
44
  }
45
-
46
- inline.usage = `@inline <text>\tInline Origami expressions found in the text`;
47
- inline.documentation = "https://weborigami.org/language/@inline.html";
@@ -1,12 +1,12 @@
1
- import { isUnpackable } from "@weborigami/async-tree";
1
+ import { extension, isUnpackable } from "@weborigami/async-tree";
2
2
  import highlight from "highlight.js";
3
3
  import { marked } from "marked";
4
4
  import { gfmHeadingId as markedGfmHeadingId } from "marked-gfm-heading-id";
5
5
  import { markedHighlight } from "marked-highlight";
6
6
  import { markedSmartypants } from "marked-smartypants";
7
7
  import documentObject from "../common/documentObject.js";
8
- import { replaceExtension, toString } from "../common/utilities.js";
9
- import origamiHighlightDefinition from "../misc/origamiHighlightDefinition.js";
8
+ import { toString } from "../common/utilities.js";
9
+ import origamiHighlightDefinition from "./origamiHighlightDefinition.js";
10
10
 
11
11
  highlight.registerLanguage("ori", origamiHighlightDefinition);
12
12
 
@@ -39,7 +39,7 @@ marked.use(
39
39
  */
40
40
  export default async function mdHtml(input) {
41
41
  if (input == null) {
42
- const error = new TypeError("@mdHtml: The input is not defined.");
42
+ const error = new TypeError("mdHtml: The input is not defined.");
43
43
  /** @type {any} */ (error).position = 0;
44
44
  throw error;
45
45
  }
@@ -49,14 +49,11 @@ export default async function mdHtml(input) {
49
49
  const inputIsDocument = input["@text"] !== undefined;
50
50
  const markdown = toString(input);
51
51
  if (markdown === null) {
52
- throw new Error("@mdHtml: The provided input couldn't be treated as text.");
52
+ throw new Error("mdHtml: The provided input couldn't be treated as text.");
53
53
  }
54
54
  const html = marked(markdown);
55
55
  return inputIsDocument ? documentObject(html, input) : html;
56
56
  }
57
57
 
58
- mdHtml.key = (sourceKey) => replaceExtension(sourceKey, ".md", ".html");
59
- mdHtml.inverseKey = (resultKey) => replaceExtension(resultKey, ".html", ".md");
60
-
61
- mdHtml.usage = `@mdHtml <markdown>\tRender the markdown text as HTML`;
62
- mdHtml.documentation = "https://weborigami.org/language/@mdHtml.html";
58
+ mdHtml.key = (sourceKey) => extension.replace(sourceKey, ".md", ".html");
59
+ mdHtml.inverseKey = (resultKey) => extension.replace(resultKey, ".html", ".md");
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Origami language definition for highlight.js
3
+ */
4
+ export default function origamiHighlightDefinition(hljs) {
5
+ return {
6
+ name: "Origami",
7
+ contains: [
8
+ hljs.C_LINE_COMMENT_MODE,
9
+ hljs.C_BLOCK_COMMENT_MODE,
10
+ hljs.C_NUMBER_MODE,
11
+ hljs.APOS_STRING_MODE,
12
+ hljs.QUOTE_STRING_MODE,
13
+ hljs.BACKSLASH_ESCAPE,
14
+ {
15
+ // Backtick template strings
16
+ className: "string",
17
+ begin: "`",
18
+ end: "`",
19
+ contains: [
20
+ hljs.BACKSLASH_ESCAPE,
21
+ {
22
+ className: "subst",
23
+ begin: "\\$\\{",
24
+ end: "\\}",
25
+ contains: [hljs.C_NUMBER_MODE, hljs.QUOTE_STRING_MODE],
26
+ },
27
+ ],
28
+ },
29
+ {
30
+ // Treat namespaces as keywords
31
+ className: "keyword",
32
+ begin:
33
+ /\b(calc|dev|explore|files|http|https|httpstree|httptree|image|inherited|js|new|node|origami|package|scope|site|text|tree):\b/,
34
+ },
35
+ {
36
+ // Treat identifier containing a period before an open paren or backtick as a variable
37
+ className: "variable",
38
+ begin:
39
+ /\b[^(){}\[\]<>\-=,/:\`"'«»\\ →⇒\t\n\r]+\.[^(){}\[\]<>\-=,/:\`"'«»\\ →⇒\t\n\r]+(?=(\(|\`))\b/,
40
+ },
41
+ {
42
+ className: "built_in",
43
+ // Treat shorthands before open paren or backtick as a builtin
44
+ begin: /\b[A-Za-z][A-Za-z0-9]*(?=(\(|\`))\b/,
45
+ },
46
+ {
47
+ // Treat remaining identifiers as variables
48
+ className: "variable",
49
+ begin: /\b[^(){}\[\]<>\-=,/:\`"'«»\\ →⇒\t\n\r]+\b/,
50
+ },
51
+ ],
52
+ };
53
+ }
@@ -0,0 +1,4 @@
1
+ export { default as document } from "./document.js";
2
+ export { default as indent } from "./indent.js";
3
+ export { default as inline } from "./inline.js";
4
+ export { default as mdHtml } from "./mdHtml.js";
@@ -1,5 +1,5 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
- import getTreeArgument from "../misc/getTreeArgument.js";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
3
 
4
4
  /**
5
5
  * Add nextKey/previousKey properties to values.
@@ -10,7 +10,12 @@ import getTreeArgument from "../misc/getTreeArgument.js";
10
10
  * @param {import("@weborigami/async-tree").Treelike} treelike
11
11
  */
12
12
  export default async function addNextPrevious(treelike) {
13
- const tree = await getTreeArgument(this, arguments, treelike, "@sequence");
13
+ const tree = await getTreeArgument(
14
+ this,
15
+ arguments,
16
+ treelike,
17
+ "tree:addNextPrevious"
18
+ );
14
19
  let keys;
15
20
  return Object.create(tree, {
16
21
  get: {
@@ -1,5 +1,5 @@
1
1
  import { Tree, cache } from "@weborigami/async-tree";
2
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
3
 
4
4
  /**
5
5
  * Caches tree values in a storable cache.
@@ -17,7 +17,7 @@ export default async function cacheBuiltin(
17
17
  cacheTreelike,
18
18
  filterTreelike
19
19
  ) {
20
- assertTreeIsDefined(this, "cache");
20
+ assertTreeIsDefined(this, "tree:cache");
21
21
  /** @type {any} */
22
22
  const cacheTree = cacheTreelike
23
23
  ? Tree.from(cacheTreelike, { parent: this })
@@ -25,6 +25,3 @@ export default async function cacheBuiltin(
25
25
  const result = cache(sourceTreelike, cacheTree, filterTreelike);
26
26
  return result;
27
27
  }
28
-
29
- cacheBuiltin.usage = `@cache/tree tree, [cache], [filter]\tCaches tree values`;
30
- cacheBuiltin.documentation = "https://weborigami.org/cli/builtins.html#@cache";
@@ -1,5 +1,5 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
- import getTreeArgument from "../misc/getTreeArgument.js";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
3
 
4
4
  /**
5
5
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
@@ -7,10 +7,10 @@ import getTreeArgument from "../misc/getTreeArgument.js";
7
7
  * @this {AsyncTree|null}
8
8
  * @param {import("@weborigami/async-tree").Treelike} treelike
9
9
  */
10
- export default async function clean(treelike) {
11
- const tree = await getTreeArgument(this, arguments, treelike, "@clean");
10
+ export default async function clear(treelike) {
11
+ const tree = await getTreeArgument(this, arguments, treelike, "tree:clear");
12
12
  if (!Tree.isAsyncMutableTree(tree)) {
13
- throw new TypeError("@clean: the given tree is read-only.");
13
+ throw new TypeError("clean: the given tree is read-only.");
14
14
  }
15
15
  const keys = Array.from(await tree.keys());
16
16
  const promises = keys.map((key) => tree.set(key, undefined));
@@ -1,6 +1,6 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
2
  import { ops } from "@weborigami/language";
3
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
3
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
4
4
 
5
5
  /**
6
6
  * Concatenate the text content of objects or trees.
@@ -11,10 +11,7 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
11
11
  * @param {any[]} args
12
12
  */
13
13
  export default async function concat(...args) {
14
- assertTreeIsDefined(this, "concat");
14
+ assertTreeIsDefined(this, "tree:concat");
15
15
  const tree = args.length === 0 ? this : Tree.from(args, { parent: this });
16
16
  return ops.concat.call(this, tree);
17
17
  }
18
-
19
- concat.usage = `@concat <...objs>\tConcatenate text and/or trees of text`;
20
- concat.documentation = "https://weborigami.org/cli/@tree.html#concat";
@@ -1,9 +1,9 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
2
  import { formatError } from "@weborigami/language";
3
3
  import process, { stdout } from "node:process";
4
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
4
5
  import { transformObject } from "../common/utilities.js";
5
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
6
- import setDeep from "./@setDeep.js";
6
+ import setDeep from "./setDeep.js";
7
7
 
8
8
  /**
9
9
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
@@ -14,8 +14,7 @@ import setDeep from "./@setDeep.js";
14
14
  * @param {Treelike} target
15
15
  */
16
16
  export default async function copy(source, target) {
17
- assertTreeIsDefined(this, "copy");
18
- // const start = performance.now();
17
+ assertTreeIsDefined(this, "tree:copy");
19
18
  const sourceTree = Tree.from(source, { parent: this });
20
19
  /** @type {any} */ let targetTree = Tree.from(target, { parent: this });
21
20
 
@@ -35,9 +34,6 @@ export default async function copy(source, target) {
35
34
  countFiles = null;
36
35
  countCopied = null;
37
36
  }
38
-
39
- // const end = performance.now();
40
- // console.log(`copy time in ms: ${end - start}`);
41
37
  }
42
38
 
43
39
  let countFiles;
@@ -67,6 +63,3 @@ function ProgressTransform(Base) {
67
63
  }
68
64
  };
69
65
  }
70
-
71
- copy.usage = `@copy <source>, <target>\tCopies the source tree to the target`;
72
- copy.documentation = "https://weborigami.org/language/@copy.html";
@@ -1,9 +1,9 @@
1
1
  import { isPlainObject } from "@weborigami/async-tree";
2
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
3
- import mapFn from "./@mapFn.js";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
+ import map from "./map.js";
4
4
 
5
5
  /**
6
- * Shorthand for calling `@mapFn` with `deep: true` option.
6
+ * Shorthand for calling `map` with `deep: true` option.
7
7
  *
8
8
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
9
  * @typedef {import("@weborigami/async-tree").Treelike} Treelike
@@ -11,15 +11,22 @@ import mapFn from "./@mapFn.js";
11
11
  * @typedef {import("./map.d.ts").TreeMapOptions} TreeMapOptions
12
12
  *
13
13
  * @this {AsyncTree|null}
14
+ * @param {Treelike} treelike
14
15
  * @param {ValueKeyFn|TreeMapOptions} operation
15
16
  */
16
- export default function deepMapFn(operation) {
17
- assertTreeIsDefined(this, "deepMap");
17
+ export default async function deepMap(treelike, operation) {
18
+ const tree = await getTreeArgument(
19
+ this,
20
+ arguments,
21
+ treelike,
22
+ "tree:deepMap",
23
+ true
24
+ );
18
25
  /** @type {TreeMapOptions} */
19
26
  const options = isPlainObject(operation)
20
27
  ? // Dictionary
21
28
  { ...operation, deep: true }
22
29
  : // Function
23
30
  { deep: true, value: operation };
24
- return mapFn.call(this, options);
31
+ return map.call(this, tree, options);
25
32
  }
@@ -1,5 +1,5 @@
1
1
  import { deepMerge } from "@weborigami/async-tree";
2
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
3
 
4
4
  /**
5
5
  * Create a tree that's the result of deep merging the given trees.
@@ -9,8 +9,9 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
9
9
  * @this {AsyncTree|null}
10
10
  * @param {Treelike[]} trees
11
11
  */
12
- export default async function treedeepMerge(...trees) {
13
- assertTreeIsDefined(this, "deepMerge");
12
+ export default async function treeDeepMerge(...trees) {
13
+ assertTreeIsDefined(this, "tree:deepMerge");
14
+
14
15
  // Filter out null or undefined trees.
15
16
  const filtered = trees.filter((tree) => tree);
16
17
 
@@ -23,7 +24,3 @@ export default async function treedeepMerge(...trees) {
23
24
  const result = deepMerge(...filtered);
24
25
  return result;
25
26
  }
26
-
27
- treedeepMerge.usage = `@deepMerge <...trees>\tMerge the given trees deeply`;
28
- treedeepMerge.documentation =
29
- "https://weborigami.org/cli/builtins.html#deepMerge";
@@ -1,5 +1,5 @@
1
1
  import { deepReverse } from "@weborigami/async-tree";
2
- import getTreeArgument from "../misc/getTreeArgument.js";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
3
 
4
4
  /**
5
5
  * Reverse the order of keys at all levels of the tree.
@@ -11,7 +11,13 @@ import getTreeArgument from "../misc/getTreeArgument.js";
11
11
  * @param {Treelike} [treelike]
12
12
  */
13
13
  export default async function deepReverseBuiltin(treelike) {
14
- const tree = await getTreeArgument(this, arguments, treelike, "@deepReverse");
14
+ const tree = await getTreeArgument(
15
+ this,
16
+ arguments,
17
+ treelike,
18
+ "tree:deepReverse",
19
+ true
20
+ );
15
21
  const reversed = deepReverse(tree);
16
22
  return reversed;
17
23
  }
@@ -0,0 +1,26 @@
1
+ import { deepTake as deepTakeTransform } from "@weborigami/async-tree";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
+
4
+ /**
5
+ * Returns a function that traverses a tree deeply and returns the values of the
6
+ * first `count` keys.
7
+ *
8
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
+ * @typedef {import("@weborigami/async-tree").Treelike} Treelike
10
+ *
11
+ * @this {AsyncTree|null}
12
+ * @param {Treelike} treelike
13
+ * @param {number} count
14
+ */
15
+ export default async function deepTake(treelike, count) {
16
+ const tree = await getTreeArgument(
17
+ this,
18
+ arguments,
19
+ treelike,
20
+ "tree:deepTake",
21
+ true
22
+ );
23
+ const taken = await deepTakeTransform(tree, count);
24
+ taken.parent = this;
25
+ return taken;
26
+ }
@@ -1,5 +1,5 @@
1
1
  import { deepValues } from "@weborigami/async-tree";
2
- import getTreeArgument from "../misc/getTreeArgument.js";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
3
 
4
4
  /**
5
5
  * Return the in-order exterior values of a tree as a flat array.
@@ -15,12 +15,8 @@ export default async function deepValuesBuiltin(treelike) {
15
15
  this,
16
16
  arguments,
17
17
  treelike,
18
- "@valuesDeep",
18
+ "tree:deepValues",
19
19
  true
20
20
  );
21
21
  return deepValues(tree);
22
22
  }
23
-
24
- deepValuesBuiltin.usage = `@valuesDeep <tree>\tThe in-order tree values as a flat array`;
25
- deepValuesBuiltin.documentation =
26
- "https://weborigami.org/cli/builtins.html#valuesDeep";
@@ -1,5 +1,5 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
- import getTreeArgument from "../misc/getTreeArgument.js";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
3
 
4
4
  /**
5
5
  * Return only the defined (not `undefined`) values in the tree.
@@ -11,7 +11,12 @@ import getTreeArgument from "../misc/getTreeArgument.js";
11
11
  * @param {Treelike} treelike
12
12
  */
13
13
  export default async function defineds(treelike) {
14
- const tree = await getTreeArgument(this, arguments, treelike, "@defineds");
14
+ const tree = await getTreeArgument(
15
+ this,
16
+ arguments,
17
+ treelike,
18
+ "tree:defineds"
19
+ );
15
20
 
16
21
  const result = await Tree.mapReduce(tree, null, async (values, keys) => {
17
22
  const object = {};
@@ -1,6 +1,6 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
- import FilterTree from "../common/FilterTree.js";
3
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
+ import FilterTree from "./FilterTree.js";
4
4
 
5
5
  /**
6
6
  * Apply a filter to a tree.
@@ -12,13 +12,10 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
12
12
  * @param {Treelike} filterTreelike
13
13
  */
14
14
  export default async function filter(sourceTreelike, filterTreelike) {
15
- assertTreeIsDefined(this, "filter");
15
+ assertTreeIsDefined(this, "tree:filter");
16
16
  const sourceTree = Tree.from(sourceTreelike, { parent: this });
17
17
  const filterTree = Tree.from(filterTreelike, { deep: true, parent: this });
18
18
  const result = new FilterTree(sourceTree, filterTree);
19
19
  result.parent = this;
20
20
  return result;
21
21
  }
22
-
23
- filter.usage = `@filter <tree>, <filter>\tOnly returns values whose keys match the filter`;
24
- filter.documentation = "https://weborigami.org/language/@filter.html";
@@ -1,4 +1,4 @@
1
- import getTreeArgument from "../misc/getTreeArgument.js";
1
+ import getTreeArgument from "../common/getTreeArgument.js";
2
2
 
3
3
  /**
4
4
  * Return the first value 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 first(treelike) {
12
- const tree = await getTreeArgument(this, arguments, treelike, "@first");
12
+ const tree = await getTreeArgument(this, arguments, treelike, "tree:first");
13
13
  for (const key of await tree.keys()) {
14
14
  // Just return first value immediately.
15
15
  const value = await tree.get(key);
@@ -17,6 +17,3 @@ export default async function first(treelike) {
17
17
  }
18
18
  return undefined;
19
19
  }
20
-
21
- first.usage = `@first <tree>\tReturns the first value in the tree.`;
22
- first.documentation = "https://weborigami.org/cli/builtins.html#first";
@@ -1,6 +1,6 @@
1
1
  import { FunctionTree } from "@weborigami/async-tree";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
2
3
  import { toFunction } from "../common/utilities.js";
3
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
4
4
 
5
5
  /**
6
6
  * Create a tree from a function and a set of keys.
@@ -12,8 +12,8 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
12
12
  * @this {AsyncTree|null}
13
13
  * @param {Invocable} [invocable]
14
14
  */
15
- export default async function fnTree(invocable, keys = []) {
16
- assertTreeIsDefined(this, "fnTree");
15
+ export default async function fromFn(invocable, keys = []) {
16
+ assertTreeIsDefined(this, "tree:fromFn");
17
17
  if (invocable === undefined) {
18
18
  throw new Error(
19
19
  "An Origami function was called with an initial argument, but its value is undefined."
@@ -24,6 +24,3 @@ export default async function fnTree(invocable, keys = []) {
24
24
  tree.parent = this;
25
25
  return tree;
26
26
  }
27
-
28
- fnTree.usage = `@fnTree <fn>, [<keys>]\tCreate a tree from a function and a set of keys`;
29
- fnTree.documentation = "https://weborigami.org/cli/tree.html#fn";
@@ -1,5 +1,5 @@
1
- import GlobTree from "../common/GlobTree.js";
2
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
1
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
2
+ import GlobTree from "./GlobTree.js";
3
3
 
4
4
  /**
5
5
  * Define a tree whose keys are globs.
@@ -11,10 +11,7 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
11
11
  * @this {AsyncTree|null}
12
12
  */
13
13
  export default async function globs(tree) {
14
- assertTreeIsDefined(this, "globs");
14
+ assertTreeIsDefined(this, "tree:globs");
15
15
  const result = new GlobTree(tree);
16
16
  return result;
17
17
  }
18
-
19
- globs.usage = `@globs <patterns>\tDefine a tree whose keys can include wildcard globs`;
20
- globs.documentation = "https://weborigami.org/language/@globs.html";
@@ -0,0 +1,26 @@
1
+ import { group as groupTransform } from "@weborigami/async-tree";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
+ import { toFunction } from "../common/utilities.js";
4
+
5
+ /**
6
+ * Map a tree to a new tree with the values from the original tree grouped by
7
+ * the given function.
8
+ *
9
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
10
+ *
11
+ * @this {AsyncTree|null}
12
+ * @param {import("@weborigami/async-tree").Treelike} treelike
13
+ * @param {import("../../index.ts").Invocable} groupKey
14
+ */
15
+ export default async function groupBuiltin(treelike, groupKey) {
16
+ const tree = await getTreeArgument(this, arguments, treelike, "tree:group");
17
+
18
+ const groupKeyFn = toFunction(groupKey);
19
+ // Have the group key function run in this tree.
20
+ const extendedGroupKeyFn = groupKeyFn.bind(tree);
21
+
22
+ // @ts-ignore
23
+ const grouped = await groupTransform(tree, extendedGroupKeyFn);
24
+ grouped.parent = tree;
25
+ return grouped;
26
+ }
@@ -1,5 +1,5 @@
1
1
  import { trailingSlash, Tree } from "@weborigami/async-tree";
2
- import getTreeArgument from "../misc/getTreeArgument.js";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
3
 
4
4
  /**
5
5
  * Return the interior nodes of the tree. This relies on subtree keys having
@@ -11,7 +11,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
11
11
  * @param {Treelike} [treelike]
12
12
  */
13
13
  export default async function inners(treelike) {
14
- const tree = await getTreeArgument(this, arguments, treelike, "@inners");
14
+ const tree = await getTreeArgument(this, arguments, treelike, "tree:inners");
15
15
 
16
16
  const result = {
17
17
  async get(key) {
@@ -28,6 +28,3 @@ export default async function inners(treelike) {
28
28
 
29
29
  return result;
30
30
  }
31
-
32
- inners.usage = `@inners <tree>\tThe interior nodes of the tree`;
33
- inners.documentation = "https://weborigami.org/cli/builtins.html#inners";
@@ -1,4 +1,4 @@
1
- import getTreeArgument from "../misc/getTreeArgument.js";
1
+ import getTreeArgument from "../common/getTreeArgument.js";
2
2
 
3
3
  /**
4
4
  * Return the top-level keys in the tree as an array.
@@ -9,10 +9,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
9
9
  * @param {Treelike} [treelike]
10
10
  */
11
11
  export default async function keys(treelike) {
12
- const tree = await getTreeArgument(this, arguments, treelike, "@keys");
12
+ const tree = await getTreeArgument(this, arguments, treelike, "tree:keys");
13
13
  const keys = await tree.keys();
14
14
  return Array.from(keys);
15
15
  }
16
-
17
- keys.usage = `@keys <tree>\tThe top-level keys in the tree`;
18
- keys.documentation = "https://weborigami.org/cli/builtins.html#keys";
@@ -1,4 +1,4 @@
1
- import getTreeArgument from "../misc/getTreeArgument.js";
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, "@length");
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 { KeyFn, Treelike, TreeTransform, ValueKeyFn } from "@weborigami/async-tree";
1
+ import { TreeMapOptions as AsyncTreeMapOptions, Treelike, TreeTransform, ValueKeyFn } from "@weborigami/async-tree";
2
2
  import { AsyncTree } from "@weborigami/types";
3
3
 
4
- type TreeMapOptions = {
5
- deep?: boolean;
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;