@weborigami/origami 0.5.4 → 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.
- package/index.ts +0 -4
- package/main.js +2 -9
- package/package.json +4 -5
- package/src/cli/cli.js +10 -8
- package/src/common/documentObject.js +3 -3
- package/src/common/loadJsDom.js +13 -0
- package/src/common/utilities.d.ts +0 -2
- package/src/common/utilities.js +1 -55
- package/src/dev/ExplorableSiteTransform.js +2 -6
- package/src/dev/OriCommandTransform.js +25 -7
- package/src/dev/changes.js +10 -5
- package/src/dev/code.js +1 -6
- package/src/dev/copy.js +4 -8
- package/src/dev/crawler/audit.js +8 -8
- package/src/dev/crawler/crawl.js +3 -5
- package/src/dev/crawler/findPaths.js +9 -3
- package/src/dev/crawler/pathsInHtml.js +4 -3
- package/src/dev/debug.js +4 -7
- package/src/dev/dev.js +4 -2
- package/src/dev/explore.js +17 -39
- package/src/dev/help.js +0 -4
- package/src/dev/help.yaml +18 -14
- package/src/dev/log.js +1 -2
- package/src/dev/serve.js +5 -18
- package/src/dev/svg.js +5 -5
- package/src/dev/treeDot.js +5 -6
- package/src/dev/watch.js +8 -12
- package/src/initializeBuiltins.js +23 -0
- package/src/origami/csv.js +1 -5
- package/src/origami/document.js +2 -5
- package/src/origami/fetch.js +4 -8
- package/src/origami/htmlDom.js +3 -2
- package/src/origami/image/format.js +0 -5
- package/src/origami/image/resize.js +0 -3
- package/src/origami/indexPage.js +4 -4
- package/src/origami/inline.js +4 -10
- package/src/origami/json.js +2 -6
- package/src/origami/jsonKeys.js +4 -10
- package/src/origami/jsonParse.js +1 -1
- package/src/origami/mdHtml.js +5 -9
- package/src/origami/mdOutline.js +3 -3
- package/src/origami/once.js +3 -7
- package/src/origami/ori.js +21 -24
- package/src/origami/origami.js +1 -4
- package/src/origami/pack.js +0 -5
- package/src/origami/post.js +4 -3
- package/src/origami/rss.js +7 -8
- package/src/origami/sitemap.js +7 -9
- package/src/origami/static.js +7 -9
- package/src/origami/string.js +1 -14
- package/src/origami/unpack.js +0 -5
- package/src/origami/yaml.js +1 -5
- package/src/origami/yamlParse.js +1 -1
- package/src/server/constructResponse.js +3 -3
- package/src/server/server.js +8 -59
- package/src/builtinsProgram.js +0 -65
- package/src/builtinsShell.js +0 -18
- package/src/cli/getConfig.js +0 -11
- package/src/common/ConstantTree.js +0 -18
- package/src/common/constructHref.js +0 -20
- package/src/common/constructSiteTree.js +0 -34
- package/src/common/fetchAndHandleExtension.js +0 -27
- package/src/handlers/css.handler.js +0 -7
- package/src/handlers/csv.handler.js +0 -126
- package/src/handlers/handlerBuiltins.js +0 -27
- package/src/handlers/handlers.js +0 -33
- package/src/handlers/htm.handler.js +0 -2
- package/src/handlers/html.handler.js +0 -7
- package/src/handlers/jpeg.handler.js +0 -62
- package/src/handlers/jpg.handler.js +0 -2
- package/src/handlers/js.handler.js +0 -20
- package/src/handlers/json.handler.js +0 -27
- package/src/handlers/md.handler.js +0 -7
- package/src/handlers/mjs.handler.js +0 -2
- package/src/handlers/ori.handler.js +0 -55
- package/src/handlers/oridocument.handler.js +0 -78
- package/src/handlers/parseFrontMatter.js +0 -16
- package/src/handlers/processUnpackedContent.js +0 -35
- package/src/handlers/ts.handler.js +0 -1
- package/src/handlers/txt.handler.js +0 -91
- package/src/handlers/wasm.handler.js +0 -17
- package/src/handlers/xhtml.handler.js +0 -2
- package/src/handlers/yaml.handler.js +0 -36
- package/src/handlers/yml.handler.js +0 -2
- package/src/origami/config.js +0 -18
- package/src/origami/project.js +0 -111
- package/src/protocols/explore.js +0 -19
- package/src/protocols/files.js +0 -31
- package/src/protocols/http.js +0 -18
- package/src/protocols/https.js +0 -18
- package/src/protocols/httpstree.js +0 -19
- package/src/protocols/httptree.js +0 -19
- package/src/protocols/js.js +0 -13
- package/src/protocols/node.js +0 -13
- package/src/protocols/package.js +0 -70
- package/src/tree/addNextPrevious.js +0 -22
- package/src/tree/cache.js +0 -22
- package/src/tree/calendar.js +0 -1
- package/src/tree/clear.js +0 -19
- package/src/tree/concat.js +0 -17
- package/src/tree/constant.js +0 -1
- package/src/tree/deepMap.js +0 -32
- package/src/tree/deepMerge.js +0 -18
- package/src/tree/deepReverse.js +0 -23
- package/src/tree/deepTake.js +0 -26
- package/src/tree/deepValues.js +0 -22
- package/src/tree/defineds.js +0 -30
- package/src/tree/filter.js +0 -19
- package/src/tree/first.js +0 -19
- package/src/tree/fromFn.js +0 -29
- package/src/tree/globKeys.js +0 -19
- package/src/tree/group.js +0 -26
- package/src/tree/inners.js +0 -30
- package/src/tree/keys.js +0 -15
- package/src/tree/length.js +0 -15
- package/src/tree/map.d.ts +0 -11
- package/src/tree/map.js +0 -125
- package/src/tree/mask.js +0 -19
- package/src/tree/match.js +0 -79
- package/src/tree/merge.js +0 -41
- package/src/tree/paginate.js +0 -20
- package/src/tree/parent.js +0 -15
- package/src/tree/plain.js +0 -15
- package/src/tree/regExpKeys.js +0 -19
- package/src/tree/reverse.js +0 -17
- package/src/tree/setDeep.js +0 -49
- package/src/tree/shuffle.js +0 -57
- package/src/tree/sort.js +0 -52
- package/src/tree/take.js +0 -19
- package/src/tree/tree.js +0 -52
- package/src/tree/values.js +0 -15
package/index.ts
CHANGED
|
@@ -3,16 +3,12 @@
|
|
|
3
3
|
* tool to confirm our code is type safe.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { Treelike, Unpackable } from "@weborigami/async-tree";
|
|
7
|
-
|
|
8
6
|
/**
|
|
9
7
|
* A class constructor is an object with a `new` method that returns an
|
|
10
8
|
* instance of the indicated type.
|
|
11
9
|
*/
|
|
12
10
|
export type Constructor<T> = new (...args: any[]) => T;
|
|
13
11
|
|
|
14
|
-
export type Invocable = Function | Unpackable<Function|Treelike> | Treelike;
|
|
15
|
-
|
|
16
12
|
export interface JsonObject {
|
|
17
13
|
[key: string]: JsonValue;
|
|
18
14
|
}
|
package/main.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
export { default as documentObject } from "./src/common/documentObject.js";
|
|
2
|
-
export
|
|
3
|
-
export * from "./src/
|
|
4
|
-
export { default as handlerBuiltins } from "./src/handlers/handlerBuiltins.js";
|
|
5
|
-
export * from "./src/handlers/handlers.js";
|
|
6
|
-
export * from "./src/origami/origami.js";
|
|
2
|
+
export * as Dev from "./src/dev/dev.js";
|
|
3
|
+
export * as Origami from "./src/origami/origami.js";
|
|
7
4
|
export { default as origamiHighlightDefinition } from "./src/origami/origamiHighlightDefinition.js";
|
|
8
|
-
export { default as package } from "./src/protocols/package.js";
|
|
9
5
|
export * from "./src/server/server.js";
|
|
10
|
-
|
|
11
|
-
// TODO: Remove once these async-tree owns sole copy of all tree builtins
|
|
12
|
-
export * from "./src/tree/tree.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/origami",
|
|
3
|
-
"version": "0.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.
|
|
20
|
+
"@weborigami/async-tree": "0.5.6",
|
|
21
21
|
"@weborigami/json-feed-to-rss": "1.0.0",
|
|
22
|
-
"@weborigami/language": "0.5.
|
|
23
|
-
"@weborigami/types": "0.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
|
|
21
|
+
const projectTree = await projectRoot();
|
|
18
22
|
|
|
19
23
|
// If no arguments were passed, show usage.
|
|
20
24
|
if (!expression) {
|
|
21
|
-
|
|
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
|
|
33
|
+
const parent = await Tree.traversePath(projectTree, relative);
|
|
32
34
|
|
|
33
|
-
const result = await ori
|
|
35
|
+
const result = await ori(expression, { parent });
|
|
34
36
|
|
|
35
37
|
if (result !== undefined) {
|
|
36
38
|
const output =
|
|
@@ -4,10 +4,10 @@ import { isPlainObject, isUnpackable, toString } from "@weborigami/async-tree";
|
|
|
4
4
|
* In Origami, a text document object is any object with a `_body` property.
|
|
5
5
|
* This function is a helper for constructing such text document objects.
|
|
6
6
|
*
|
|
7
|
-
* @typedef {import("@weborigami/async-tree").
|
|
7
|
+
* @typedef {import("@weborigami/async-tree").Stringlike} Stringlike
|
|
8
8
|
* @typedef {import("@weborigami/async-tree").PlainObject} PlainObject
|
|
9
9
|
*
|
|
10
|
-
* @param {
|
|
10
|
+
* @param {Stringlike|PlainObject} input
|
|
11
11
|
* @param {any} [data]
|
|
12
12
|
*/
|
|
13
13
|
export default async function documentObject(input, data) {
|
|
@@ -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
|
|
33
|
+
// return txt_handler.pack(this);
|
|
34
34
|
// },
|
|
35
35
|
// };
|
|
36
36
|
// const result = Object.create(base);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
let promise;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Lazy-load the jsdom library.
|
|
5
|
+
*
|
|
6
|
+
* Statically loading jsdom is slightly annoying. It's a large library that's
|
|
7
|
+
* rarely used. It also executes non-trivial code at load time. That includes a
|
|
8
|
+
* runtime test that (always?) throws an exception, which complicates debugging.
|
|
9
|
+
*/
|
|
10
|
+
export default async function loadJsDom() {
|
|
11
|
+
promise ??= await import("jsdom");
|
|
12
|
+
return promise;
|
|
13
|
+
}
|
|
@@ -2,6 +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 toFunction(object: any): Function;
|
|
6
|
-
export function toString(object: any): string|null;
|
|
7
5
|
export function transformObject(Transform: Function, object: any): any;
|
package/src/common/utilities.js
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Tree,
|
|
3
|
-
toString as asyncTreeToString,
|
|
4
|
-
isPlainObject,
|
|
5
|
-
isUnpackable,
|
|
6
|
-
trailingSlash,
|
|
7
|
-
} from "@weborigami/async-tree";
|
|
1
|
+
import { trailingSlash } from "@weborigami/async-tree";
|
|
8
2
|
import { symbols } from "@weborigami/language";
|
|
9
3
|
import { basename } from "node:path";
|
|
10
4
|
|
|
@@ -52,54 +46,6 @@ export function isTransformApplied(Transform, obj) {
|
|
|
52
46
|
return false;
|
|
53
47
|
}
|
|
54
48
|
|
|
55
|
-
/**
|
|
56
|
-
* Convert the given object to a function.
|
|
57
|
-
*
|
|
58
|
-
* @typedef {import("../../index.ts").Invocable} Invocable
|
|
59
|
-
* @param {any} obj
|
|
60
|
-
* @returns {Function|null}
|
|
61
|
-
*/
|
|
62
|
-
export function toFunction(obj) {
|
|
63
|
-
if (typeof obj === "function") {
|
|
64
|
-
// Return a function as is.
|
|
65
|
-
return obj;
|
|
66
|
-
} else if (isUnpackable(obj)) {
|
|
67
|
-
// Extract the contents of the object and convert that to a function.
|
|
68
|
-
let fnPromise;
|
|
69
|
-
/** @this {any} */
|
|
70
|
-
return async function (...args) {
|
|
71
|
-
if (!fnPromise) {
|
|
72
|
-
// unpack() may return a function or a promise for a function; normalize
|
|
73
|
-
// to a promise for a function
|
|
74
|
-
const unpackPromise = Promise.resolve(obj.unpack());
|
|
75
|
-
fnPromise = unpackPromise.then((content) => toFunction(content));
|
|
76
|
-
}
|
|
77
|
-
const fn = await fnPromise;
|
|
78
|
-
return fn.call(this, ...args);
|
|
79
|
-
};
|
|
80
|
-
} else if (Tree.isTreelike(obj)) {
|
|
81
|
-
// Return a function that invokes the tree's getter.
|
|
82
|
-
return Tree.toFunction(obj);
|
|
83
|
-
} else {
|
|
84
|
-
// Not a function
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Extend the async-tree toString method: objects that have a `_body` property
|
|
91
|
-
* will return the value of that property as a string.
|
|
92
|
-
*
|
|
93
|
-
* @param {any} object
|
|
94
|
-
* @returns {string|null}
|
|
95
|
-
*/
|
|
96
|
-
export function toString(object) {
|
|
97
|
-
if (isPlainObject(object) && "_body" in object) {
|
|
98
|
-
object = object._body;
|
|
99
|
-
}
|
|
100
|
-
return asyncTreeToString(object);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
49
|
/**
|
|
104
50
|
* Apply a functional class mixin to an individual object instance.
|
|
105
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
|
-
//
|
|
35
|
-
value = await indexPage
|
|
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
|
}
|
|
@@ -48,7 +48,6 @@ export default function ExplorableSiteTransform(Base) {
|
|
|
48
48
|
// If the value isn't a tree, but has a tree attached via an `unpack`
|
|
49
49
|
// method, wrap the unpack method to add this transform.
|
|
50
50
|
const original = value.unpack.bind(value);
|
|
51
|
-
const parent = this;
|
|
52
51
|
value.unpack = async () => {
|
|
53
52
|
const content = await original();
|
|
54
53
|
// See function notes at @debug
|
|
@@ -57,9 +56,6 @@ export default function ExplorableSiteTransform(Base) {
|
|
|
57
56
|
}
|
|
58
57
|
/** @type {any} */
|
|
59
58
|
let tree = Tree.from(content);
|
|
60
|
-
if (!tree.parent) {
|
|
61
|
-
tree.parent = parent;
|
|
62
|
-
}
|
|
63
59
|
if (!isTransformApplied(ExplorableSiteTransform, tree)) {
|
|
64
60
|
tree = transformObject(ExplorableSiteTransform, tree);
|
|
65
61
|
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
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
|
-
*
|
|
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
|
|
28
|
-
|
|
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;
|
package/src/dev/changes.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { trailingSlash, Tree } from "@weborigami/async-tree";
|
|
1
|
+
import { getTreeArgument, trailingSlash, Tree } from "@weborigami/async-tree";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Given an old tree and a new tree, return a tree of changes indicated
|
|
@@ -6,13 +6,18 @@ import { trailingSlash, Tree } from "@weborigami/async-tree";
|
|
|
6
6
|
*
|
|
7
7
|
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
8
8
|
*
|
|
9
|
-
* @this {import("@weborigami/types").AsyncTree|null}
|
|
10
9
|
* @param {Treelike} oldTreelike
|
|
11
10
|
* @param {Treelike} newTreelike
|
|
12
11
|
*/
|
|
13
12
|
export default async function changes(oldTreelike, newTreelike) {
|
|
14
|
-
const oldTree =
|
|
15
|
-
|
|
13
|
+
const oldTree = await getTreeArgument(oldTreelike, "changes", {
|
|
14
|
+
deep: true,
|
|
15
|
+
position: 0,
|
|
16
|
+
});
|
|
17
|
+
const newTree = await getTreeArgument(newTreelike, "changes", {
|
|
18
|
+
deep: true,
|
|
19
|
+
position: 1,
|
|
20
|
+
});
|
|
16
21
|
|
|
17
22
|
const oldKeys = Array.from(await oldTree.keys());
|
|
18
23
|
const newKeys = Array.from(await newTree.keys());
|
|
@@ -34,7 +39,7 @@ export default async function changes(oldTreelike, newTreelike) {
|
|
|
34
39
|
const newValue = await newTree.get(oldKey);
|
|
35
40
|
|
|
36
41
|
if (Tree.isAsyncTree(oldValue) && Tree.isAsyncTree(newValue)) {
|
|
37
|
-
const treeChanges = await changes
|
|
42
|
+
const treeChanges = await changes(oldValue, newValue);
|
|
38
43
|
if (treeChanges && Object.keys(treeChanges).length > 0) {
|
|
39
44
|
result ??= {};
|
|
40
45
|
result[oldKey] = treeChanges;
|
package/src/dev/code.js
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { toString } from "@weborigami/async-tree";
|
|
2
2
|
import { compile } from "@weborigami/language";
|
|
3
|
-
import getTreeArgument from "../common/getTreeArgument.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
7
6
|
*
|
|
8
|
-
* @
|
|
9
|
-
* @param {import("@weborigami/async-tree").StringLike} input
|
|
7
|
+
* @param {import("@weborigami/async-tree").Stringlike} input
|
|
10
8
|
*/
|
|
11
9
|
export default async function code(input) {
|
|
12
|
-
if (input === undefined) {
|
|
13
|
-
input = await getTreeArgument(this, arguments, input, "code");
|
|
14
|
-
}
|
|
15
10
|
if (input === undefined) {
|
|
16
11
|
return undefined;
|
|
17
12
|
}
|
package/src/dev/copy.js
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
|
-
import { Tree } from "@weborigami/async-tree";
|
|
1
|
+
import { getTreeArgument, Tree } from "@weborigami/async-tree";
|
|
2
2
|
import { formatError } from "@weborigami/language";
|
|
3
3
|
import process, { stdout } from "node:process";
|
|
4
|
-
import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
|
|
5
4
|
import { transformObject } from "../common/utilities.js";
|
|
6
|
-
import setDeep from "../tree/setDeep.js";
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
10
8
|
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
11
9
|
*
|
|
12
|
-
* @this {AsyncTree|null}
|
|
13
10
|
* @param {Treelike} source
|
|
14
11
|
* @param {Treelike} target
|
|
15
12
|
*/
|
|
16
13
|
export default async function copy(source, target) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/** @type {any} */ let targetTree = Tree.from(target, { parent: this });
|
|
14
|
+
const sourceTree = await getTreeArgument(source, "copy", { position: 0 });
|
|
15
|
+
let targetTree = await getTreeArgument(target, "copy", { position: 1 });
|
|
20
16
|
|
|
21
17
|
if (stdout.isTTY) {
|
|
22
18
|
targetTree = transformObject(ProgressTransform, targetTree);
|
|
@@ -25,7 +21,7 @@ export default async function copy(source, target) {
|
|
|
25
21
|
countCopied = 0;
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
await
|
|
24
|
+
await Tree.assign(targetTree, sourceTree);
|
|
29
25
|
|
|
30
26
|
if (stdout.isTTY) {
|
|
31
27
|
process.stdout.clearLine(0);
|
package/src/dev/crawler/audit.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
getTreeArgument,
|
|
3
|
+
pathFromKeys,
|
|
4
|
+
symbols,
|
|
5
|
+
Tree,
|
|
6
|
+
} from "@weborigami/async-tree";
|
|
3
7
|
import crawlResources from "./crawlResources.js";
|
|
4
8
|
import { getBaseUrl } from "./utilities.js";
|
|
5
9
|
|
|
@@ -10,12 +14,11 @@ import { getBaseUrl } from "./utilities.js";
|
|
|
10
14
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
11
15
|
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
12
16
|
*
|
|
13
|
-
* @this {AsyncTree|null}
|
|
14
17
|
* @param {Treelike} treelike
|
|
15
18
|
* @param {string} [baseHref]
|
|
16
19
|
*/
|
|
17
20
|
export default async function audit(treelike, baseHref) {
|
|
18
|
-
const tree = await getTreeArgument(
|
|
21
|
+
const tree = await getTreeArgument(treelike, "audit");
|
|
19
22
|
const baseUrl = getBaseUrl(baseHref, treelike);
|
|
20
23
|
|
|
21
24
|
let errors = {};
|
|
@@ -73,13 +76,10 @@ export default async function audit(treelike, baseHref) {
|
|
|
73
76
|
return undefined;
|
|
74
77
|
}
|
|
75
78
|
|
|
76
|
-
Object.defineProperty(errors, symbols.parent, {
|
|
77
|
-
enumerable: false,
|
|
78
|
-
value: this,
|
|
79
|
-
});
|
|
80
79
|
Object.defineProperty(errors, symbols.deep, {
|
|
81
80
|
enumerable: false,
|
|
82
81
|
value: true,
|
|
83
82
|
});
|
|
83
|
+
|
|
84
84
|
return errors;
|
|
85
85
|
}
|
package/src/dev/crawler/crawl.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DeepObjectTree,
|
|
3
3
|
Tree,
|
|
4
|
-
|
|
4
|
+
getTreeArgument,
|
|
5
5
|
keysFromPath,
|
|
6
6
|
} from "@weborigami/async-tree";
|
|
7
7
|
import { InvokeFunctionsTransform } from "@weborigami/language";
|
|
8
|
-
import getTreeArgument from "../../common/getTreeArgument.js";
|
|
9
8
|
import crawlResources from "./crawlResources.js";
|
|
10
9
|
import { addValueToObject, getBaseUrl } from "./utilities.js";
|
|
11
10
|
|
|
@@ -20,13 +19,12 @@ import { addValueToObject, getBaseUrl } from "./utilities.js";
|
|
|
20
19
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
21
20
|
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
22
21
|
*
|
|
23
|
-
* @this {AsyncTree|null}
|
|
24
22
|
* @param {Treelike} treelike
|
|
25
23
|
* @param {string} [baseHref]
|
|
26
24
|
* @returns {Promise<AsyncTree>}
|
|
27
25
|
*/
|
|
28
26
|
export default async function crawlBuiltin(treelike, baseHref) {
|
|
29
|
-
const tree = await getTreeArgument(
|
|
27
|
+
const tree = await getTreeArgument(treelike, "crawl");
|
|
30
28
|
const baseUrl = getBaseUrl(baseHref, treelike);
|
|
31
29
|
|
|
32
30
|
const cache = {};
|
|
@@ -55,7 +53,7 @@ export default async function crawlBuiltin(treelike, baseHref) {
|
|
|
55
53
|
// Merge the cache on top of the resources tree. If we have an actual value
|
|
56
54
|
// for something already, that's better than a function that will get that
|
|
57
55
|
// value.
|
|
58
|
-
const result = deepMerge(
|
|
56
|
+
const result = Tree.deepMerge(
|
|
59
57
|
new DeepObjectTree(cache),
|
|
60
58
|
new (InvokeFunctionsTransform(DeepObjectTree))(resources)
|
|
61
59
|
);
|
|
@@ -41,15 +41,21 @@ function filterPaths(paths, baseUrl, localPath) {
|
|
|
41
41
|
* Given a value retrieved from a site using a given key (name), determine what
|
|
42
42
|
* kind of file it is and, based on that, find the paths it references.
|
|
43
43
|
*/
|
|
44
|
-
export default function findPaths(value, key, baseUrl, localPath) {
|
|
44
|
+
export default async function findPaths(value, key, baseUrl, localPath) {
|
|
45
45
|
const text = toString(value);
|
|
46
|
+
if (text === null) {
|
|
47
|
+
return {
|
|
48
|
+
crawlablePaths: [],
|
|
49
|
+
resourcePaths: [],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
46
52
|
|
|
47
53
|
// We guess the value is HTML is if its key has an .html extension or
|
|
48
54
|
// doesn't have an extension, or the value starts with `<`.
|
|
49
55
|
const ext = key ? extension.extname(key).toLowerCase() : "";
|
|
50
56
|
let foundPaths;
|
|
51
57
|
if (ext === ".html" || ext === ".htm" || ext === ".xhtml") {
|
|
52
|
-
foundPaths = pathsInHtml(text);
|
|
58
|
+
foundPaths = await pathsInHtml(text);
|
|
53
59
|
} else if (ext === ".css") {
|
|
54
60
|
foundPaths = pathsInCss(text);
|
|
55
61
|
} else if (ext === ".js") {
|
|
@@ -62,7 +68,7 @@ export default function findPaths(value, key, baseUrl, localPath) {
|
|
|
62
68
|
foundPaths = pathsInSitemap(text);
|
|
63
69
|
} else if (ext === "" && text?.trim().startsWith("<")) {
|
|
64
70
|
// Probably HTML
|
|
65
|
-
foundPaths = pathsInHtml(text);
|
|
71
|
+
foundPaths = await pathsInHtml(text);
|
|
66
72
|
} else {
|
|
67
73
|
// Doesn't have an extension we want to process
|
|
68
74
|
return {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import loadJsDom from "../../common/loadJsDom.js";
|
|
2
2
|
import pathsInCss from "./pathsInCss.js";
|
|
3
3
|
import pathsInJs from "./pathsInJs.js";
|
|
4
4
|
import { addHref } from "./utilities.js";
|
|
5
5
|
|
|
6
|
-
export default function pathsInHtml(html) {
|
|
6
|
+
export default async function pathsInHtml(html) {
|
|
7
|
+
const { JSDOM, VirtualConsole } = await loadJsDom();
|
|
7
8
|
const paths = {
|
|
8
9
|
/** @type {string[]} */
|
|
9
10
|
crawlablePaths: [],
|
|
@@ -153,7 +154,7 @@ export default function pathsInHtml(html) {
|
|
|
153
154
|
while ((match = noframesRegex.exec(html))) {
|
|
154
155
|
const noframesHtml = match.groups?.html;
|
|
155
156
|
if (noframesHtml) {
|
|
156
|
-
const noframesPaths = pathsInHtml(noframesHtml);
|
|
157
|
+
const noframesPaths = await pathsInHtml(noframesHtml);
|
|
157
158
|
paths.crawlablePaths.push(...noframesPaths.crawlablePaths);
|
|
158
159
|
paths.resourcePaths.push(...noframesPaths.resourcePaths);
|
|
159
160
|
}
|
package/src/dev/debug.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Tree } from "@weborigami/async-tree";
|
|
2
|
-
import getTreeArgument from "../common/getTreeArgument.js";
|
|
1
|
+
import { getTreeArgument, Tree } from "@weborigami/async-tree";
|
|
3
2
|
import { isTransformApplied, transformObject } from "../common/utilities.js";
|
|
4
3
|
import ExplorableSiteTransform from "./ExplorableSiteTransform.js";
|
|
5
4
|
import OriCommandTransform from "./OriCommandTransform.js";
|
|
@@ -10,13 +9,11 @@ import OriCommandTransform from "./OriCommandTransform.js";
|
|
|
10
9
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
11
10
|
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
12
11
|
*
|
|
13
|
-
* @
|
|
14
|
-
* @
|
|
12
|
+
* @param {Treelike} treelike
|
|
13
|
+
* @returns {Promise<AsyncTree>}
|
|
15
14
|
*/
|
|
16
15
|
export default async function debug(treelike) {
|
|
17
|
-
|
|
18
|
-
// apply its own scope to the tree.
|
|
19
|
-
let tree = await getTreeArgument(this, arguments, treelike, "debug");
|
|
16
|
+
let tree = await getTreeArgument(treelike, "debug");
|
|
20
17
|
|
|
21
18
|
if (!isTransformApplied(DebugTransform, tree)) {
|
|
22
19
|
tree = transformObject(DebugTransform, tree);
|
package/src/dev/dev.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { Tree } from "@weborigami/async-tree";
|
|
2
|
+
export const clear = Tree.clear;
|
|
3
|
+
export const keys = Tree.keys;
|
|
4
|
+
|
|
1
5
|
export { default as indexPage } from "../origami/indexPage.js";
|
|
2
6
|
export { default as yaml } from "../origami/yaml.js";
|
|
3
|
-
export { default as clear } from "../tree/clear.js";
|
|
4
|
-
export { default as keys } from "../tree/keys.js";
|
|
5
7
|
export { default as breakpoint } from "./breakpoint.js";
|
|
6
8
|
export { default as changes } from "./changes.js";
|
|
7
9
|
export { default as code } from "./code.js";
|
package/src/dev/explore.js
CHANGED
|
@@ -1,54 +1,30 @@
|
|
|
1
1
|
/** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
|
|
2
|
-
import {
|
|
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
|
-
*
|
|
12
|
+
* Display a debug/explore page for the current tree.
|
|
15
13
|
*/
|
|
16
|
-
export default async function explore(
|
|
17
|
-
|
|
18
|
-
if (!this) {
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
14
|
+
export default async function explore(treelike) {
|
|
15
|
+
const tree = await getTreeArgument(treelike, "explore");
|
|
21
16
|
|
|
22
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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 = 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 data = await getScopeData(scope(tree));
|
|
45
|
-
templatePromise ??= loadTemplate();
|
|
46
|
-
const template = await templatePromise;
|
|
47
|
-
const text = await template.call(this, data);
|
|
48
|
-
|
|
49
|
-
result = new String(text);
|
|
50
|
-
result.unpack = () => debug.call(tree, tree);
|
|
51
|
-
}
|
|
26
|
+
const result = new String(text);
|
|
27
|
+
result.unpack = () => debug(tree);
|
|
52
28
|
|
|
53
29
|
return result;
|
|
54
30
|
}
|
|
@@ -70,6 +46,8 @@ async function loadTemplate() {
|
|
|
70
46
|
const folderPath = path.resolve(fileURLToPath(import.meta.url), "..");
|
|
71
47
|
const folder = new OrigamiFiles(folderPath);
|
|
72
48
|
const templateFile = await folder.get("explore.ori");
|
|
73
|
-
const template = await
|
|
49
|
+
const template = await Handlers.ori_handler.unpack(templateFile, {
|
|
50
|
+
parent: folder,
|
|
51
|
+
});
|
|
74
52
|
return template;
|
|
75
53
|
}
|
package/src/dev/help.js
CHANGED
|
@@ -2,18 +2,14 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
import YAML from "yaml";
|
|
5
|
-
import assertTreeIsDefined from "../common/assertTreeIsDefined.js";
|
|
6
5
|
import version from "./version.js";
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
10
9
|
*
|
|
11
|
-
* @this {AsyncTree|null}
|
|
12
10
|
* @param {string} [key]
|
|
13
11
|
*/
|
|
14
12
|
export default async function help(key) {
|
|
15
|
-
assertTreeIsDefined(this, "help");
|
|
16
|
-
|
|
17
13
|
const helpFilename = path.resolve(
|
|
18
14
|
fileURLToPath(import.meta.url),
|
|
19
15
|
"../help.yaml"
|