forked from sashin/sashinexists
run npm install to generate a package lock
This commit is contained in:
18
node_modules/@weborigami/origami/src/common/ConstantTree.js
generated
vendored
Normal file
18
node_modules/@weborigami/origami/src/common/ConstantTree.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
||||
* @implements {AsyncTree}
|
||||
*/
|
||||
export default class ConstantTree {
|
||||
constructor(value) {
|
||||
this.value = value;
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
async keys() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
1
node_modules/@weborigami/origami/src/common/assertTreeIsDefined.d.ts
generated
vendored
Normal file
1
node_modules/@weborigami/origami/src/common/assertTreeIsDefined.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export default function assertTreeIsDefined(tree: any, methodName: string): asserts tree is object
|
||||
10
node_modules/@weborigami/origami/src/common/assertTreeIsDefined.js
generated
vendored
Normal file
10
node_modules/@weborigami/origami/src/common/assertTreeIsDefined.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Tree } from "@weborigami/async-tree";
|
||||
|
||||
export default function assertTreeIsDefined(tree, methodName) {
|
||||
const isValid = tree === null || Tree.isAsyncTree(tree);
|
||||
if (!isValid) {
|
||||
throw new Error(
|
||||
`${methodName} must be called with a tree target. If you don't want to pass a tree, invoke with: ${methodName}.call(null)`
|
||||
);
|
||||
}
|
||||
}
|
||||
20
node_modules/@weborigami/origami/src/common/constructHref.js
generated
vendored
Normal file
20
node_modules/@weborigami/origami/src/common/constructHref.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { pathFromKeys } from "@weborigami/async-tree";
|
||||
|
||||
/**
|
||||
* Given a protocol, a host, and a list of keys, construct an href.
|
||||
*
|
||||
* @param {string} protocol
|
||||
* @param {string} host
|
||||
* @param {string[]} keys
|
||||
*/
|
||||
export default function constructHref(protocol, host, ...keys) {
|
||||
const path = pathFromKeys(keys);
|
||||
let href = [host, path].join("/");
|
||||
if (!href.startsWith(protocol)) {
|
||||
if (!href.startsWith("//")) {
|
||||
href = `//${href}`;
|
||||
}
|
||||
href = `${protocol}${href}`;
|
||||
}
|
||||
return href;
|
||||
}
|
||||
34
node_modules/@weborigami/origami/src/common/constructSiteTree.js
generated
vendored
Normal file
34
node_modules/@weborigami/origami/src/common/constructSiteTree.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import { trailingSlash } from "@weborigami/async-tree";
|
||||
import { HandleExtensionsTransform } from "@weborigami/language";
|
||||
import constructHref from "./constructHref.js";
|
||||
|
||||
/**
|
||||
* Given a protocol, a host, and a list of keys, construct an href.
|
||||
*
|
||||
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
||||
*
|
||||
* @param {string} protocol
|
||||
* @param {import("../../index.ts").Constructor<AsyncTree>} treeClass
|
||||
* @param {AsyncTree|null} parent
|
||||
* @param {string} host
|
||||
* @param {string[]} keys
|
||||
*/
|
||||
export default function constructSiteTree(
|
||||
protocol,
|
||||
treeClass,
|
||||
parent,
|
||||
host,
|
||||
...keys
|
||||
) {
|
||||
// If the last key doesn't end in a slash, remove it for now.
|
||||
let lastKey;
|
||||
if (keys.length > 0 && keys.at(-1) && !trailingSlash.has(keys.at(-1))) {
|
||||
lastKey = keys.pop();
|
||||
}
|
||||
|
||||
const href = constructHref(protocol, host, ...keys);
|
||||
let result = new (HandleExtensionsTransform(treeClass))(href);
|
||||
result.parent = parent;
|
||||
|
||||
return lastKey ? result.get(lastKey) : result;
|
||||
}
|
||||
42
node_modules/@weborigami/origami/src/common/documentObject.js
generated
vendored
Normal file
42
node_modules/@weborigami/origami/src/common/documentObject.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import { isPlainObject, isUnpackable, toString } from "@weborigami/async-tree";
|
||||
// import txtHandler from "../builtins/txt.handler.js";
|
||||
|
||||
/**
|
||||
* In Origami, a text document object is any object with a `@text` property and
|
||||
* a pack() method that formats that object as text with YAML front matter. This
|
||||
* function is a helper for constructing such text document objects.
|
||||
*
|
||||
* @typedef {import("@weborigami/async-tree").StringLike} StringLike
|
||||
* @typedef {import("@weborigami/async-tree").PlainObject} PlainObject
|
||||
*
|
||||
* @param {StringLike|PlainObject} input
|
||||
* @param {any} [data]
|
||||
*/
|
||||
export default async function documentObject(input, data) {
|
||||
let text;
|
||||
let inputData;
|
||||
|
||||
if (isUnpackable(input)) {
|
||||
// Unpack the input first, might already be a document object.
|
||||
input = await input.unpack();
|
||||
}
|
||||
|
||||
if (isPlainObject(input)) {
|
||||
text = input["@text"];
|
||||
inputData = input;
|
||||
} else {
|
||||
text = toString(input);
|
||||
inputData = null;
|
||||
}
|
||||
// TODO: Either restore this code, or move responsibility for packing a
|
||||
// document to HandleExtensionsTransform set().
|
||||
// const base = {
|
||||
// pack() {
|
||||
// return txtHandler.pack(this);
|
||||
// },
|
||||
// };
|
||||
// const result = Object.create(base);
|
||||
const result = {};
|
||||
Object.assign(result, inputData, data, { "@text": text });
|
||||
return result;
|
||||
}
|
||||
26
node_modules/@weborigami/origami/src/common/fetchAndHandleExtension.js
generated
vendored
Normal file
26
node_modules/@weborigami/origami/src/common/fetchAndHandleExtension.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import { handleExtension } from "@weborigami/language";
|
||||
|
||||
/**
|
||||
* Fetch the resource at the given href.
|
||||
*
|
||||
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
||||
*
|
||||
* @this {AsyncTree|null}
|
||||
* @param {string} href
|
||||
*/
|
||||
export default async function fetchAndHandleExtension(href) {
|
||||
const response = await fetch(href);
|
||||
if (!response.ok) {
|
||||
return undefined;
|
||||
}
|
||||
let buffer = await response.arrayBuffer();
|
||||
|
||||
// Attach any loader defined for the file type.
|
||||
const url = new URL(href);
|
||||
const filename = url.pathname.split("/").pop();
|
||||
if (this && filename) {
|
||||
buffer = await handleExtension(this, buffer, filename);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
67
node_modules/@weborigami/origami/src/common/getTreeArgument.js
generated
vendored
Normal file
67
node_modules/@weborigami/origami/src/common/getTreeArgument.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
import { Tree, isUnpackable } from "@weborigami/async-tree";
|
||||
import assertTreeIsDefined from "./assertTreeIsDefined.js";
|
||||
|
||||
/**
|
||||
* Many Origami built-in functions accept an optional treelike object as their
|
||||
* first argument. If no tree is supplied, then the current context for the
|
||||
* Origami command is used as the tree.
|
||||
*
|
||||
* So the argument is optional -- but if supplied, it must be defined. The
|
||||
* caller should pass its `arguments` object to this function so that the actual
|
||||
* number of supplied arguments can be checked.
|
||||
*
|
||||
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
||||
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
||||
*
|
||||
* @param {AsyncTree|null} parent
|
||||
* @param {IArguments} args
|
||||
* @param {Treelike|undefined} treelike
|
||||
* @param {string} methodName
|
||||
* @param {boolean} [deep]
|
||||
* @returns {Promise<AsyncTree>}
|
||||
*/
|
||||
export default async function getTreeArgument(
|
||||
parent,
|
||||
args,
|
||||
treelike,
|
||||
methodName,
|
||||
deep
|
||||
) {
|
||||
assertTreeIsDefined(parent, methodName);
|
||||
|
||||
if (treelike !== undefined) {
|
||||
if (isUnpackable(treelike)) {
|
||||
treelike = await treelike.unpack();
|
||||
}
|
||||
if (Tree.isTreelike(treelike)) {
|
||||
const options = deep !== undefined ? { deep } : undefined;
|
||||
let tree = Tree.from(treelike, options);
|
||||
// If the tree was created from a treelike object and does not yet have a
|
||||
// parent, make the current tree its parent.
|
||||
if (!tree.parent && parent !== undefined) {
|
||||
if (parent !== null && !Tree.isAsyncTree(parent)) {
|
||||
throw new Error(
|
||||
`The parent argument passed to ${methodName} must be a tree.`
|
||||
);
|
||||
}
|
||||
tree.parent = parent;
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
throw new Error(
|
||||
`The first argument to ${methodName} must be a tree, like an array, object, or files.`
|
||||
);
|
||||
}
|
||||
|
||||
if (args.length === 0) {
|
||||
if (!parent) {
|
||||
// Should never happen because assertTreeIsDefined throws an exception.
|
||||
throw new Error(
|
||||
`${methodName} was called with no tree argument and no parent.`
|
||||
);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
throw new Error(`The first argument to ${methodName} was undefined.`);
|
||||
}
|
||||
38
node_modules/@weborigami/origami/src/common/processUnpackedContent.js
generated
vendored
Normal file
38
node_modules/@weborigami/origami/src/common/processUnpackedContent.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import { symbols, Tree } from "@weborigami/async-tree";
|
||||
import { builtinsTree } from "../internal.js";
|
||||
|
||||
/**
|
||||
* Perform any necessary post-processing on the unpacked content of a file. This
|
||||
* lets treat the contents of various file types consistently.
|
||||
*
|
||||
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
||||
*
|
||||
* @param {any} content
|
||||
* @param {AsyncTree|null} parent
|
||||
* @returns
|
||||
*/
|
||||
export default function processUnpackedContent(content, parent) {
|
||||
if (typeof content === "function") {
|
||||
// Bind the function to the parent as the `this` context.
|
||||
const target = parent ?? builtinsTree;
|
||||
const result = content.bind(target);
|
||||
if (content.code) {
|
||||
result.code = content.code;
|
||||
}
|
||||
return result;
|
||||
} else if (Tree.isAsyncTree(content) && !content.parent) {
|
||||
const result = Object.create(content);
|
||||
result.parent = parent;
|
||||
return result;
|
||||
} else if (Object.isExtensible(content) && !content[symbols.parent]) {
|
||||
Object.defineProperty(content, symbols.parent, {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
value: parent,
|
||||
writable: true,
|
||||
});
|
||||
return content;
|
||||
} else {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
7
node_modules/@weborigami/origami/src/common/serialize.d.ts
generated
vendored
Normal file
7
node_modules/@weborigami/origami/src/common/serialize.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { AsyncTree } from "@weborigami/types";
|
||||
import type { JsonValue } from "../../index.ts";
|
||||
|
||||
export function evaluateYaml(text: string, parent?: AsyncTree|null): Promise<JsonValue>;
|
||||
export function parseYaml(text: string): JsonValue|AsyncTree;
|
||||
export function toJson(obj: JsonValue | AsyncTree): Promise<string>;
|
||||
export function toYaml(obj: JsonValue | AsyncTree): Promise<string>;
|
||||
58
node_modules/@weborigami/origami/src/common/serialize.js
generated
vendored
Normal file
58
node_modules/@weborigami/origami/src/common/serialize.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @typedef {import("../../index.ts").JsonValue} JsonValue
|
||||
* @typedef {import("@weborigami/async-tree").PlainObject} PlainObject
|
||||
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
||||
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
||||
*/
|
||||
|
||||
import { Tree, toPlainValue } from "@weborigami/async-tree";
|
||||
import * as YAMLModule from "yaml";
|
||||
|
||||
// The "yaml" package doesn't seem to provide a default export that the browser can
|
||||
// recognize, so we have to handle two ways to accommodate Node and the browser.
|
||||
// @ts-ignore
|
||||
const YAML = YAMLModule.default ?? YAMLModule.YAML;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} text
|
||||
* @param {AsyncTree|null} [parent]
|
||||
*/
|
||||
export async function evaluateYaml(text, parent) {
|
||||
const data = parseYaml(String(text));
|
||||
if (Tree.isAsyncTree(data)) {
|
||||
data.parent = parent;
|
||||
return Tree.plain(data);
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @returns {JsonValue|AsyncTree}
|
||||
*/
|
||||
export function parseYaml(text) {
|
||||
return YAML.parse(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes an object as a JSON string.
|
||||
*
|
||||
* @param {any} obj
|
||||
*/
|
||||
export async function toJson(obj) {
|
||||
const serializable = await toPlainValue(obj);
|
||||
return JSON.stringify(serializable, null, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes an object as a JSON string.
|
||||
*
|
||||
* @param {any} obj
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function toYaml(obj) {
|
||||
const serializable = await toPlainValue(obj);
|
||||
return YAML.stringify(serializable);
|
||||
}
|
||||
7
node_modules/@weborigami/origami/src/common/utilities.d.ts
generated
vendored
Normal file
7
node_modules/@weborigami/origami/src/common/utilities.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
export function getDescriptor(object: any): string;
|
||||
export function hasNonPrintableCharacters(text: string): boolean;
|
||||
export function isTransformApplied(Transform: Function, object: any): boolean;
|
||||
export function toFunction(object: any): Function;
|
||||
export function toString(object: any): string|null;
|
||||
export function transformObject(Transform: Function, object: any): any;
|
||||
144
node_modules/@weborigami/origami/src/common/utilities.js
generated
vendored
Normal file
144
node_modules/@weborigami/origami/src/common/utilities.js
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
import {
|
||||
Tree,
|
||||
toString as asyncTreeToString,
|
||||
isPlainObject,
|
||||
isUnpackable,
|
||||
trailingSlash,
|
||||
} from "@weborigami/async-tree";
|
||||
import { symbols } from "@weborigami/language";
|
||||
import { basename } from "node:path";
|
||||
|
||||
// For a given tree, return some user-friendly descriptor
|
||||
export function getDescriptor(tree) {
|
||||
if ("path" in tree) {
|
||||
return trailingSlash.add(basename(tree.path));
|
||||
}
|
||||
|
||||
const source = tree[symbols.sourceSymbol];
|
||||
if (source) {
|
||||
// If the source looks like an identifier, use that.
|
||||
// TODO: Use real identifier parsing.
|
||||
const identifierRegex = /^[A-Za-z0-9_\-\.]+\/?$/;
|
||||
if (identifierRegex.test(source)) {
|
||||
return trailingSlash.add(source);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Return true if the text appears to contain non-printable binary characters;
|
||||
// used to infer whether a file is binary or text.
|
||||
export function hasNonPrintableCharacters(text) {
|
||||
// https://stackoverflow.com/a/1677660/76472
|
||||
return /[\x00-\x08\x0E-\x1F]/.test(text);
|
||||
}
|
||||
|
||||
export function isTransformApplied(Transform, obj) {
|
||||
let transformName = Transform.name;
|
||||
if (!transformName) {
|
||||
throw `isTransformApplied was called on an unnamed transform function, but a name is required.`;
|
||||
}
|
||||
if (transformName.endsWith("Transform")) {
|
||||
transformName = transformName.slice(0, -9);
|
||||
}
|
||||
// Walk up prototype chain looking for a constructor with the same name as the
|
||||
// transform. This is not a great test.
|
||||
for (let proto = obj; proto; proto = Object.getPrototypeOf(proto)) {
|
||||
if (proto.constructor.name === transformName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given object to a function.
|
||||
*
|
||||
* @typedef {import("../../index.ts").Invocable} Invocable
|
||||
* @param {any} obj
|
||||
* @returns {Function|null}
|
||||
*/
|
||||
export function toFunction(obj) {
|
||||
if (typeof obj === "function") {
|
||||
// Return a function as is.
|
||||
return obj;
|
||||
} else if (isUnpackable(obj)) {
|
||||
// Extract the contents of the object and convert that to a function.
|
||||
let fnPromise;
|
||||
/** @this {any} */
|
||||
return async function (...args) {
|
||||
if (!fnPromise) {
|
||||
// unpack() may return a function or a promise for a function; normalize
|
||||
// to a promise for a function
|
||||
const unpackPromise = Promise.resolve(obj.unpack());
|
||||
fnPromise = unpackPromise.then((content) => toFunction(content));
|
||||
}
|
||||
const fn = await fnPromise;
|
||||
return fn.call(this, ...args);
|
||||
};
|
||||
} else if (Tree.isTreelike(obj)) {
|
||||
// Return a function that invokes the tree's getter.
|
||||
return Tree.toFunction(obj);
|
||||
} else {
|
||||
// Not a function
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the async-tree toString method: objects that have a `@text` property
|
||||
* will return the value of that property as a string.
|
||||
*
|
||||
* @param {any} object
|
||||
* @returns {string|null}
|
||||
*/
|
||||
export function toString(object) {
|
||||
if (isPlainObject(object) && "@text" in object) {
|
||||
object = object["@text"];
|
||||
}
|
||||
return asyncTreeToString(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a functional class mixin to an individual object instance.
|
||||
*
|
||||
* This works by create an intermediate class, creating an instance of that, and
|
||||
* then setting the intermediate class's prototype to the given individual
|
||||
* object. The resulting, extended object is then returned.
|
||||
*
|
||||
* This manipulation of the prototype chain is generally sound in JavaScript,
|
||||
* with some caveats. In particular, the original object class cannot make
|
||||
* direct use of private members; JavaScript will complain if the extended
|
||||
* object does anything that requires access to those private members.
|
||||
*
|
||||
* @param {Function} Transform
|
||||
* @param {any} obj
|
||||
*/
|
||||
export function transformObject(Transform, obj) {
|
||||
// Apply the mixin to Object and instantiate that. The Object base class here
|
||||
// is going to be cut out of the prototype chain in a moment; we just use
|
||||
// Object as a convenience because its constructor takes no arguments.
|
||||
const mixed = new (Transform(Object))();
|
||||
|
||||
// Find the highest prototype in the chain that was added by the class mixin.
|
||||
// The mixin may have added multiple prototypes to the chain. Walk up the
|
||||
// prototype chain until we hit Object.
|
||||
let mixinProto = Object.getPrototypeOf(mixed);
|
||||
while (Object.getPrototypeOf(mixinProto) !== Object.prototype) {
|
||||
mixinProto = Object.getPrototypeOf(mixinProto);
|
||||
}
|
||||
|
||||
// Redirect the prototype chain above the mixin to point to the original
|
||||
// object. The mixed object now extends the original object with the mixin.
|
||||
Object.setPrototypeOf(mixinProto, obj);
|
||||
|
||||
// Create a new constructor for this mixed object that reflects its prototype
|
||||
// chain. Because we've already got the instance we want, we won't use this
|
||||
// constructor now, but this can be used later to instantiate other objects
|
||||
// that look like the mixed one.
|
||||
mixed.constructor = Transform(obj.constructor);
|
||||
|
||||
// Return the mixed object.
|
||||
return mixed;
|
||||
}
|
||||
Reference in New Issue
Block a user