@weborigami/origami 0.0.46 → 0.0.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/exports/buildExports.js +2 -2
  2. package/exports/exports.js +16 -16
  3. package/package.json +11 -13
  4. package/src/builtins/@config.js +12 -5
  5. package/src/builtins/@crawl.js +3 -3
  6. package/src/builtins/@debug.js +9 -2
  7. package/src/builtins/@document.js +3 -5
  8. package/src/builtins/@fnTree.js +5 -2
  9. package/src/builtins/@inline.js +18 -25
  10. package/src/builtins/@inners.js +1 -3
  11. package/src/builtins/@invoke.js +2 -1
  12. package/src/builtins/@json.js +0 -3
  13. package/src/builtins/@keysJson.js +1 -4
  14. package/src/builtins/@mdHtml.js +8 -8
  15. package/src/builtins/@project.js +22 -14
  16. package/src/builtins/@shuffle.js +1 -6
  17. package/src/builtins/@sitemap.js +2 -2
  18. package/src/builtins/@sort.js +1 -4
  19. package/src/builtins/@static.js +1 -3
  20. package/src/builtins/@tree.js +1 -4
  21. package/src/builtins/@yaml.js +0 -3
  22. package/src/builtins/css_handler.js +7 -0
  23. package/src/builtins/htm_handler.js +2 -0
  24. package/src/builtins/html_handler.js +7 -0
  25. package/src/builtins/jpeg_handler.js +58 -0
  26. package/src/builtins/jpg_handler.js +2 -0
  27. package/src/builtins/js_handler.js +20 -0
  28. package/src/builtins/json_handler.js +19 -0
  29. package/src/builtins/md_handler.js +7 -0
  30. package/src/builtins/mjs_handler.js +2 -0
  31. package/src/builtins/ori_handler.js +48 -0
  32. package/src/builtins/txt_handler.js +78 -0
  33. package/src/builtins/wasm_handler.js +17 -0
  34. package/src/builtins/xhtml_handler.js +2 -0
  35. package/src/builtins/yaml_handler.js +29 -0
  36. package/src/builtins/yml_handler.js +2 -0
  37. package/src/common/ExplorableSiteTransform.js +5 -1
  38. package/src/common/addValueKeyToScope.js +3 -2
  39. package/src/common/documentObject.js +33 -0
  40. package/src/common/serialize.d.ts +1 -0
  41. package/src/common/serialize.js +68 -27
  42. package/src/common/utilities.js +9 -7
  43. package/src/misc/getTreeArgument.js +12 -2
  44. package/src/server/constructResponse.js +18 -5
  45. package/src/server/server.js +5 -4
  46. package/src/builtins/@loaders/css.js +0 -2
  47. package/src/builtins/@loaders/htm.js +0 -2
  48. package/src/builtins/@loaders/html.js +0 -2
  49. package/src/builtins/@loaders/jpeg.js +0 -55
  50. package/src/builtins/@loaders/jpg.js +0 -2
  51. package/src/builtins/@loaders/js.js +0 -14
  52. package/src/builtins/@loaders/json.js +0 -14
  53. package/src/builtins/@loaders/md.js +0 -2
  54. package/src/builtins/@loaders/mjs.js +0 -2
  55. package/src/builtins/@loaders/ori.js +0 -45
  56. package/src/builtins/@loaders/txt.js +0 -37
  57. package/src/builtins/@loaders/wasm.js +0 -11
  58. package/src/builtins/@loaders/xhtml.js +0 -2
  59. package/src/builtins/@loaders/yaml.js +0 -23
  60. package/src/builtins/@loaders/yml.js +0 -2
  61. package/src/common/TextDocument.js +0 -58
@@ -1,6 +1,6 @@
1
1
  /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
2
  import { keyFunctionsForExtensions, map } from "@weborigami/async-tree";
3
- import unpackOrigamiTemplate from "../src/builtins/@loaders/ori.js";
3
+ import fileTypeOrigami from "../src/builtins/ori_handler.js";
4
4
  import { transformObject } from "../src/common/utilities.js";
5
5
  import PathTransform from "./PathTransform.js";
6
6
 
@@ -22,7 +22,7 @@ const templateText = `=\`// This file is generated by running buildExports.js --
22
22
  // file's export(s) in the top-level export file.
23
23
  export default async function exportFile(src) {
24
24
  const statements = await exportStatements(src);
25
- const templateFn = await unpackOrigamiTemplate(templateText);
25
+ const templateFn = await fileTypeOrigami.unpack(templateText);
26
26
  const result = await templateFn(statements);
27
27
  return result;
28
28
  }
@@ -38,21 +38,6 @@ export { default as js } from "../src/builtins/@js.js";
38
38
  export { default as json } from "../src/builtins/@json.js";
39
39
  export { default as keys } from "../src/builtins/@keys.js";
40
40
  export { default as keysJson } from "../src/builtins/@keysJson.js";
41
- export { default as loadersCss } from "../src/builtins/@loaders/css.js";
42
- export { default as loadersHtm } from "../src/builtins/@loaders/htm.js";
43
- export { default as loadersHtml } from "../src/builtins/@loaders/html.js";
44
- export { default as loadersJpeg } from "../src/builtins/@loaders/jpeg.js";
45
- export { default as loadersJpg } from "../src/builtins/@loaders/jpg.js";
46
- export { default as loadersJs } from "../src/builtins/@loaders/js.js";
47
- export { default as loadersJson } from "../src/builtins/@loaders/json.js";
48
- export { default as loadersMd } from "../src/builtins/@loaders/md.js";
49
- export { default as loadersMjs } from "../src/builtins/@loaders/mjs.js";
50
- export { default as loadersOri } from "../src/builtins/@loaders/ori.js";
51
- export { default as loadersTxt } from "../src/builtins/@loaders/txt.js";
52
- export { default as loadersWasm } from "../src/builtins/@loaders/wasm.js";
53
- export { default as loadersXhtml } from "../src/builtins/@loaders/xhtml.js";
54
- export { default as loadersYaml } from "../src/builtins/@loaders/yaml.js";
55
- export { default as loadersYml } from "../src/builtins/@loaders/yml.js";
56
41
  export { default as map } from "../src/builtins/@map.js";
57
42
  export { default as mapDeep } from "../src/builtins/@mapDeep.js";
58
43
  export { default as match } from "../src/builtins/@match.js";
@@ -104,19 +89,34 @@ export { default as watch } from "../src/builtins/@watch.js";
104
89
  export { default as with } from "../src/builtins/@with.js";
105
90
  export { default as yaml } from "../src/builtins/@yaml.js";
106
91
  export { default as homeFiles } from "../src/builtins/~.js";
92
+ export { default as csshandler } from "../src/builtins/css_handler.js";
93
+ export { default as htmhandler } from "../src/builtins/htm_handler.js";
94
+ export { default as htmlhandler } from "../src/builtins/html_handler.js";
95
+ export { default as jpeghandler } from "../src/builtins/jpeg_handler.js";
96
+ export { default as jpghandler } from "../src/builtins/jpg_handler.js";
97
+ export { default as jshandler } from "../src/builtins/js_handler.js";
98
+ export { default as jsonhandler } from "../src/builtins/json_handler.js";
99
+ export { default as mdhandler } from "../src/builtins/md_handler.js";
100
+ export { default as mjshandler } from "../src/builtins/mjs_handler.js";
101
+ export { default as orihandler } from "../src/builtins/ori_handler.js";
102
+ export { default as txthandler } from "../src/builtins/txt_handler.js";
103
+ export { default as wasmhandler } from "../src/builtins/wasm_handler.js";
104
+ export { default as xhtmlhandler } from "../src/builtins/xhtml_handler.js";
105
+ export { default as yamlhandler } from "../src/builtins/yaml_handler.js";
106
+ export { default as ymlhandler } from "../src/builtins/yml_handler.js";
107
107
  export { default as defaultModuleExport } from "../src/cli/defaultModuleExport.js";
108
108
  export { default as showUsage } from "../src/cli/showUsage.js";
109
109
  export { default as addValueKeyToScope } from "../src/common/addValueKeyToScope.js";
110
110
  export { default as arrowFunctionsMap } from "../src/common/arrowFunctionsMap.js";
111
111
  export { default as CommandModulesTransform } from "../src/common/CommandModulesTransform.js";
112
112
  export { default as ConstantTree } from "../src/common/ConstantTree.js";
113
+ export { default as documentObject } from "../src/common/documentObject.js";
113
114
  export { default as ExplorableSiteTransform } from "../src/common/ExplorableSiteTransform.js";
114
115
  export { default as FilterTree } from "../src/common/FilterTree.js";
115
116
  export { default as GlobTree } from "../src/common/GlobTree.js";
116
117
  export { default as processUnpackedContent } from "../src/common/processUnpackedContent.js";
117
118
  export * from "../src/common/serialize.js";
118
119
  export { default as ShuffleTransform } from "../src/common/ShuffleTransform.js";
119
- export { default as TextDocument } from "../src/common/TextDocument.js";
120
120
  export * from "../src/common/utilities.js";
121
121
  export { default as assertScopeIsDefined } from "../src/misc/assertScopeIsDefined.js";
122
122
  export { default as getTreeArgument } from "../src/misc/getTreeArgument.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/origami",
3
- "version": "0.0.46",
3
+ "version": "0.0.47",
4
4
  "description": "Web Origami language, CLI, framework, and server",
5
5
  "type": "module",
6
6
  "repository": {
@@ -13,24 +13,22 @@
13
13
  "main": "./exports/exports.js",
14
14
  "types": "./index.ts",
15
15
  "devDependencies": {
16
- "@types/chai": "4.3.11",
17
- "@types/mocha": "10.0.6",
18
- "@types/node": "20.11.7",
19
- "typescript": "5.3.3"
16
+ "@types/node": "20.11.27",
17
+ "typescript": "5.4.2"
20
18
  },
21
19
  "dependencies": {
22
- "@weborigami/async-tree": "0.0.46",
23
- "@weborigami/language": "0.0.46",
24
- "@weborigami/types": "0.0.46",
20
+ "@weborigami/async-tree": "0.0.47",
21
+ "@weborigami/language": "0.0.47",
22
+ "@weborigami/types": "0.0.47",
25
23
  "exif-parser": "0.1.12",
26
24
  "graphviz-wasm": "3.0.1",
27
25
  "highlight.js": "11.9.0",
28
- "marked": "11.1.1",
29
- "marked-gfm-heading-id": "3.1.2",
30
- "marked-highlight": "2.1.0",
31
- "marked-smartypants": "1.1.5",
26
+ "marked": "12.0.1",
27
+ "marked-gfm-heading-id": "3.1.3",
28
+ "marked-highlight": "2.1.1",
29
+ "marked-smartypants": "1.1.6",
32
30
  "sharp": "0.33.2",
33
- "yaml": "2.3.4"
31
+ "yaml": "2.4.1"
34
32
  },
35
33
  "scripts": {
36
34
  "build": "ori exports/buildExports.js src > exports/exports.js",
@@ -1,11 +1,11 @@
1
+ import { Scope } from "@weborigami/language";
1
2
  import project from "./@project.js";
2
3
 
3
4
  /**
4
5
  * Return the configuration for the current project.
5
6
  *
6
- * If the project's root defines an ori.config.js file, the configuration is
7
- * the default export of that file. Otherwise, the configuration is the set of
8
- * built-in functions.
7
+ * The configuration is the project's config.ori file (if defined in the project
8
+ * root) plus the Origami builtins.
9
9
  *
10
10
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
11
11
  *
@@ -14,10 +14,17 @@ import project from "./@project.js";
14
14
  */
15
15
  export default async function config(key) {
16
16
  const projectTree = await project.call(this);
17
- const scope = projectTree?.parent;
18
- if (!scope) {
17
+ // HACK: We use specific knowledge of how @project returns a tree to get the
18
+ // config. We get the scope of the project's root folder, then remove that
19
+ // folder from the scope, leaving config + builtins.
20
+ /** @type {any} */
21
+ const projectTreeScope = Scope.getScope(projectTree);
22
+ const trees = projectTreeScope?.trees;
23
+ if (!trees) {
19
24
  return undefined;
20
25
  }
26
+ trees.shift();
27
+ const scope = new Scope(...trees);
21
28
  return key === undefined ? scope : scope.get(key);
22
29
  }
23
30
 
@@ -1,5 +1,5 @@
1
1
  import {
2
- ObjectTree,
2
+ DeepObjectTree,
3
3
  Tree,
4
4
  isPlainObject,
5
5
  keysFromPath,
@@ -94,8 +94,8 @@ export default async function crawl(treelike, baseHref) {
94
94
  // value.
95
95
  /** @type {AsyncTree} */
96
96
  let result = mergeDeep(
97
- new ObjectTree(cache),
98
- new (InvokeFunctionsTransform(ObjectTree))(resources)
97
+ new DeepObjectTree(cache),
98
+ new (InvokeFunctionsTransform(DeepObjectTree))(resources)
99
99
  );
100
100
  result = Scope.treeWithScope(result, this);
101
101
  return result;
@@ -1,4 +1,5 @@
1
1
  import { Tree, isPlainObject } from "@weborigami/async-tree";
2
+ import { Scope } from "@weborigami/language";
2
3
  import ExplorableSiteTransform from "../common/ExplorableSiteTransform.js";
3
4
  import { isTransformApplied, transformObject } from "../common/utilities.js";
4
5
  import OriCommandTransform from "../misc/OriCommandTransform.js";
@@ -54,12 +55,18 @@ function DebugTransform(Base) {
54
55
  const original = value.unpack.bind(value);
55
56
  value.unpack = async () => {
56
57
  let content = await original();
57
- if (!Tree.isTreelike(content)) {
58
+ if (!Tree.isTraversable(content)) {
58
59
  return content;
59
60
  }
60
61
  /** @type {any} */
61
62
  let tree = Tree.from(content);
62
- tree = transformObject(ExplorableSiteTransform, tree);
63
+ if (!tree.parent && !tree.scope) {
64
+ const scope = Scope.getScope(this);
65
+ tree = Scope.treeWithScope(tree, scope);
66
+ }
67
+ if (!isTransformApplied(ExplorableSiteTransform, tree)) {
68
+ tree = transformObject(ExplorableSiteTransform, tree);
69
+ }
63
70
  tree = transformObject(DebugTransform, tree);
64
71
  return tree;
65
72
  };
@@ -1,4 +1,4 @@
1
- import TextDocument from "../common/TextDocument.js";
1
+ import documentObject from "../common/documentObject.js";
2
2
  import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
3
3
 
4
4
  /**
@@ -8,11 +8,9 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
8
8
  * @this {AsyncTree|null}
9
9
  * @param {StringLike} text
10
10
  * @param {any} [data]
11
- * @param {AsyncTree|null} [parent]
12
11
  * @returns
13
12
  */
14
- export default function document(text, data, parent) {
13
+ export default function documentBuiltin(text, data) {
15
14
  assertScopeIsDefined(this, "document");
16
- const merged = Object.assign({}, data, { "@text": text });
17
- return new TextDocument(merged, parent ?? this);
15
+ return documentObject(text, data);
18
16
  }
@@ -1,4 +1,4 @@
1
- import { FunctionTree } from "@weborigami/async-tree";
1
+ import { FunctionTree, ObjectTree } from "@weborigami/async-tree";
2
2
  import { Scope } from "@weborigami/language";
3
3
  import { toFunction } from "../common/utilities.js";
4
4
  import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
@@ -29,7 +29,10 @@ export default async function fnTree(invocable, keys = []) {
29
29
 
30
30
  /** @this {AsyncTree|null} */
31
31
  async function extendedFn(key) {
32
- const ambientsTree = Scope.treeWithScope({ "@key": key }, this);
32
+ const ambientsTree = Scope.treeWithScope(
33
+ new ObjectTree({ "@key": key }),
34
+ this
35
+ );
33
36
  return invocableFn.call(ambientsTree, key);
34
37
  }
35
38
 
@@ -1,8 +1,9 @@
1
- import { Tree, isPlainObject } from "@weborigami/async-tree";
1
+ import { isUnpackable, symbols } from "@weborigami/async-tree";
2
2
  import { compile } from "@weborigami/language";
3
- import unpackText from "../builtins/@loaders/txt.js";
3
+ import documentObject from "../common/documentObject.js";
4
+ import { toString } from "../common/utilities.js";
4
5
  import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
5
- import unpackOrigamiExpression from "./@loaders/ori.js";
6
+ import fileTypeOrigami from "./ori_handler.js";
6
7
 
7
8
  /**
8
9
  * Inline any Origami expressions found inside ${...} placeholders in the input
@@ -18,33 +19,25 @@ export default async function inline(input) {
18
19
  assertScopeIsDefined(this, "inline");
19
20
 
20
21
  // Get the input text and any attached front matter.
21
- let inputDocument;
22
- if (input["@text"]) {
23
- inputDocument = input;
24
- } else if (/** @type {any} */ (input).unpack) {
25
- // Have the input unpack itself.
26
- inputDocument = await /** @type {any} */ (input).unpack();
27
- } else {
28
- // Unpack the input as a text document with possible front matter.
29
- inputDocument = await unpackText(input);
22
+ if (isUnpackable(input)) {
23
+ input = await input.unpack();
30
24
  }
25
+ const inputIsDocument = input["@text"] !== undefined;
26
+ const origami = inputIsDocument ? input["@text"] : toString(input);
27
+ const parent = input.parent ?? input[symbols.parent];
31
28
 
32
- // If the input document is a plain object or AsyncTree, we'll have it
33
- // included in scope for the evaluated expression. We ignore other kinds of
34
- // treelike inputs for this test: in particular, a Buffer will be interpreted
35
- // as a tree, but we don't want to put a Buffer in scope.
36
- const attachedData =
37
- isPlainObject(inputDocument) || Tree.isAsyncTree(inputDocument)
38
- ? inputDocument
39
- : null;
29
+ // If the input document is a plain object, include it in scope for the
30
+ // evaluated expression.
31
+ const inputData = inputIsDocument ? input : null;
40
32
 
41
- const templateFn = await unpackOrigamiExpression(inputDocument, {
42
- attachedData,
33
+ const templateFn = await fileTypeOrigami.unpack(origami, {
34
+ attachedData: inputData,
43
35
  compiler: compile.templateDocument,
36
+ parent,
44
37
  });
45
- const templateResult = await templateFn(inputDocument);
46
- return inputDocument
47
- ? Object.assign({}, inputDocument, { "@text": String(templateResult) })
38
+ const templateResult = await templateFn(inputData);
39
+ return inputIsDocument
40
+ ? documentObject(templateResult, inputData)
48
41
  : templateResult;
49
42
  }
50
43
 
@@ -1,5 +1,4 @@
1
1
  import { Tree } from "@weborigami/async-tree";
2
- import { Scope } from "@weborigami/language";
3
2
  import getTreeArgument from "../misc/getTreeArgument.js";
4
3
 
5
4
  /**
@@ -14,7 +13,7 @@ export default async function inners(treelike) {
14
13
  const tree = await getTreeArgument(this, arguments, treelike, "@inners");
15
14
 
16
15
  /** @type {AsyncTree} */
17
- let result = {
16
+ const result = {
18
17
  async get(key) {
19
18
  const value = await tree.get(key);
20
19
  return Tree.isAsyncTree(value) ? inners.call(this, value) : undefined;
@@ -31,7 +30,6 @@ export default async function inners(treelike) {
31
30
  },
32
31
  };
33
32
 
34
- result = Scope.treeWithScope(result, this);
35
33
  return result;
36
34
  }
37
35
 
@@ -1,3 +1,4 @@
1
+ import { isUnpackable } from "@weborigami/async-tree";
1
2
  import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
2
3
  import builtins from "./@builtins.js";
3
4
 
@@ -30,7 +31,7 @@ export default async function invoke(fn) {
30
31
  "An Origami function was called with an initial argument, but its value is undefined."
31
32
  );
32
33
  }
33
- if (typeof fn !== "function" && fn.unpack) {
34
+ if (isUnpackable(fn)) {
34
35
  fn = await fn.unpack();
35
36
  }
36
37
  const scope = (await this?.get("@current")) ?? builtins;
@@ -20,9 +20,6 @@ export default async function json(obj) {
20
20
  if (obj === undefined) {
21
21
  return undefined;
22
22
  }
23
- if (typeof obj.unpack === "function") {
24
- obj = await obj.unpack();
25
- }
26
23
  const value = await serialize.toJsonValue(obj);
27
24
  return JSON.stringify(value, null, 2);
28
25
  }
@@ -1,5 +1,4 @@
1
1
  import { Tree, keysJson } from "@weborigami/async-tree";
2
- import { Scope } from "@weborigami/language";
3
2
  import { transformObject } from "../common/utilities.js";
4
3
  import getTreeArgument from "../misc/getTreeArgument.js";
5
4
 
@@ -13,9 +12,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
13
12
  */
14
13
  export default async function treeKeysJson(treelike) {
15
14
  const tree = await getTreeArgument(this, arguments, treelike, "@keysJson");
16
- let result = transformObject(KeysJsonTransform, tree);
17
- result = Scope.treeWithScope(result, this);
18
- return result;
15
+ return transformObject(KeysJsonTransform, tree);
19
16
  }
20
17
 
21
18
  function KeysJsonTransform(Base) {
@@ -1,9 +1,11 @@
1
+ import { isUnpackable } from "@weborigami/async-tree";
1
2
  import highlight from "highlight.js";
2
3
  import { marked } from "marked";
3
4
  import { gfmHeadingId as markedGfmHeadingId } from "marked-gfm-heading-id";
4
5
  import { markedHighlight } from "marked-highlight";
5
6
  import { markedSmartypants } from "marked-smartypants";
6
- import { replaceExtension } from "../common/utilities.js";
7
+ import documentObject from "../common/documentObject.js";
8
+ import { replaceExtension, toString } from "../common/utilities.js";
7
9
 
8
10
  marked.use(
9
11
  markedGfmHeadingId(),
@@ -31,15 +33,13 @@ marked.use(
31
33
  * @param {StringLike|UnpackableStringlike} input
32
34
  */
33
35
  export default async function mdHtml(input) {
34
- if (/** @type {any} */ (input).unpack) {
35
- input = await /** @type {any} */ (input).unpack();
36
+ if (isUnpackable(input)) {
37
+ input = await input.unpack();
36
38
  }
37
- const inputDocument = input["@text"] ? input : null;
38
- const markdown = inputDocument?.["@text"] ?? String(input);
39
+ const inputIsDocument = input["@text"] !== undefined;
40
+ const markdown = inputIsDocument ? input["@text"] : toString(input);
39
41
  const html = marked(markdown);
40
- return inputDocument
41
- ? Object.assign({}, inputDocument, { "@text": html })
42
- : html;
42
+ return inputIsDocument ? documentObject(html, input) : html;
43
43
  }
44
44
 
45
45
  mdHtml.key = (sourceKey) => replaceExtension(sourceKey, ".md", ".html");
@@ -2,17 +2,18 @@
2
2
  import { OrigamiFiles, Scope } from "@weborigami/language";
3
3
  import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
4
4
  import builtins from "./@builtins.js";
5
+ import fileTypeOrigami from "./ori_handler.js";
5
6
 
6
- const configFileName = "ori.config.js";
7
+ const configFileName = "config.ori";
7
8
 
8
9
  /**
9
10
  * Return the tree for the current project's root folder.
10
11
  *
11
- * This searches the current directory and its ancestors for an Origami
12
- * configuration file. If an Origami configuration file is found, the containing
13
- * folder is considered to be the project root. This returns a tree for that
14
- * folder, with the exported configuration as the context for that folder — that
15
- * is, the tree exported by the configuration will be the scope.
12
+ * This searches the current directory and its ancestors for an Origami file
13
+ * called `config.ori`. If an Origami configuration file is found, the
14
+ * containing folder is considered to be the project root. This returns a tree
15
+ * for that folder, with the exported configuration as the context for that
16
+ * folder — that is, the tree exported by the configuration will be the scope.
16
17
  *
17
18
  * If no Origami configuration file is found, the current folder will be
18
19
  * returned as a tree, with the builtins as its parent.
@@ -25,24 +26,31 @@ export default async function project(key) {
25
26
 
26
27
  const dirname = process.cwd();
27
28
  const currentTree = new OrigamiFiles(dirname);
28
- let projectTree = await findConfigContainer(currentTree);
29
+ let containerTree = await findConfigContainer(currentTree);
29
30
 
30
31
  let config;
31
- if (projectTree) {
32
+ if (containerTree) {
32
33
  // Load the configuration.
33
- config = await projectTree.import(configFileName);
34
+ const configParent = Scope.treeWithScope(containerTree, builtins);
35
+ const buffer = await configParent.get(configFileName);
36
+ config = await fileTypeOrigami.unpack(buffer, {
37
+ key: configFileName,
38
+ parent: configParent,
39
+ });
34
40
  if (!config) {
41
+ const configPath = /** @type {any} */ (configParent).path;
35
42
  throw new Error(
36
- `Couldn't load the Origami configuration in ${projectTree.path}`
43
+ `Couldn't load the Origami configuration in ${configPath}/${configFileName}`
37
44
  );
38
45
  }
39
46
  } else {
40
- projectTree = currentTree;
41
- config = builtins;
47
+ containerTree = currentTree;
48
+ config = null;
42
49
  }
43
50
 
44
51
  // Add the configuration as the context for the project root.
45
- const result = Scope.treeWithScope(projectTree, config);
52
+ const scope = new Scope(config, builtins);
53
+ const result = Scope.treeWithScope(containerTree, scope);
46
54
  return key === undefined ? result : result.get(key);
47
55
  }
48
56
 
@@ -67,5 +75,5 @@ async function findConfigContainer(start) {
67
75
  return undefined;
68
76
  }
69
77
 
70
- project.usage = `@project\tThe root of the current Tree Origami project`;
78
+ project.usage = `@project\tThe root of the current Origami project`;
71
79
  project.documentation = "https://weborigami.org/language/@project.html";
@@ -1,4 +1,3 @@
1
- import { Scope } from "@weborigami/language";
2
1
  import ShuffleTransform from "../common/ShuffleTransform.js";
3
2
  import { transformObject } from "../common/utilities.js";
4
3
  import getTreeArgument from "../misc/getTreeArgument.js";
@@ -14,11 +13,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
14
13
  */
15
14
  export default async function shuffle(treelike) {
16
15
  const tree = await getTreeArgument(this, arguments, treelike, "@shuffle");
17
-
18
- /** @type {AsyncTree} */
19
- let shuffled = transformObject(ShuffleTransform, tree);
20
- shuffled = Scope.treeWithScope(shuffled, this);
21
- return shuffled;
16
+ return transformObject(ShuffleTransform, tree);
22
17
  }
23
18
 
24
19
  shuffle.usage = `@shuffle <tree>\tReturn a new tree with the original's keys shuffled`;
@@ -1,7 +1,7 @@
1
1
  import getTreeArgument from "../misc/getTreeArgument.js";
2
2
  import builtins from "./@builtins.js";
3
- import unpackOrigamiExpression from "./@loaders/ori.js";
4
3
  import paths from "./@paths.js";
4
+ import fileTypeOrigami from "./ori_handler.js";
5
5
 
6
6
  const templateText = `=\`<?xml version="1.0" encoding="UTF-8"?>
7
7
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@@ -48,7 +48,7 @@ export default async function sitemap(treelike, baseHref = "") {
48
48
  .filter((path) => path.endsWith(".html"))
49
49
  .map((path) => (path.endsWith("index.html") ? path.slice(0, -10) : path));
50
50
 
51
- const templateFn = await unpackOrigamiExpression(templateText);
51
+ const templateFn = await fileTypeOrigami.unpack(templateText);
52
52
  const templateResult = await templateFn.call(builtins, htmlPaths);
53
53
  return String(templateResult);
54
54
  }
@@ -1,5 +1,4 @@
1
1
  import { sortNatural } from "@weborigami/async-tree";
2
- import { Scope } from "@weborigami/language";
3
2
  import getTreeArgument from "../misc/getTreeArgument.js";
4
3
 
5
4
  /**
@@ -14,9 +13,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
14
13
  */
15
14
  export default async function sort(treelike) {
16
15
  const tree = await getTreeArgument(this, arguments, treelike, "@sort");
17
- const sorted = sortNatural()(tree);
18
- const scoped = Scope.treeWithScope(sorted, this);
19
- return scoped;
16
+ return sortNatural()(tree);
20
17
  }
21
18
 
22
19
  sort.usage = `@sort <tree>\tReturn a new tree with the original's keys sorted`;
@@ -1,5 +1,4 @@
1
1
  import { Tree, keysJson } from "@weborigami/async-tree";
2
- import { Scope } from "@weborigami/language";
3
2
  import { transformObject } from "../common/utilities.js";
4
3
  import getTreeArgument from "../misc/getTreeArgument.js";
5
4
  import index from "./@index.js";
@@ -14,8 +13,7 @@ import index from "./@index.js";
14
13
  */
15
14
  export default async function staticTree(treelike) {
16
15
  const tree = await getTreeArgument(this, arguments, treelike, "@static");
17
- let result = transformObject(StaticTransform, tree);
18
- result = Scope.treeWithScope(result, this);
16
+ const result = transformObject(StaticTransform, tree);
19
17
  return result;
20
18
  }
21
19
 
@@ -1,4 +1,3 @@
1
- import { Scope } from "@weborigami/language";
2
1
  import getTreeArgument from "../misc/getTreeArgument.js";
3
2
 
4
3
  /**
@@ -10,9 +9,7 @@ import getTreeArgument from "../misc/getTreeArgument.js";
10
9
  * @param {Treelike} [treelike]
11
10
  */
12
11
  export default async function tree(treelike) {
13
- let tree = await getTreeArgument(this, arguments, treelike, "@tree");
14
- tree = Scope.treeWithScope(tree, this);
15
- return tree;
12
+ return getTreeArgument(this, arguments, treelike, "@tree");
16
13
  }
17
14
 
18
15
  tree.usage = `@tree <treelike>\tConvert JSON, YAML, function, or plain object to a tree`;
@@ -21,9 +21,6 @@ export default async function toYaml(obj) {
21
21
  if (obj === undefined) {
22
22
  return undefined;
23
23
  }
24
- if (typeof obj.unpack === "function") {
25
- obj = await obj.unpack();
26
- }
27
24
  const value = await serialize.toJsonValue(obj);
28
25
  return YAML.stringify(value);
29
26
  }
@@ -0,0 +1,7 @@
1
+ // .css files use the .txt loader
2
+ import fileTypeText from "./txt_handler.js";
3
+
4
+ export default {
5
+ ...fileTypeText,
6
+ mediaType: "text/css",
7
+ };
@@ -0,0 +1,2 @@
1
+ // .htm is a synonynm for .html
2
+ export { default } from "./html_handler.js";
@@ -0,0 +1,7 @@
1
+ // .html files use the .txt loader
2
+ import fileTypeText from "./txt_handler.js";
3
+
4
+ export default {
5
+ ...fileTypeText,
6
+ mediaType: "text/html",
7
+ };