@weborigami/origami 0.5.5 → 0.5.6

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 (66) hide show
  1. package/main.js +2 -26
  2. package/package.json +4 -5
  3. package/src/cli/cli.js +10 -8
  4. package/src/common/documentObject.js +1 -1
  5. package/src/common/utilities.d.ts +0 -1
  6. package/src/common/utilities.js +1 -19
  7. package/src/dev/ExplorableSiteTransform.js +2 -2
  8. package/src/dev/OriCommandTransform.js +25 -7
  9. package/src/dev/explore.js +17 -40
  10. package/src/dev/help.yaml +4 -1
  11. package/src/dev/log.js +1 -1
  12. package/src/dev/svg.js +5 -5
  13. package/src/initializeBuiltins.js +23 -0
  14. package/src/origami/fetch.js +4 -8
  15. package/src/origami/indexPage.js +4 -4
  16. package/src/origami/inline.js +3 -4
  17. package/src/origami/jsonParse.js +1 -1
  18. package/src/origami/mdHtml.js +3 -7
  19. package/src/origami/mdOutline.js +3 -3
  20. package/src/origami/ori.js +16 -24
  21. package/src/origami/origami.js +0 -2
  22. package/src/origami/sitemap.js +2 -2
  23. package/src/origami/static.js +2 -2
  24. package/src/origami/string.js +1 -10
  25. package/src/origami/yaml.js +1 -5
  26. package/src/origami/yamlParse.js +1 -1
  27. package/src/server/constructResponse.js +1 -1
  28. package/src/server/server.js +6 -26
  29. package/src/builtinsProgram.js +0 -56
  30. package/src/builtinsShell.js +0 -18
  31. package/src/cli/getConfig.js +0 -11
  32. package/src/common/constructHref.js +0 -20
  33. package/src/common/constructSiteTree.js +0 -34
  34. package/src/common/fetchAndHandleExtension.js +0 -27
  35. package/src/handlers/css.handler.js +0 -7
  36. package/src/handlers/csv.handler.js +0 -129
  37. package/src/handlers/handlerBuiltins.js +0 -27
  38. package/src/handlers/handlers.js +0 -33
  39. package/src/handlers/htm.handler.js +0 -2
  40. package/src/handlers/html.handler.js +0 -7
  41. package/src/handlers/jpeg.handler.js +0 -62
  42. package/src/handlers/jpg.handler.js +0 -2
  43. package/src/handlers/js.handler.js +0 -20
  44. package/src/handlers/json.handler.js +0 -27
  45. package/src/handlers/md.handler.js +0 -7
  46. package/src/handlers/mjs.handler.js +0 -2
  47. package/src/handlers/ori.handler.js +0 -55
  48. package/src/handlers/oridocument.handler.js +0 -78
  49. package/src/handlers/parseFrontMatter.js +0 -16
  50. package/src/handlers/processUnpackedContent.js +0 -35
  51. package/src/handlers/ts.handler.js +0 -1
  52. package/src/handlers/txt.handler.js +0 -91
  53. package/src/handlers/wasm.handler.js +0 -17
  54. package/src/handlers/xhtml.handler.js +0 -2
  55. package/src/handlers/yaml.handler.js +0 -36
  56. package/src/handlers/yml.handler.js +0 -2
  57. package/src/origami/config.js +0 -18
  58. package/src/origami/project.js +0 -111
  59. package/src/protocols/explore.js +0 -17
  60. package/src/protocols/files.js +0 -31
  61. package/src/protocols/http.js +0 -18
  62. package/src/protocols/https.js +0 -18
  63. package/src/protocols/httpstree.js +0 -17
  64. package/src/protocols/httptree.js +0 -17
  65. package/src/protocols/node.js +0 -13
  66. package/src/protocols/package.js +0 -70
package/main.js CHANGED
@@ -1,29 +1,5 @@
1
1
  export { default as documentObject } from "./src/common/documentObject.js";
2
- export { toString } from "./src/common/utilities.js";
3
- export { default as handlerBuiltins } from "./src/handlers/handlerBuiltins.js";
4
- export * from "./src/handlers/handlers.js";
5
- export * from "./src/origami/origami.js";
2
+ export * as Dev from "./src/dev/dev.js";
3
+ export * as Origami from "./src/origami/origami.js";
6
4
  export { default as origamiHighlightDefinition } from "./src/origami/origamiHighlightDefinition.js";
7
- export { default as package } from "./src/protocols/package.js";
8
5
  export * from "./src/server/server.js";
9
-
10
- // Export only those dev exports that aren't tree exports
11
- export {
12
- audit,
13
- breakpoint,
14
- changes,
15
- code,
16
- copy,
17
- crawl,
18
- debug,
19
- explore,
20
- help,
21
- indexPage,
22
- log,
23
- serve,
24
- stdin,
25
- svg,
26
- version,
27
- watch,
28
- yaml,
29
- } from "./src/dev/dev.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/origami",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "Web Origami language, CLI, framework, and server",
5
5
  "type": "module",
6
6
  "repository": {
@@ -17,12 +17,11 @@
17
17
  "typescript": "5.9.2"
18
18
  },
19
19
  "dependencies": {
20
- "@weborigami/async-tree": "0.5.5",
20
+ "@weborigami/async-tree": "0.5.6",
21
21
  "@weborigami/json-feed-to-rss": "1.0.0",
22
- "@weborigami/language": "0.5.5",
23
- "@weborigami/types": "0.5.5",
22
+ "@weborigami/language": "0.5.6",
23
+ "@weborigami/types": "0.5.6",
24
24
  "css-tree": "3.1.0",
25
- "exif-parser": "0.1.12",
26
25
  "graphviz-wasm": "3.0.2",
27
26
  "highlight.js": "11.11.1",
28
27
  "jsdom": "26.1.0",
package/src/cli/cli.js CHANGED
@@ -1,26 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { Tree } from "@weborigami/async-tree";
4
- import { formatError } from "@weborigami/language";
4
+ import { formatError, projectRoot } from "@weborigami/language";
5
5
  import path from "node:path";
6
6
  import process, { stdout } from "node:process";
7
7
  import help from "../dev/help.js";
8
+ import initializeBuiltins from "../initializeBuiltins.js";
8
9
  import ori from "../origami/ori.js";
9
- import project from "../origami/project.js";
10
10
 
11
11
  const TypedArray = Object.getPrototypeOf(Uint8Array);
12
12
 
13
13
  async function main(...args) {
14
14
  const expression = args.join(" ");
15
15
 
16
+ // Need to initialize builtins before calling projectRoot, which instantiates
17
+ // an OrigamiFiles object that handles extensions, which requires builtins.
18
+ initializeBuiltins();
19
+
16
20
  // Find the project root.
17
- const projectTree = await project.call(null);
21
+ const projectTree = await projectRoot();
18
22
 
19
23
  // If no arguments were passed, show usage.
20
24
  if (!expression) {
21
- // HACK: the config is the parent of the project tree.
22
- const config = projectTree.parent;
23
- const usage = await help.call(config);
25
+ const usage = await help();
24
26
  console.log(usage);
25
27
  return;
26
28
  }
@@ -28,9 +30,9 @@ async function main(...args) {
28
30
  // Traverse from the project root to the current directory.
29
31
  const currentDirectory = process.cwd();
30
32
  const relative = path.relative(projectTree.path, currentDirectory);
31
- const tree = await Tree.traversePath(projectTree, relative);
33
+ const parent = await Tree.traversePath(projectTree, relative);
32
34
 
33
- const result = await ori.call(tree, expression);
35
+ const result = await ori(expression, { parent });
34
36
 
35
37
  if (result !== undefined) {
36
38
  const output =
@@ -30,7 +30,7 @@ export default async function documentObject(input, data) {
30
30
  // document to HandleExtensionsTransform set().
31
31
  // const base = {
32
32
  // pack() {
33
- // return txtHandler.pack(this);
33
+ // return txt_handler.pack(this);
34
34
  // },
35
35
  // };
36
36
  // const result = Object.create(base);
@@ -2,5 +2,4 @@
2
2
  export function getDescriptor(object: any): string;
3
3
  export function hasNonPrintableCharacters(text: string): boolean;
4
4
  export function isTransformApplied(Transform: Function, object: any): boolean;
5
- export function toString(object: any): string|null;
6
5
  export function transformObject(Transform: Function, object: any): any;
@@ -1,8 +1,4 @@
1
- import {
2
- toString as asyncTreeToString,
3
- isPlainObject,
4
- trailingSlash,
5
- } from "@weborigami/async-tree";
1
+ import { trailingSlash } from "@weborigami/async-tree";
6
2
  import { symbols } from "@weborigami/language";
7
3
  import { basename } from "node:path";
8
4
 
@@ -50,20 +46,6 @@ export function isTransformApplied(Transform, obj) {
50
46
  return false;
51
47
  }
52
48
 
53
- /**
54
- * Extend the async-tree toString method: objects that have a `_body` property
55
- * will return the value of that property as a string.
56
- *
57
- * @param {any} object
58
- * @returns {string|null}
59
- */
60
- export function toString(object) {
61
- if (isPlainObject(object) && "_body" in object) {
62
- object = object._body;
63
- }
64
- return asyncTreeToString(object);
65
- }
66
-
67
49
  /**
68
50
  * Apply a functional class mixin to an individual object instance.
69
51
  *
@@ -31,8 +31,8 @@ export default function ExplorableSiteTransform(Base) {
31
31
  if (value === undefined) {
32
32
  // The tree doesn't have the key; try the defaults.
33
33
  if (key === "index.html") {
34
- // This tree is both the function call target and the parameter.
35
- value = await indexPage.call(this, this);
34
+ // Generate an index page for this site
35
+ value = await indexPage(this);
36
36
  } else if (key === ".keys.json") {
37
37
  value = await jsonKeys.stringify(this);
38
38
  }
@@ -1,13 +1,16 @@
1
- /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
- import ori from "../origami/ori.js";
1
+ import { scope, trailingSlash } from "@weborigami/async-tree";
2
+ import { projectGlobals } from "@weborigami/language";
3
3
 
4
4
  /**
5
5
  * Add support for commands prefixed with `!`.
6
6
  *
7
- * E.g., asking this tree for `!yaml` will invoke the yaml() builtin function
8
- * in the context of this tree.
7
+ * E.g., asking this tree for `!yaml` will invoke the yaml() builtin function,
8
+ * passing the current tree as the first argument.
9
+ *
10
+ * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
11
+ * @typedef {import("../../index.ts").Constructor<AsyncTree>}
12
+ * AsyncTreeConstructor
9
13
  *
10
- * @typedef {import("../../index.ts").Constructor<AsyncTree>} AsyncTreeConstructor
11
14
  * @param {AsyncTreeConstructor} Base
12
15
  */
13
16
  export default function OriCommandTransform(Base) {
@@ -23,9 +26,24 @@ export default function OriCommandTransform(Base) {
23
26
  ) {
24
27
  return undefined;
25
28
  }
29
+
26
30
  // Key is an Origami command; invoke it.
27
- const source = key.slice(1).trim();
28
- value = await ori.call(this, source, { formatResult: false });
31
+ const globals = await projectGlobals();
32
+ const commandName = trailingSlash.remove(key.slice(1).trim());
33
+
34
+ // Look for command as a global or Dev command
35
+ const command = globals[commandName] ?? globals.Dev?.[commandName];
36
+ if (command) {
37
+ value = await command(this);
38
+ } else {
39
+ // Look for command in scope
40
+ const parentScope = await scope(this);
41
+ value = await parentScope.get(commandName);
42
+ }
43
+
44
+ if (value === undefined) {
45
+ throw new Error(`Unknown Origami command: ${commandName}`);
46
+ }
29
47
  }
30
48
 
31
49
  return value;
@@ -1,55 +1,30 @@
1
1
  /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
- import { Tree } from "@weborigami/async-tree";
3
- import { OrigamiFiles } from "@weborigami/language";
2
+ import { getTreeArgument, Tree } from "@weborigami/async-tree";
3
+ import { Handlers, OrigamiFiles } from "@weborigami/language";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
- import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
7
6
  import { getDescriptor } from "../common/utilities.js";
8
- import { oriHandler } from "../handlers/handlers.js";
9
7
  import debug from "./debug.js";
10
8
 
11
9
  let templatePromise;
12
10
 
13
11
  /**
14
- * @this {AsyncTree|null}
12
+ * Display a debug/explore page for the current tree.
15
13
  */
16
- export default async function explore(...keys) {
17
- assertTreeIsDefined(this, "explore");
18
- if (!this) {
19
- return undefined;
20
- }
14
+ export default async function explore(treelike) {
15
+ const tree = await getTreeArgument(treelike, "explore");
21
16
 
22
- const tree = Tree.from(this);
17
+ // Construct the template page
18
+ const scope = await Tree.scope(tree);
19
+ const data = await getScopeData(scope);
20
+ templatePromise ??= loadTemplate();
21
+ const template = await templatePromise;
22
+ const text = await template(data);
23
23
 
24
+ // If the user navigates inside this page, unpack back to the original tree.
24
25
  /** @type {any} */
25
- let result;
26
- if (keys.length > 0) {
27
- // Traverse the scope using the given keys.
28
- const debugTree = await debug.call(tree, this);
29
- if (!debugTree) {
30
- return undefined;
31
- }
32
- const debugScope = await Tree.scope(debugTree);
33
- // HACK: reproduce logic of ExplorableSiteTransform that turns a trailing
34
- // slash into index.html. Calling `debug` applies that transform and the
35
- // transform should handle that logic, but unfortunately the `traverse`
36
- // operation has special casing to treat a trailing slash, and never gives
37
- // ExplorableSiteTransform a chance.
38
- if (keys.at(-1) === "") {
39
- keys[keys.length - 1] = "index.html";
40
- }
41
- result = await Tree.traverse(debugScope, ...keys);
42
- } else {
43
- // Return the Explore page for the current scope.
44
- const scope = await Tree.scope(tree);
45
- const data = await getScopeData(scope);
46
- templatePromise ??= loadTemplate();
47
- const template = await templatePromise;
48
- const text = await template.call(this, data);
49
-
50
- result = new String(text);
51
- result.unpack = () => debug.call(tree, tree);
52
- }
26
+ const result = new String(text);
27
+ result.unpack = () => debug(tree);
53
28
 
54
29
  return result;
55
30
  }
@@ -71,6 +46,8 @@ async function loadTemplate() {
71
46
  const folderPath = path.resolve(fileURLToPath(import.meta.url), "..");
72
47
  const folder = new OrigamiFiles(folderPath);
73
48
  const templateFile = await folder.get("explore.ori");
74
- const template = await oriHandler.unpack(templateFile, { parent: folder });
49
+ const template = await Handlers.ori_handler.unpack(templateFile, {
50
+ parent: folder,
51
+ });
75
52
  return template;
76
53
  }
package/src/dev/help.yaml CHANGED
@@ -223,7 +223,7 @@ Tree:
223
223
  globKeys:
224
224
  args: (patterns)
225
225
  description: A tree whose keys can include glob wildcard patterns
226
- group:
226
+ groupBy:
227
227
  args: (tree, fn)
228
228
  description: A new tree with values grouped by the function
229
229
  has:
@@ -259,6 +259,9 @@ Tree:
259
259
  map:
260
260
  args: (tree, options)
261
261
  description: Create a new tree by mapping keys and/or values
262
+ mapExtension:
263
+ args: (tree, ext, options)
264
+ description: Map extensions and values
262
265
  mapReduce:
263
266
  args: (tree, mapFn, reduceFn)
264
267
  description: Map values and reduce them
package/src/dev/log.js CHANGED
@@ -8,7 +8,7 @@ import yaml from "../origami/yaml.js";
8
8
  * @param {any} [result]
9
9
  */
10
10
  export default async function log(result, object = result) {
11
- let text = object !== undefined ? await yaml.call(null, object) : "undefined";
11
+ let text = object !== undefined ? await yaml(object) : "undefined";
12
12
  text = text?.trim();
13
13
  console.log(text);
14
14
  return result;
package/src/dev/svg.js CHANGED
@@ -1,5 +1,6 @@
1
+ import { getTreeArgument } from "@weborigami/async-tree";
1
2
  import graphviz from "graphviz-wasm";
2
- import getTreeArgument from "../common/getTreeArgument.js";
3
+
3
4
  import dot from "./treeDot.js";
4
5
 
5
6
  let graphvizLoaded = false;
@@ -11,8 +12,7 @@ let graphvizLoaded = false;
11
12
  * @typedef {import("@weborigami/async-tree").Treelike} Treelike
12
13
  * @typedef {import("@weborigami/async-tree").PlainObject} PlainObject
13
14
  *
14
- * @this {AsyncTree|null}
15
- * @param {Treelike} [treelike]
15
+ * @param {Treelike} treelike
16
16
  * @param {PlainObject} [options]
17
17
  */
18
18
  export default async function svg(treelike, options = {}) {
@@ -20,8 +20,8 @@ export default async function svg(treelike, options = {}) {
20
20
  await graphviz.loadWASM();
21
21
  graphvizLoaded = true;
22
22
  }
23
- const tree = await getTreeArgument(this, arguments, treelike, "svg", true);
24
- const dotText = await dot.call(this, tree, options);
23
+ const tree = await getTreeArgument(treelike, "svg", { deep: true });
24
+ const dotText = await dot(tree, options);
25
25
  if (dotText === undefined) {
26
26
  return undefined;
27
27
  }
@@ -0,0 +1,23 @@
1
+ import { builtins } from "@weborigami/language";
2
+ import * as dev from "./dev/dev.js";
3
+ import help from "./dev/help.js";
4
+ import * as origami from "./origami/origami.js";
5
+
6
+ let initialized = false;
7
+
8
+ /**
9
+ * Pass the Origami builtins to the compiler.
10
+ */
11
+ export default function initializeBuiltins() {
12
+ if (!initialized) {
13
+ const origamiBuiltins = {
14
+ Dev: dev,
15
+ Origami: origami,
16
+ "help:": help,
17
+ };
18
+
19
+ Object.assign(builtins, origamiBuiltins);
20
+ }
21
+
22
+ initialized = true;
23
+ }
@@ -1,7 +1,8 @@
1
- import { getHandlers, handleExtension } from "@weborigami/language";
1
+ import { handleExtension } from "@weborigami/language";
2
2
 
3
3
  /**
4
- * @this {import("@weborigami/types").AsyncTree|null|undefined}
4
+ * Extend the JavaScript `fetch` function to implicity return an ArrayBuffer
5
+ * with an unpack() method if the resource has a known file extension.
5
6
  */
6
7
  export default async function fetchBuiltin(resource, options) {
7
8
  const response = await fetch(resource, options);
@@ -10,13 +11,8 @@ export default async function fetchBuiltin(resource, options) {
10
11
  }
11
12
 
12
13
  const value = await response.arrayBuffer();
13
- if (!this) {
14
- // Can't get extension handlers
15
- return value;
16
- }
17
14
 
18
- const handlers = getHandlers(this);
19
15
  const url = new URL(resource);
20
16
  const key = url.pathname;
21
- return handleExtension(this, value, key, handlers);
17
+ return handleExtension(value, key);
22
18
  }
@@ -1,4 +1,4 @@
1
- import getTreeArgument from "../common/getTreeArgument.js";
1
+ import { getTreeArgument } from "@weborigami/async-tree";
2
2
  import { getDescriptor } from "../common/utilities.js";
3
3
 
4
4
  /**
@@ -6,12 +6,12 @@ import { getDescriptor } from "../common/utilities.js";
6
6
  *
7
7
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
8
8
  * @typedef {import("@weborigami/async-tree").Treelike} Treelike
9
- * @this {AsyncTree|null}
10
- * @param {Treelike} [treelike]
9
+ *
10
+ * @param {Treelike} treelike
11
11
  * @param {string} [basePath]
12
12
  */
13
13
  export default async function indexPage(treelike, basePath) {
14
- const tree = await getTreeArgument(this, arguments, treelike, "indexPage");
14
+ const tree = await getTreeArgument(treelike, "svg");
15
15
  const keys = Array.from(await tree.keys());
16
16
 
17
17
  // Skip system-ish files that start with a period. Also skip `index.html`.
@@ -1,15 +1,14 @@
1
1
  import { isUnpackable, symbols, toString } from "@weborigami/async-tree";
2
+ import { oridocument_handler } from "@weborigami/language/src/handlers/handlers.js";
2
3
  import documentObject from "../common/documentObject.js";
3
- import { oridocumentHandler } from "../handlers/handlers.js";
4
4
 
5
5
  /**
6
6
  * Inline any Origami expressions found inside ${...} placeholders in the input
7
7
  * text.
8
8
  *
9
9
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
10
- * @typedef {import("@weborigami/async-tree").Stringlike} Stringlike
11
10
  *
12
- * @param {Stringlike & {_body?: Stringlike}} input
11
+ * @param {any} input
13
12
  */
14
13
  export default async function inline(input) {
15
14
  // Get the input text and any attached front matter.
@@ -37,7 +36,7 @@ export default async function inline(input) {
37
36
  }
38
37
 
39
38
  // @ts-ignore
40
- let result = await oridocumentHandler.unpack(origami, {
39
+ let result = await oridocument_handler.unpack(origami, {
41
40
  front,
42
41
  parent,
43
42
  });
@@ -1,4 +1,4 @@
1
- import { toString } from "../common/utilities.js";
1
+ import { toString } from "@weborigami/async-tree";
2
2
 
3
3
  export default async function jsonParse(input) {
4
4
  const text = toString(input);
@@ -1,11 +1,10 @@
1
- import { extension, isUnpackable } from "@weborigami/async-tree";
1
+ import { extension, isUnpackable, toString } 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 { toString } from "../common/utilities.js";
9
8
  import origamiHighlightDefinition from "./origamiHighlightDefinition.js";
10
9
 
11
10
  highlight.registerLanguage("ori", origamiHighlightDefinition);
@@ -32,10 +31,7 @@ marked.use(
32
31
  /**
33
32
  * Transform markdown to HTML.
34
33
  *
35
- * @typedef {import("@weborigami/async-tree").Stringlike} Stringlike
36
- * @typedef {import("@weborigami/async-tree").Unpackable} Unpackable
37
- *
38
- * @param {Stringlike|Unpackable} input
34
+ * @param {any} input
39
35
  */
40
36
  export default async function mdHtml(input) {
41
37
  if (input == null) {
@@ -47,7 +43,7 @@ export default async function mdHtml(input) {
47
43
  input = await input.unpack();
48
44
  }
49
45
  const inputIsDocument = typeof input === "object" && "_body" in input;
50
- const markdown = toString(input);
46
+ const markdown = inputIsDocument ? input._body : toString(input);
51
47
  if (markdown === null) {
52
48
  throw new Error("mdHtml: The provided input couldn't be treated as text.");
53
49
  }
@@ -1,12 +1,12 @@
1
- import { isUnpackable } from "@weborigami/async-tree";
1
+ import { isUnpackable, toString } from "@weborigami/async-tree";
2
2
  import { Marked } from "marked";
3
- import { toString } from "../common/utilities.js";
4
3
 
5
4
  export default async function mdOutline(input) {
6
5
  if (isUnpackable(input)) {
7
6
  input = await input.unpack();
8
7
  }
9
- const markdown = toString(input);
8
+ const inputIsDocument = typeof input === "object" && "_body" in input;
9
+ const markdown = inputIsDocument ? input._body : toString(input);
10
10
  if (markdown === null) {
11
11
  throw new Error("mdHtml: The provided input couldn't be treated as text.");
12
12
  }
@@ -5,10 +5,9 @@ import {
5
5
  toString,
6
6
  } from "@weborigami/async-tree";
7
7
  import { compile } from "@weborigami/language";
8
- import builtinsShell from "../builtinsShell.js";
9
- import getConfig from "../cli/getConfig.js";
10
- import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
8
+ import projectGlobals from "@weborigami/language/src/project/projectGlobals.js";
11
9
  import { toYaml } from "../common/serialize.js";
10
+ import * as dev from "../dev/dev.js";
12
11
 
13
12
  const TypedArray = Object.getPrototypeOf(Uint8Array);
14
13
 
@@ -18,14 +17,11 @@ const TypedArray = Object.getPrototypeOf(Uint8Array);
18
17
  *
19
18
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
20
19
  *
21
- * @this {AsyncTree|null}
22
20
  * @param {string} expression
23
21
  */
24
- export default async function ori(
25
- expression,
26
- options = { formatResult: true }
27
- ) {
28
- assertTreeIsDefined(this, "ori");
22
+ export default async function ori(expression, options = {}) {
23
+ const parent = options.parent ?? null;
24
+ const formatResult = options.formatResult ?? true;
29
25
 
30
26
  // In case expression has come from a file, cast it to a string.
31
27
  if (!isStringlike(expression)) {
@@ -34,38 +30,34 @@ export default async function ori(
34
30
  // @ts-ignore
35
31
  expression = toString(expression);
36
32
 
37
- // Run in the context of `this` if defined
38
- const tree = this;
39
-
40
- const config = getConfig(tree);
41
- const globals = config
42
- ? {
43
- ...builtinsShell(),
44
- ...config,
45
- }
46
- : builtinsShell();
33
+ // Add Dev builtins as top-level globals
34
+ const globals = {
35
+ ...(await projectGlobals()),
36
+ ...dev,
37
+ };
47
38
 
48
39
  // Compile the expression. Avoid caching scope references so that, e.g.,
49
40
  // passing a function to the `watch` builtin will always look the current
50
41
  // value of things in scope.
51
42
  const fn = compile.expression(expression, {
52
43
  globals,
53
- mode: "shell",
54
44
  enableCaching: false,
45
+ mode: "shell",
46
+ parent,
55
47
  });
56
48
 
57
49
  // Execute
58
- let result = await fn.call(tree);
50
+ let result = await fn();
59
51
 
60
52
  // If result was a function, execute it.
61
53
  if (typeof result === "function") {
62
- result = await result.call(tree);
54
+ result = await result();
63
55
  }
64
56
 
65
- return options.formatResult ? await formatResult(result) : result;
57
+ return formatResult ? await format(result) : result;
66
58
  }
67
59
 
68
- async function formatResult(result) {
60
+ async function format(result) {
69
61
  if (
70
62
  typeof result === "string" ||
71
63
  result instanceof ArrayBuffer ||
@@ -12,7 +12,6 @@ export { default as sitemap } from "../origami/sitemap.js";
12
12
  export { default as slug } from "../origami/slug.js";
13
13
  export { default as static } from "../origami/static.js";
14
14
  export { default as basename } from "./basename.js";
15
- export { default as config } from "./config.js";
16
15
  export { default as csv } from "./csv.js";
17
16
  export { default as fetch } from "./fetch.js";
18
17
  export { default as format } from "./image/format.js";
@@ -26,7 +25,6 @@ export { default as once } from "./once.js";
26
25
  export { default as ori } from "./ori.js";
27
26
  export { default as pack } from "./pack.js";
28
27
  export { default as post } from "./post.js";
29
- export { default as project } from "./project.js";
30
28
  export { default as repeat } from "./repeat.js";
31
29
  export { default as shell } from "./shell.js";
32
30
  export { default as slash } from "./slash.js";
@@ -1,5 +1,5 @@
1
1
  import { getTreeArgument, Tree } from "@weborigami/async-tree";
2
- import { oriHandler } from "../handlers/handlers.js";
2
+ import { ori_handler } from "@weborigami/language/src/handlers/handlers.js";
3
3
 
4
4
  const templateText = `(urls) => \`<?xml version="1.0" encoding="UTF-8"?>
5
5
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@@ -45,7 +45,7 @@ export default async function sitemap(treelike, options = {}) {
45
45
  .filter((path) => path.endsWith(".html"))
46
46
  .map((path) => (path.endsWith("index.html") ? path.slice(0, -10) : path));
47
47
 
48
- const templateFn = await oriHandler.unpack(templateText);
48
+ const templateFn = await ori_handler.unpack(templateText);
49
49
  const templateResult = await templateFn(htmlPaths);
50
50
  return String(templateResult);
51
51
  }
@@ -1,5 +1,5 @@
1
1
  import { Tree, getTreeArgument, jsonKeys } from "@weborigami/async-tree";
2
- import index from "./indexPage.js";
2
+ import indexPage from "./indexPage.js";
3
3
 
4
4
  /**
5
5
  * Expose common static keys (index.html, .keys.json) for a tree.
@@ -23,7 +23,7 @@ function staticTree(tree) {
23
23
  async get(key) {
24
24
  let value = await tree.get(key);
25
25
  if (value === undefined && key === "index.html") {
26
- value = await index.call(this, this);
26
+ value = await indexPage(this);
27
27
  } else if (value === undefined && key === ".keys.json") {
28
28
  value = await jsonKeys.stringify(this);
29
29
  } else if (Tree.isTreelike(value)) {
@@ -1,10 +1 @@
1
- import { toString } from "../common/utilities.js";
2
-
3
- /**
4
- * Convert an object to a string.
5
- *
6
- * @param {any} object
7
- */
8
- export default function stringBuiltin(object) {
9
- return toString(object);
10
- }
1
+ export { toString as default } from "@weborigami/async-tree";