@weborigami/origami 0.0.73 → 0.2.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 +71 -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 +1 -2
  14. package/src/common/utilities.js +24 -31
  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} +24 -30
  22. package/src/{misc → dev}/explore.js.inline +4 -4
  23. package/src/{misc → dev}/explore.ori +4 -4
  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 +2 -5
  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 +428 -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} +32 -10
  75. package/src/protocols/scope.js +24 -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} +4 -7
  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 +57 -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 +50 -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,4 +1,4 @@
1
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
1
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
2
2
 
3
3
  /**
4
4
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
@@ -8,6 +8,6 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
8
8
  * @returns
9
9
  */
10
10
  export default function pack(obj) {
11
- assertTreeIsDefined(this, "pack");
11
+ assertTreeIsDefined(this, "origami:pack");
12
12
  return obj?.pack?.();
13
13
  }
@@ -1,9 +1,8 @@
1
1
  /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
2
  import { Tree } from "@weborigami/async-tree";
3
3
  import { OrigamiFiles } from "@weborigami/language";
4
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
5
- import builtins from "./@builtins.js";
6
- import fileTypeOrigami from "./ori.handler.js";
4
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
5
+ import { builtinsTree, oriHandler } from "../internal.js";
7
6
 
8
7
  const configFileName = "config.ori";
9
8
 
@@ -23,11 +22,11 @@ const configFileName = "config.ori";
23
22
  * @param {any} [key]
24
23
  */
25
24
  export default async function project(key) {
26
- assertTreeIsDefined(this, "project");
25
+ assertTreeIsDefined(this, "origami:project");
27
26
 
28
27
  const dirname = process.cwd();
29
28
  const currentTree = new OrigamiFiles(dirname);
30
- currentTree.parent = builtins;
29
+ currentTree.parent = builtinsTree;
31
30
 
32
31
  // Search up the tree for the configuration file or package.json to determine
33
32
  // the project root.
@@ -47,7 +46,7 @@ export default async function project(key) {
47
46
  projectRoot = configContainer;
48
47
  } else {
49
48
  // Load Origami configuration file
50
- const config = await fileTypeOrigami.unpack(buffer, {
49
+ const config = await oriHandler.unpack(buffer, {
51
50
  key: configFileName,
52
51
  parent: configContainer,
53
52
  });
@@ -66,7 +65,7 @@ export default async function project(key) {
66
65
  projectRoot = new OrigamiFiles(configContainer.path);
67
66
  projectRoot.parent = configTree;
68
67
  configTree.parent = configContainer;
69
- configContainer.parent = builtins;
68
+ configContainer.parent = builtinsTree;
70
69
  }
71
70
  }
72
71
 
@@ -83,7 +82,7 @@ async function findAncestorFile(start, fileName) {
83
82
  // Found the desired file; its container is the project root. Set the
84
83
  // parent to the builtins; in the context of this project, there's nothing
85
84
  // higher up.
86
- current.parent = builtins;
85
+ current.parent = builtinsTree;
87
86
  return current;
88
87
  }
89
88
  // Not found; try the parent.
@@ -98,6 +97,3 @@ async function findAncestorFile(start, fileName) {
98
97
  }
99
98
  return undefined;
100
99
  }
101
-
102
- project.usage = `@project\tThe root of the current Origami project`;
103
- project.documentation = "https://weborigami.org/language/@project.html";
@@ -1,4 +1,4 @@
1
- import regexMatchFn from "./@regexMatchFn.js";
1
+ import regexMatchFn from "./regexMatchFn.js";
2
2
 
3
3
  export default function regexMatch(text, regex) {
4
4
  return regexMatchFn(regex)(text);
@@ -0,0 +1,5 @@
1
+ export default async function repeat(count, content) {
2
+ const array = new Array(count);
3
+ array.fill(content);
4
+ return array;
5
+ }
@@ -11,6 +11,3 @@ export default async function shell(command) {
11
11
  return undefined;
12
12
  }
13
13
  }
14
-
15
- shell.usage = `@shell <command>\tExecutes the shell command and returns the output`;
16
- shell.documentation = "https://weborigami.org/language/@shell.html";
@@ -27,6 +27,3 @@ function readAll(readable) {
27
27
  });
28
28
  });
29
29
  }
30
-
31
- stdin.usage = `@stdin\tReturns the contents of the standard input stream`;
32
- stdin.documentation = "https://weborigami.org/language/@stdin.html";
@@ -1,5 +1,5 @@
1
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
1
2
  import { toString } from "../common/utilities.js";
2
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
3
3
 
4
4
  /**
5
5
  * Convert an object to a string.
@@ -9,6 +9,6 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
9
9
  * @param {any} object
10
10
  */
11
11
  export default function stringBuiltin(object) {
12
- assertTreeIsDefined(this, "string");
12
+ assertTreeIsDefined(this, "origami:string");
13
13
  return toString(object);
14
14
  }
@@ -1,4 +1,4 @@
1
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
1
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
2
2
 
3
3
  /**
4
4
  * Unpack a packed format like a Uint8Array or ArrayBuffer to a usable form like
@@ -9,6 +9,6 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
9
9
  * @param {any} obj
10
10
  */
11
11
  export default function unpack(obj) {
12
- assertTreeIsDefined(this, "unpack");
12
+ assertTreeIsDefined(this, "origami:unpack");
13
13
  return obj?.unpack?.() ?? obj;
14
14
  }
@@ -1,7 +1,7 @@
1
1
  /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
2
  import { isUnpackable, toPlainValue } from "@weborigami/async-tree";
3
3
  import YAML from "yaml";
4
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
4
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
5
5
 
6
6
  /**
7
7
  * Render the object as text in YAML format.
@@ -10,7 +10,7 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
10
10
  * @param {any} [obj]
11
11
  */
12
12
  export default async function toYaml(obj) {
13
- assertTreeIsDefined(this, "yaml");
13
+ assertTreeIsDefined(this, "origami:yaml");
14
14
  // A fragment of the logic from getTreeArgument.js
15
15
  if (arguments.length > 0 && obj === undefined) {
16
16
  throw new Error(
@@ -27,6 +27,3 @@ export default async function toYaml(obj) {
27
27
  const value = await toPlainValue(obj);
28
28
  return YAML.stringify(value);
29
29
  }
30
-
31
- toYaml.usage = `@yaml <obj>\tRender the object as text in YAML format`;
32
- toYaml.documentation = "https://weborigami.org/language/@yaml.html";
@@ -5,6 +5,3 @@ export default async function yamlParse(input) {
5
5
  const text = toString(input);
6
6
  return text ? serialize.parseYaml(text) : undefined;
7
7
  }
8
-
9
- yamlParse.usage = `@yamlParse <text>\tParse text as YAML`;
10
- yamlParse.documentation = "https://weborigami.org/builtins/@yamlParse.html";
@@ -0,0 +1,19 @@
1
+ import { ExplorableSiteTree } from "@weborigami/async-tree";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
+ import constructSiteTree from "../common/constructSiteTree.js";
4
+
5
+ /**
6
+ * A site tree with JSON Keys via HTTPS.
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 {string} host
14
+ * @param {...string} keys
15
+ */
16
+ export default function explore(host, ...keys) {
17
+ assertTreeIsDefined(this, "explore:");
18
+ return constructSiteTree("https:", ExplorableSiteTree, this, host, ...keys);
19
+ }
@@ -2,7 +2,7 @@ import { OrigamiFiles } from "@weborigami/language";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import process from "node:process";
5
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
5
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
6
6
 
7
7
  /**
8
8
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
@@ -11,7 +11,7 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
11
11
  * @param {string[]} keys
12
12
  */
13
13
  export default async function files(...keys) {
14
- assertTreeIsDefined(this, "files");
14
+ assertTreeIsDefined(this, "files:");
15
15
 
16
16
  // If path begins with `~`, treat it relative to the home directory.
17
17
  // Otherwise, treat it relative to the current working directory.
@@ -28,6 +28,3 @@ export default async function files(...keys) {
28
28
  const result = new OrigamiFiles(resolved);
29
29
  return result;
30
30
  }
31
-
32
- files.usage = `@files [path]\tTree of files at the given path`;
33
- files.documentation = "https://weborigami.org/language/@files.html";
@@ -0,0 +1,18 @@
1
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
2
+ import constructHref from "../common/constructHref.js";
3
+ import fetchAndHandleExtension from "../common/fetchAndHandleExtension.js";
4
+
5
+ /**
6
+ * Retrieve the indicated web resource via HTTP.
7
+ *
8
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
+ *
10
+ * @this {AsyncTree|null}
11
+ * @param {string} host
12
+ * @param {...string} keys
13
+ */
14
+ export default async function http(host, ...keys) {
15
+ assertTreeIsDefined(this, "http:");
16
+ const href = constructHref("http:", host, ...keys);
17
+ return fetchAndHandleExtension.call(this, href);
18
+ }
@@ -0,0 +1,18 @@
1
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
2
+ import constructHref from "../common/constructHref.js";
3
+ import fetchAndHandleExtension from "../common/fetchAndHandleExtension.js";
4
+
5
+ /**
6
+ * Retrieve the indicated web resource via HTTPS.
7
+ *
8
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
+ *
10
+ * @this {AsyncTree|null}
11
+ * @param {string} host
12
+ * @param {...string} keys
13
+ */
14
+ export default async function https(host, ...keys) {
15
+ assertTreeIsDefined(this, "https:");
16
+ const href = constructHref("https:", host, ...keys);
17
+ return fetchAndHandleExtension.call(this, href);
18
+ }
@@ -0,0 +1,19 @@
1
+ import { SiteTree } from "@weborigami/async-tree";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
+ import constructSiteTree from "../common/constructSiteTree.js";
4
+
5
+ /**
6
+ * Return a website tree via HTTPS.
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 {string} host
14
+ * @param {...string} keys
15
+ */
16
+ export default function httpstree(host, ...keys) {
17
+ assertTreeIsDefined(this, "treehttps:");
18
+ return constructSiteTree("https:", SiteTree, this, host, ...keys);
19
+ }
@@ -0,0 +1,19 @@
1
+ import { SiteTree } from "@weborigami/async-tree";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
+ import constructSiteTree from "../common/constructSiteTree.js";
4
+
5
+ /**
6
+ * Return a website tree via HTTP.
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 {string} host
14
+ * @param {...string} keys
15
+ */
16
+ export default function httptree(host, ...keys) {
17
+ assertTreeIsDefined(this, "httptree:");
18
+ return constructSiteTree("http:", SiteTree, this, host, ...keys);
19
+ }
@@ -0,0 +1,18 @@
1
+ import { Tree } from "@weborigami/async-tree";
2
+ import { ops } from "@weborigami/language";
3
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
4
+
5
+ /**
6
+ * Return the inherited value (if any) for the indicated key.
7
+ *
8
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
9
+ *
10
+ * @this {AsyncTree|null}
11
+ * @param {string[]} keys
12
+ */
13
+ export default async function inherited(...keys) {
14
+ assertTreeIsDefined(this, "inherited:");
15
+ const key = keys.shift();
16
+ const value = await ops.inherited.call(this, key);
17
+ return keys.length > 0 ? await Tree.traverse(value, ...keys) : value;
18
+ }
@@ -0,0 +1,42 @@
1
+ import { isUnpackable, scope as scopeFn, Tree } from "@weborigami/async-tree";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
+
4
+ /**
5
+ * Find the indicated class constructor in scope, then return a function which
6
+ * invokes it with `new`.
7
+ *
8
+ * This can also take a single argument that is a class.
9
+ *
10
+ * @this {import("@weborigami/types").AsyncTree|null}
11
+ * @param {...any} keys
12
+ */
13
+ export default async function instantiate(...keys) {
14
+ assertTreeIsDefined(this, "new:");
15
+ let constructor;
16
+ const scope = this ? scopeFn(this) : null;
17
+ if (
18
+ keys.length === 1 &&
19
+ (typeof keys[0] === "object" || typeof keys[0] === "function")
20
+ ) {
21
+ constructor = keys[0];
22
+ } else if (scope) {
23
+ constructor = await Tree.traverseOrThrow(scope, ...keys);
24
+ } else {
25
+ throw new TypeError(`new: The scope isn't defined.`);
26
+ }
27
+ if (isUnpackable(constructor)) {
28
+ constructor = await constructor.unpack();
29
+ }
30
+ // Origami may pass `undefined` as the first argument to the constructor. We
31
+ // don't pass that along, because constructors like `Date` don't like it.
32
+ return (...args) => {
33
+ const object =
34
+ args.length === 1 && args[0] === undefined
35
+ ? new constructor()
36
+ : new constructor(...args);
37
+ if (Tree.isAsyncTree(object)) {
38
+ object.parent = scope;
39
+ }
40
+ return object;
41
+ };
42
+ }
@@ -1,28 +1,45 @@
1
1
  import { Tree, keysFromPath, scope } from "@weborigami/async-tree";
2
- import project from "./@project.js";
2
+ import project from "../origami/project.js";
3
3
 
4
4
  /**
5
5
  * @this {import("@weborigami/types").AsyncTree|null}
6
6
  * @param {string[]} keys
7
7
  */
8
- export default async function packageBuiltin(...keys) {
8
+ export default async function packageNamespace(...keys) {
9
9
  const parent = this ?? (await project.call(null));
10
- const parentScope = scope(parent);
11
10
 
12
- const packageKeys = [keys.shift()];
13
- if (packageKeys[0]?.startsWith("@")) {
14
- // First key is an npm organization, get the next key too.
15
- packageKeys.push(keys.shift());
11
+ let name = keys.shift();
12
+ let organization;
13
+ if (name?.startsWith("@")) {
14
+ // First key is an npm organization
15
+ organization = name;
16
+ if (keys.length === 0) {
17
+ // Return a function that will process the next key
18
+ return async (name, ...keys) =>
19
+ getPackage(parent, organization, name, keys);
20
+ }
21
+ name = keys.shift();
22
+ }
23
+
24
+ return getPackage(parent, organization, name, keys);
25
+ }
26
+
27
+ async function getPackage(parent, organization, name, keys) {
28
+ const packagePath = ["node_modules"];
29
+ if (organization) {
30
+ packagePath.push(organization);
16
31
  }
32
+ packagePath.push(name);
17
33
 
34
+ const parentScope = scope(parent);
18
35
  const packageRoot = await Tree.traverse(
19
36
  // @ts-ignore
20
37
  parentScope,
21
- "node_modules",
22
- ...packageKeys
38
+ ...packagePath
23
39
  );
40
+
24
41
  if (!packageRoot) {
25
- throw new Error(`Can't find node_modules/${packageKeys.join("/")}`);
42
+ throw new Error(`Can't find ${packagePath.join("/")}`);
26
43
  }
27
44
 
28
45
  const mainPath = await Tree.traverse(packageRoot, "package.json", "main");
@@ -44,5 +61,10 @@ export default async function packageBuiltin(...keys) {
44
61
  keys.length > 0
45
62
  ? await Tree.traverse(packageExports, ...keys)
46
63
  : packageExports;
64
+
65
+ if (Tree.isAsyncTree(result)) {
66
+ result.parent = parent;
67
+ }
68
+
47
69
  return result;
48
70
  }
@@ -0,0 +1,24 @@
1
+ import { Tree } from "@weborigami/async-tree";
2
+ import { ops } from "@weborigami/language";
3
+
4
+ /**
5
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
6
+ *
7
+ * @this {AsyncTree|null}
8
+ * @param {string[]} keys
9
+ */
10
+ export default async function scope(...keys) {
11
+ const key = keys.shift();
12
+ let value;
13
+ try {
14
+ // Look up key in scope but don't throw if it's undefined
15
+ value = await ops.scope.call(this, key);
16
+ } catch (error) {
17
+ if (error instanceof ReferenceError) {
18
+ value = undefined;
19
+ } else {
20
+ throw error;
21
+ }
22
+ }
23
+ return keys.length > 0 ? await Tree.traverse(value, ...keys) : value;
24
+ }
@@ -1,11 +1,11 @@
1
1
  import {
2
- SiteTree,
3
- Tree,
2
+ extension,
4
3
  isPacked,
5
4
  isPlainObject,
6
5
  isStringLike,
6
+ SiteTree,
7
+ Tree,
7
8
  } from "@weborigami/async-tree";
8
- import { extname } from "@weborigami/language";
9
9
  import * as serialize from "../common/serialize.js";
10
10
  import { toString } from "../common/utilities.js";
11
11
  import { mediaTypeForExtension } from "./mediaTypes.js";
@@ -51,8 +51,8 @@ export default async function constructResponse(request, resource) {
51
51
  mediaType = resource.mediaType;
52
52
  } else {
53
53
  // Infer expected media type from file extension on request URL.
54
- const extension = extname(url.pathname).toLowerCase();
55
- mediaType = extension ? mediaTypeForExtension[extension] : undefined;
54
+ const ext = extension.extname(url.pathname).toLowerCase();
55
+ mediaType = ext ? mediaTypeForExtension[ext] : undefined;
56
56
  }
57
57
 
58
58
  if (
@@ -1,13 +1,13 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
- import getTreeArgument from "../misc/getTreeArgument.js";
3
- import crawl from "./@crawl.js";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
3
+ import crawl from "./crawler/crawl.js";
4
4
 
5
5
  /**
6
6
  * @this {import("@weborigami/types").AsyncTree|null}
7
7
  * @param {import("@weborigami/async-tree").Treelike} treelike
8
8
  */
9
- export default async function siteAudit(treelike) {
10
- const tree = await getTreeArgument(this, arguments, treelike, "@siteAudit");
9
+ export default async function audit(treelike) {
10
+ const tree = await getTreeArgument(this, arguments, treelike, "site:audit");
11
11
  const crawled = await crawl.call(this, tree);
12
12
  let crawlErrorsJson = await crawled.get("crawl-errors.json");
13
13
  if (!crawlErrorsJson) {
@@ -7,8 +7,8 @@ import {
7
7
  trailingSlash,
8
8
  } from "@weborigami/async-tree";
9
9
  import { InvokeFunctionsTransform } from "@weborigami/language";
10
- import crawlResources from "../crawler/crawlResources.js";
11
- import getTreeArgument from "../misc/getTreeArgument.js";
10
+ import getTreeArgument from "../../common/getTreeArgument.js";
11
+ import crawlResources from "./crawlResources.js";
12
12
 
13
13
  /**
14
14
  * Crawl a tree, starting its root index.html page, and following links to
@@ -26,7 +26,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
26
26
  * @returns {Promise<AsyncTree>}
27
27
  */
28
28
  export default async function crawlBuiltin(treelike, baseHref) {
29
- const tree = await getTreeArgument(this, arguments, treelike, "@crawl");
29
+ const tree = await getTreeArgument(this, arguments, treelike, "site:crawl");
30
30
 
31
31
  if (baseHref === undefined) {
32
32
  // Ask tree or original treelike if it has an `href` property we can use as
@@ -124,6 +124,3 @@ function addValueToObject(object, keys, value) {
124
124
  }
125
125
  }
126
126
  }
127
-
128
- crawlBuiltin.usage = `@crawl <tree>\tCrawl a tree`;
129
- crawlBuiltin.documentation = "https://weborigami.org/language/@crawl.html";
@@ -1,5 +1,4 @@
1
- import { toString } from "@weborigami/async-tree";
2
- import { extname } from "@weborigami/language";
1
+ import { extension, toString } from "@weborigami/async-tree";
3
2
  import { isCrawlableHref, normalizeHref } from "./utilities.js";
4
3
 
5
4
  // Filter the paths to those that are local to the site.
@@ -42,7 +41,7 @@ export default function findPaths(value, key, baseUrl, localPath) {
42
41
 
43
42
  // We guess the value is HTML is if its key has an .html extension or
44
43
  // doesn't have an extension, or the value starts with `<`.
45
- const ext = key ? extname(key).toLowerCase() : "";
44
+ const ext = key ? extension.extname(key).toLowerCase() : "";
46
45
  let foundPaths;
47
46
  if (ext === ".html" || ext === ".htm" || ext === ".xhtml") {
48
47
  foundPaths = findPathsInHtml(text);
@@ -1,5 +1,4 @@
1
- import { trailingSlash } from "@weborigami/async-tree";
2
- import { extname } from "@weborigami/language";
1
+ import { extension, trailingSlash } from "@weborigami/async-tree";
3
2
 
4
3
  // A fake base URL used to handle cases where an href is relative and must be
5
4
  // treated relative to some base URL.
@@ -13,7 +12,7 @@ export function isCrawlableHref(href) {
13
12
  if (lastKey === "robots.txt" || lastKey === "sitemap.xml") {
14
13
  return true;
15
14
  }
16
- const ext = extname(lastKey);
15
+ const ext = extension.extname(lastKey);
17
16
  // We assume an empty extension is HTML.
18
17
  const crawlableExtensions = [".html", ".css", ".js", ".map", ".xhtml", ""];
19
18
  return crawlableExtensions.includes(ext);
@@ -1,5 +1,5 @@
1
- import { keySymbol } from "../common/utilities.js";
2
- import getTreeArgument from "../misc/getTreeArgument.js";
1
+ import getTreeArgument from "../common/getTreeArgument.js";
2
+ import { getDescriptor } from "../common/utilities.js";
3
3
 
4
4
  /**
5
5
  * Return a default index.html page for the current tree.
@@ -10,7 +10,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
10
10
  * @param {Treelike} [treelike]
11
11
  */
12
12
  export default async function index(treelike) {
13
- const tree = await getTreeArgument(this, arguments, treelike, "@index");
13
+ const tree = await getTreeArgument(this, arguments, treelike, "site:index");
14
14
  const keys = Array.from(await tree.keys());
15
15
 
16
16
  // Skip system-ish files that start with a period. Also skip `index.html`.
@@ -26,7 +26,7 @@ export default async function index(treelike) {
26
26
  links.push(link);
27
27
  }
28
28
 
29
- const heading = tree[keySymbol] ?? "Index";
29
+ const heading = getDescriptor(tree) ?? "Index";
30
30
  const list = ` <ul>\n${links.join("\n")}\n </ul>`;
31
31
 
32
32
  const html = `<!DOCTYPE html>
@@ -59,6 +59,3 @@ ${list}
59
59
  result.unpack = () => tree;
60
60
  return result;
61
61
  }
62
-
63
- index.usage = `@index\tReturn a default index.html page for the current tree`;
64
- index.documentation = "https://weborigami.org/language/@index.html";
@@ -1,6 +1,6 @@
1
1
  import { Tree, jsonKeys } from "@weborigami/async-tree";
2
+ import getTreeArgument from "../common/getTreeArgument.js";
2
3
  import { transformObject } from "../common/utilities.js";
3
- import getTreeArgument from "../misc/getTreeArgument.js";
4
4
 
5
5
  /**
6
6
  * Expose .keys.json for a tree.
@@ -15,13 +15,13 @@ export default async function jsonKeysBuiltin(treelike) {
15
15
  this,
16
16
  arguments,
17
17
  treelike,
18
- "@keysJson",
18
+ "site:jsonKeys",
19
19
  true
20
20
  );
21
- return transformObject(KeysJsonTransform, tree);
21
+ return transformObject(JsonKeysTransform, tree);
22
22
  }
23
23
 
24
- function KeysJsonTransform(Base) {
24
+ function JsonKeysTransform(Base) {
25
25
  return class Static extends Base {
26
26
  async get(key) {
27
27
  let value = await super.get(key);
@@ -29,7 +29,7 @@ function KeysJsonTransform(Base) {
29
29
  value = await jsonKeys.stringify(this);
30
30
  } else if (Tree.isTreelike(value)) {
31
31
  const tree = Tree.from(value, { deep: true, parent: this });
32
- value = transformObject(KeysJsonTransform, tree);
32
+ value = transformObject(JsonKeysTransform, tree);
33
33
  }
34
34
  return value;
35
35
  }
@@ -1,5 +1,5 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
- import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
2
+ import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
3
3
 
4
4
  const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
5
5
  const months = [
@@ -25,7 +25,7 @@ const months = [
25
25
  * @param {any} options
26
26
  */
27
27
  export default async function rss(jsonFeedTree, options = {}) {
28
- assertTreeIsDefined(this, "rss");
28
+ assertTreeIsDefined(this, "site:rss");
29
29
  const jsonFeed = await Tree.plain(jsonFeedTree);
30
30
  const { description, home_page_url, items, title } = jsonFeed;
31
31
 
@@ -114,6 +114,3 @@ function toRFC822Date(date) {
114
114
  const seconds = date.getUTCSeconds().toString().padStart(2, "0");
115
115
  return `${day}, ${dayOfMonth} ${month} ${year} ${hours}:${minutes}:${seconds} GMT`;
116
116
  }
117
-
118
- rss.usage = `@rss <feed>\tTransforms a JSON Feed tree to RSS XML`;
119
- rss.documentation = "https://weborigami.org/language/@rss.html";
@@ -0,0 +1,9 @@
1
+ export { default as audit } from "./audit.js";
2
+ export { default as crawl } from "./crawler/crawl.js";
3
+ export { default as index } from "./index.js";
4
+ export { default as jsonKeys } from "./jsonKeys.js";
5
+ export { default as redirect } from "./redirect.js";
6
+ export { default as rss } from "./rss.js";
7
+ export { default as sitemap } from "./sitemap.js";
8
+ export { default as slug } from "./slug.js";
9
+ export { default as staticBuiltin } from "./static.js";