@weborigami/origami 0.0.44 → 0.0.46

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.
@@ -1,5 +1,5 @@
1
1
  /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
- import { keyMapsForExtensions, map } from "@weborigami/async-tree";
2
+ import { keyFunctionsForExtensions, map } from "@weborigami/async-tree";
3
3
  import unpackOrigamiTemplate from "../src/builtins/@loaders/ori.js";
4
4
  import { transformObject } from "../src/common/utilities.js";
5
5
  import PathTransform from "./PathTransform.js";
@@ -47,7 +47,8 @@ async function exportStatementForCode(codeBuffer, key) {
47
47
  const pathParts = path.split("/");
48
48
  pathParts.pop(); // Drop key
49
49
 
50
- const exportsDefault = code.match(/^export default /m);
50
+ const exportsDefault =
51
+ code.match(/^export default /m) || code.match(/^export { default } /m);
51
52
  if (!exportsDefault) {
52
53
  // Export everything.
53
54
  return `export * from "../src/${path}";\n`;
@@ -76,12 +77,15 @@ async function exportStatementForCode(codeBuffer, key) {
76
77
  name = specialName;
77
78
  }
78
79
 
80
+ // Split the name into parts based on dots.
81
+ const nameParts = name.split(".");
82
+
79
83
  // Add the name to the parts.
80
- exportIdentifierParts.push(name);
84
+ exportIdentifierParts.push(...nameParts);
81
85
 
82
- // Remove the @ prefix from any parts, if present.
86
+ // Remove characters that can't be in JavaScript identifiers.
83
87
  exportIdentifierParts = exportIdentifierParts.map((part) =>
84
- part.startsWith("@") ? part.slice(1) : part
88
+ part.replace(/[^a-zA-Z0-9]/g, "")
85
89
  );
86
90
 
87
91
  // Join the parts in camelCase to form the identifier.
@@ -101,8 +105,8 @@ function exportStatements(src) {
101
105
  // Map each source file to an export statement.
102
106
  const mapped = map({
103
107
  deep: true,
104
- valueMap: exportStatementForCode,
105
- ...keyMapsForExtensions({ sourceExtension: "js" }),
108
+ value: exportStatementForCode,
109
+ ...keyFunctionsForExtensions({ sourceExtension: "js" }),
106
110
  })(withPaths);
107
111
 
108
112
  return mapped;
@@ -38,26 +38,28 @@ 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 * from "../src/builtins/@loaders/css.js";
42
- export * from "../src/builtins/@loaders/htm.js";
43
- export * from "../src/builtins/@loaders/html.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
44
  export { default as loadersJpeg } from "../src/builtins/@loaders/jpeg.js";
45
- export * from "../src/builtins/@loaders/jpg.js";
45
+ export { default as loadersJpg } from "../src/builtins/@loaders/jpg.js";
46
46
  export { default as loadersJs } from "../src/builtins/@loaders/js.js";
47
47
  export { default as loadersJson } from "../src/builtins/@loaders/json.js";
48
- export * from "../src/builtins/@loaders/md.js";
49
- export * from "../src/builtins/@loaders/mjs.js";
48
+ export { default as loadersMd } from "../src/builtins/@loaders/md.js";
49
+ export { default as loadersMjs } from "../src/builtins/@loaders/mjs.js";
50
50
  export { default as loadersOri } from "../src/builtins/@loaders/ori.js";
51
51
  export { default as loadersTxt } from "../src/builtins/@loaders/txt.js";
52
- export * from "../src/builtins/@loaders/xhtml.js";
52
+ export { default as loadersWasm } from "../src/builtins/@loaders/wasm.js";
53
+ export { default as loadersXhtml } from "../src/builtins/@loaders/xhtml.js";
53
54
  export { default as loadersYaml } from "../src/builtins/@loaders/yaml.js";
54
- export * from "../src/builtins/@loaders/yml.js";
55
+ export { default as loadersYml } from "../src/builtins/@loaders/yml.js";
55
56
  export { default as map } from "../src/builtins/@map.js";
56
57
  export { default as mapDeep } from "../src/builtins/@mapDeep.js";
57
58
  export { default as match } from "../src/builtins/@match.js";
58
59
  export { default as mdHtml } from "../src/builtins/@mdHtml.js";
59
60
  export { default as merge } from "../src/builtins/@merge.js";
60
61
  export { default as mergeDeep } from "../src/builtins/@mergeDeep.js";
62
+ export { default as mkdir } from "../src/builtins/@mkdir.js";
61
63
  export { default as node } from "../src/builtins/@node.js";
62
64
  export { default as not } from "../src/builtins/@not.js";
63
65
  export { default as once } from "../src/builtins/@once.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/origami",
3
- "version": "0.0.44",
3
+ "version": "0.0.46",
4
4
  "description": "Web Origami language, CLI, framework, and server",
5
5
  "type": "module",
6
6
  "repository": {
@@ -19,9 +19,9 @@
19
19
  "typescript": "5.3.3"
20
20
  },
21
21
  "dependencies": {
22
- "@weborigami/async-tree": "0.0.44",
23
- "@weborigami/language": "0.0.44",
24
- "@weborigami/types": "0.0.44",
22
+ "@weborigami/async-tree": "0.0.46",
23
+ "@weborigami/language": "0.0.46",
24
+ "@weborigami/types": "0.0.46",
25
25
  "exif-parser": "0.1.12",
26
26
  "graphviz-wasm": "3.0.1",
27
27
  "highlight.js": "11.9.0",
@@ -1,4 +1,4 @@
1
- import { cache, Tree } from "@weborigami/async-tree";
1
+ import { Tree, cache } from "@weborigami/async-tree";
2
2
  import { Scope } from "@weborigami/language";
3
3
  import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
4
4
 
@@ -19,14 +19,10 @@ export default async function cacheBuiltin(
19
19
  filterTreelike
20
20
  ) {
21
21
  assertScopeIsDefined(this, "cache");
22
-
23
- const sourceTree = Tree.from(sourceTreelike);
24
22
  /** @type {any} */
25
23
  const cacheTree = cacheTreelike ? Tree.from(cacheTreelike) : undefined;
26
- const filterTree = filterTreelike ? Tree.from(filterTreelike) : undefined;
27
-
28
24
  /** @type {AsyncTree} */
29
- let result = cache(sourceTree, cacheTree, filterTree);
25
+ let result = cache(sourceTreelike, cacheTree, filterTreelike);
30
26
  result = Scope.treeWithScope(result, this);
31
27
  return result;
32
28
  }
@@ -1,8 +1,14 @@
1
+ import * as utilities from "../../common/utilities.js";
2
+
1
3
  /**
2
4
  * Load a file as JSON.
3
5
  *
4
6
  * @type {import("@weborigami/language").FileUnpackFunction}
5
7
  */
6
8
  export default function unpackJson(input) {
7
- return JSON.parse(String(input));
9
+ const json = utilities.toString(input);
10
+ if (!json) {
11
+ throw new Error("Tried to parse something as JSON but it wasn't text.");
12
+ }
13
+ return JSON.parse(json);
8
14
  }
@@ -1,5 +1,6 @@
1
1
  import TextDocument from "../../common/TextDocument.js";
2
2
  import { evaluateYaml } from "../../common/serialize.js";
3
+ import * as utilities from "../../common/utilities.js";
3
4
 
4
5
  /**
5
6
  * Load a file as text document with possible front matter.
@@ -16,7 +17,10 @@ import { evaluateYaml } from "../../common/serialize.js";
16
17
  */
17
18
  export default async function unpackText(input, options = {}) {
18
19
  const parent = options.parent ?? null;
19
- const text = String(input);
20
+ const text = utilities.toString(input);
21
+ if (!text) {
22
+ throw new Error("Tried to treat something as text but it wasn't text.");
23
+ }
20
24
  const regex =
21
25
  /^(---\r?\n(?<frontText>[\s\S]*?\r?\n)---\r?\n)(?<body>[\s\S]*$)/;
22
26
  const match = regex.exec(text);
@@ -0,0 +1,11 @@
1
+ import processUnpackedContent from "../../common/processUnpackedContent.js";
2
+
3
+ /**
4
+ * Load a WebAssembly module and return its exports.
5
+ *
6
+ * @type {import("@weborigami/language").FileUnpackFunction}
7
+ */
8
+ export default async function unpackWasm(buffer, options = {}) {
9
+ const wasmModule = await WebAssembly.instantiate(buffer);
10
+ return processUnpackedContent(wasmModule.instance.exports, options.parent);
11
+ }
@@ -1,6 +1,7 @@
1
1
  import * as YAMLModule from "yaml";
2
2
  import processUnpackedContent from "../../common/processUnpackedContent.js";
3
3
  import { evaluateYaml } from "../../common/serialize.js";
4
+ import * as utilities from "../../common/utilities.js";
4
5
 
5
6
  // See notes at serialize.js
6
7
  // @ts-ignore
@@ -13,6 +14,10 @@ const YAML = YAMLModule.default ?? YAMLModule.YAML;
13
14
  */
14
15
  export default async function unpackYaml(input, options = {}) {
15
16
  const parent = options.parent ?? null;
16
- const data = await evaluateYaml(String(input), options.parent);
17
+ const yaml = utilities.toString(input);
18
+ if (!yaml) {
19
+ throw new Error("Tried to parse something as YAML but it wasn't text.");
20
+ }
21
+ const data = await evaluateYaml(yaml, options.parent);
17
22
  return processUnpackedContent(data, parent);
18
23
  }
@@ -1,8 +1,7 @@
1
1
  import {
2
- cachedKeyMaps,
3
- keyMapsForExtensions,
2
+ cachedKeyFunctions,
3
+ keyFunctionsForExtensions,
4
4
  map,
5
- Tree,
6
5
  } from "@weborigami/async-tree";
7
6
  import { Scope } from "@weborigami/language";
8
7
  import addValueKeyToScope from "../common/addValueKeyToScope.js";
@@ -18,9 +17,9 @@ import { toFunction } from "../common/utilities.js";
18
17
  * @typedef {import("../../index.ts").TreelikeTransform} TreelikeTransform
19
18
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
20
19
  *
21
- * @typedef {{ deep?: boolean, description?: string, extensions?: string,
22
- * inverseKeyMap?: KeyFn, keyMap?: ValueKeyFn, valueMap?: ValueKeyFn }}
23
- * TreeMapOptions
20
+ * @typedef {{ deep?: boolean, description?: string, extension?: string,
21
+ * extensions?: string, inverseKey?: KeyFn, key?: ValueKeyFn, keyMap?:
22
+ * ValueKeyFn, value?: ValueKeyFn, valueFn?: ValueKeyFn }} TreeMapOptions
24
23
  *
25
24
  * @this {import("@weborigami/types").AsyncTree|null}
26
25
  *
@@ -43,7 +42,7 @@ import { toFunction } from "../common/utilities.js";
43
42
  * @returns {AsyncTree}
44
43
  */
45
44
  export default function treeMap(param1, param2) {
46
- // Identify whether the valueMap/options are the first parameter
45
+ // Identify whether the valueFn/options are the first parameter
47
46
  // or the second.
48
47
  let source;
49
48
  let options;
@@ -62,37 +61,32 @@ export default function treeMap(param1, param2) {
62
61
  options = param2;
63
62
  }
64
63
 
65
- // Identify whether the valueMap/options is a valueMap function
64
+ // Identify whether the valueFn/options is a valueFn function
66
65
  // or an options dictionary.
67
- let valueMap;
66
+ let valueFn;
68
67
  if (
69
68
  typeof options === "function" ||
70
69
  typeof (/** @type {any} */ (options)?.unpack) === "function"
71
70
  ) {
72
- valueMap = options;
71
+ valueFn = options;
73
72
  options = {};
74
73
  } else if (!options) {
75
74
  throw new TypeError(
76
- `@map: You must specify a valueMap function or options dictionary.`
75
+ `@map: You must specify a value function or options dictionary.`
77
76
  );
78
77
  } else {
79
- valueMap = options.valueMap;
78
+ valueFn = options.value ?? options.valueMap;
80
79
  }
81
80
 
82
- let {
83
- deep,
84
- description,
85
- extensions,
86
- inverseKeyMap,
87
- keyMap,
88
- needsSourceValue,
89
- } = options;
81
+ let { deep, description, inverseKey, needsSourceValue } = options;
82
+ let extension = options.extension ?? options.extensions;
83
+ let keyFn = options.keyMap ?? options.key;
90
84
 
91
- description ??= `@map ${extensions ?? ""}`;
85
+ description ??= `@map ${extension ?? ""}`;
92
86
 
93
- if (extensions && (keyMap || inverseKeyMap)) {
87
+ if (extension && (keyFn || inverseKey)) {
94
88
  throw new TypeError(
95
- `@map: You can't specify both extensions and a keyMap or inverseKeyMap`
89
+ `@map: You can't specify extensions and also a key or inverseKey function`
96
90
  );
97
91
  }
98
92
 
@@ -100,8 +94,8 @@ export default function treeMap(param1, param2) {
100
94
 
101
95
  // Extend the value function to include the value and key in scope.
102
96
  let extendedValueFn;
103
- if (valueMap) {
104
- const resolvedValueFn = toFunction(valueMap);
97
+ if (valueFn) {
98
+ const resolvedValueFn = toFunction(valueFn);
105
99
  extendedValueFn = function (sourceValue, sourceKey, tree) {
106
100
  const scope = addValueKeyToScope(baseScope, sourceValue, sourceKey);
107
101
  return resolvedValueFn.call(scope, sourceValue, sourceKey, tree);
@@ -109,18 +103,18 @@ export default function treeMap(param1, param2) {
109
103
  }
110
104
 
111
105
  // Extend the key function to include the value and key in scope.
112
- let extendedKeyMap;
113
- let extendedInverseKeyMap;
114
- if (extensions) {
115
- let { resultExtension, sourceExtension } = parseExtensions(extensions);
116
- const keyFns = keyMapsForExtensions({
106
+ let extendedKeyFn;
107
+ let extendedInverseKeyFn;
108
+ if (extension) {
109
+ let { resultExtension, sourceExtension } = parseExtensions(extension);
110
+ const keyFns = keyFunctionsForExtensions({
117
111
  resultExtension,
118
112
  sourceExtension,
119
113
  });
120
- extendedKeyMap = keyFns.keyMap;
121
- extendedInverseKeyMap = keyFns.inverseKeyMap;
122
- } else if (keyMap) {
123
- const resolvedKeyFn = toFunction(keyMap);
114
+ extendedKeyFn = keyFns.key;
115
+ extendedInverseKeyFn = keyFns.inverseKey;
116
+ } else if (keyFn) {
117
+ const resolvedKeyFn = toFunction(keyFn);
124
118
  async function scopedKeyFn(sourceKey, tree) {
125
119
  const sourceValue = await tree.get(sourceKey);
126
120
  const scope = addValueKeyToScope(baseScope, sourceValue, sourceKey);
@@ -132,25 +126,24 @@ export default function treeMap(param1, param2) {
132
126
  );
133
127
  return resultKey;
134
128
  }
135
- const keyFns = cachedKeyMaps(scopedKeyFn);
136
- extendedKeyMap = keyFns.keyMap;
137
- extendedInverseKeyMap = keyFns.inverseKeyMap;
129
+ const keyFns = cachedKeyFunctions(scopedKeyFn);
130
+ extendedKeyFn = keyFns.key;
131
+ extendedInverseKeyFn = keyFns.inverseKey;
138
132
  } else {
139
- // Use sidecar keyMap/inverseKeyMap functions if the valueMap defines them.
140
- extendedKeyMap = valueMap?.keyMap;
141
- extendedInverseKeyMap = valueMap?.inverseKeyMap;
133
+ // Use sidecar keyFn/inverseKey functions if the valueFn defines them.
134
+ extendedKeyFn = valueFn?.key;
135
+ extendedInverseKeyFn = valueFn?.inverseKey;
142
136
  }
143
137
 
144
138
  const transform = function mapTreelike(treelike) {
145
- const tree = Tree.from(treelike);
146
139
  return map({
147
140
  deep,
148
141
  description,
149
- inverseKeyMap: extendedInverseKeyMap,
150
- keyMap: extendedKeyMap,
142
+ inverseKey: extendedInverseKeyFn,
143
+ key: extendedKeyFn,
151
144
  needsSourceValue,
152
- valueMap: extendedValueFn,
153
- })(tree);
145
+ value: extendedValueFn,
146
+ })(treelike);
154
147
  };
155
148
 
156
149
  return source ? transform(source) : transform;
@@ -2,7 +2,7 @@ import { isPlainObject } from "@weborigami/async-tree";
2
2
  import treeMap from "./@map.js";
3
3
 
4
4
  export default function mapDeep(param1, param2) {
5
- // Identify whether the valueMap/options are the first parameter
5
+ // Identify whether the valueFn/options are the first parameter
6
6
  // or the second.
7
7
  let source;
8
8
  let options;
@@ -13,7 +13,7 @@ export default function mapDeep(param1, param2) {
13
13
  if (isPlainObject(param2)) {
14
14
  options = param2;
15
15
  } else {
16
- options = { valueMap: param2 };
16
+ options = { value: param2 };
17
17
  }
18
18
  }
19
19
 
@@ -42,9 +42,8 @@ export default async function mdHtml(input) {
42
42
  : html;
43
43
  }
44
44
 
45
- mdHtml.keyMap = (sourceKey) => replaceExtension(sourceKey, ".md", ".html");
46
- mdHtml.inverseKeyMap = (resultKey) =>
47
- replaceExtension(resultKey, ".html", ".md");
45
+ mdHtml.key = (sourceKey) => replaceExtension(sourceKey, ".md", ".html");
46
+ mdHtml.inverseKey = (resultKey) => replaceExtension(resultKey, ".html", ".md");
48
47
 
49
48
  mdHtml.usage = `@mdHtml <markdown>\tRender the markdown text as HTML`;
50
49
  mdHtml.documentation = "https://weborigami.org/language/@mdHtml.html";
@@ -0,0 +1,3 @@
1
+ // For now this is a synonym for @files.
2
+ // If we like it, it might replace @files.
3
+ export { default } from "./@files.js";
@@ -7,7 +7,8 @@ import url from "node:url";
7
7
  const patchedProcess = Object.create(null, {
8
8
  ...Object.getOwnPropertyDescriptors(process),
9
9
  env: {
10
- value: function () {
10
+ enumerable: true,
11
+ get: function () {
11
12
  return Object.assign({}, process.env);
12
13
  },
13
14
  },
@@ -73,13 +73,13 @@ async function formatResult(result) {
73
73
  text = result;
74
74
  }
75
75
 
76
- // If the result is a tree, attach the tree to the text output.
76
+ // If the result is treelike, attach it to the text output.
77
77
  if (Tree.isTreelike(result)) {
78
78
  if (typeof text === "string") {
79
79
  // @ts-ignore
80
80
  text = new String(text);
81
81
  }
82
- /** @type {any} */ (text).unpack = () => Tree.from(result);
82
+ /** @type {any} */ (text).unpack = () => result;
83
83
  }
84
84
 
85
85
  return text;
@@ -6,12 +6,12 @@ type TreeMapOptions = {
6
6
  deep?: boolean;
7
7
  description?: string;
8
8
  extensions?: string;
9
- inverseKeyMap?: KeyFn;
10
- keyMap?: ValueKeyFn;
11
- valueMap?: ValueKeyFn;
9
+ inverseKey?: KeyFn;
10
+ key?: ValueKeyFn;
11
+ value?: ValueKeyFn;
12
12
  };
13
13
 
14
- export default function treeMap(valueMap: ValueKeyFn): TreelikeTransform;
14
+ export default function treeMap(value: ValueKeyFn): TreelikeTransform;
15
15
  export default function treeMap(options: TreeMapOptions): TreelikeTransform;
16
- export default function treeMap(treelike: Treelike, valueMap: ValueKeyFn): AsyncTree;
16
+ export default function treeMap(treelike: Treelike, value: ValueKeyFn): AsyncTree;
17
17
  export default function treeMap(treelike: Treelike, options: TreeMapOptions): AsyncTree;
@@ -1,4 +1,4 @@
1
- import { cachedKeyMaps, map } from "@weborigami/async-tree";
1
+ import { cachedKeyFunctions, map } from "@weborigami/async-tree";
2
2
  import { toFunction } from "./utilities.js";
3
3
 
4
4
  export default function arrowFunctionsMap() {
@@ -6,12 +6,12 @@ export default function arrowFunctionsMap() {
6
6
  return map({
7
7
  deep,
8
8
  description: "arrowFunctions",
9
- valueMap,
10
- ...cachedKeyMaps(keyMap, deep),
9
+ value: valueFn,
10
+ ...cachedKeyFunctions(keyFn, deep),
11
11
  });
12
12
  }
13
13
 
14
- function keyMap(sourceKey, tree) {
14
+ function keyFn(sourceKey, tree) {
15
15
  return parseArrowKey(sourceKey) ?? sourceKey;
16
16
  }
17
17
 
@@ -23,7 +23,7 @@ function parseArrowKey(sourceKey) {
23
23
  return match?.groups.lhs;
24
24
  }
25
25
 
26
- function valueMap(sourceValue, sourceKey, tree) {
26
+ function valueFn(sourceValue, sourceKey, tree) {
27
27
  let resultValue;
28
28
  if (parseArrowKey(sourceKey)) {
29
29
  // Treat the value as a function to be invoked.
@@ -78,7 +78,12 @@ async function statements(tree, nodePath, nodeLabel, options) {
78
78
  } else {
79
79
  const label = isStringLike(value)
80
80
  ? String(value)
81
- : await serialize.toYaml(value);
81
+ : value != null
82
+ ? await serialize.toYaml(value)
83
+ : "";
84
+ if (value == null) {
85
+ isError = true;
86
+ }
82
87
  nodes[key] = { label };
83
88
  if (isError) {
84
89
  nodes[key].isError = true;
package/src/builtins/!.js DELETED
@@ -1,21 +0,0 @@
1
- /**
2
- * The `!` built-in returns `undefined`, and is intended for force function
3
- * invocation in the shell without requiring the use of parentheses. Parentheses
4
- * can't be used in the shell without quoting them, which is inconvenient.
5
- *
6
- * This parentheses form:
7
- *
8
- * ```
9
- * $ ori "fn1.js(fn2.js())"
10
- * ```
11
- *
12
- * Can be written as:
13
- *
14
- * ```
15
- * $ ori fn1.js fn2.js !
16
- * ```
17
- *
18
- * This forces the invocation of `fn2.js`, passing `undefined` as the argument.
19
- * The result of that invocation is then passed to `fn1.js`.
20
- */
21
- export default undefined;