Update plugin shape again
This commit is contained in:
parent
dfc65dacfa
commit
2d3ba356b5
5 changed files with 52 additions and 46 deletions
61
README.md
61
README.md
|
@ -1,20 +1,17 @@
|
||||||
# Muse
|
# Muse
|
||||||
|
|
||||||
A CLI for wrangling directories of source files.
|
_Bind data into anything_
|
||||||
|
|
||||||
Like a static generator, but for whatever.
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
**Muse** is a CLI and toolchain for operating on directories of
|
**Muse** is a CLI and toolchain for operating on data collected from
|
||||||
json, yaml, toml, and markdown files. Each file can specify any shape
|
json, yaml, toml, and markdown files.
|
||||||
of data. Muse scans included files, parses them into data, and streams
|
|
||||||
the loaded data through processors and plugins.
|
|
||||||
|
|
||||||
Each processor can modify the data at compile time, as well as enact
|
Muse scans included files, parses them into data, and streams
|
||||||
side effects such as writing files to disk.
|
the loaded data through plugins.
|
||||||
|
|
||||||
Muse does not edit source files, it only reads them in.
|
Each plugin can modify the data as well as enact side effects
|
||||||
|
such as writing files to disk.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -32,10 +29,9 @@ Options:
|
||||||
|
|
||||||
Each Muse project should specify a `binding` file with the following shape:
|
Each Muse project should specify a `binding` file with the following shape:
|
||||||
```yaml
|
```yaml
|
||||||
include:
|
sources: # Optional
|
||||||
- ../another-project # Optional
|
- file: "**/*.yaml"
|
||||||
files: # Optional
|
- web: "https://example.com/data.json"
|
||||||
- "**/*.yaml"
|
|
||||||
contentKey: "content" # Optional
|
contentKey: "content" # Optional
|
||||||
options: # Optional
|
options: # Optional
|
||||||
someOption: someValue
|
someOption: someValue
|
||||||
|
@ -44,9 +40,9 @@ processors:
|
||||||
- second-processor
|
- second-processor
|
||||||
```
|
```
|
||||||
|
|
||||||
The `binding` file can be any of the supported file types for Muse. If
|
The `binding` file can be any of the supported file types for Muse and can
|
||||||
the CLI is invoked with a directory instead of a file, Muse will look
|
be named anything. If the CLI is invoked with a directory instead of a file,
|
||||||
for a binding file in the directory with the following order:
|
Muse will look for a binding file in the directory with the following order:
|
||||||
|
|
||||||
1. `binding.json`
|
1. `binding.json`
|
||||||
2. `binding.yaml`
|
2. `binding.yaml`
|
||||||
|
@ -68,3 +64,34 @@ Your markdown content here
|
||||||
When loading markdown files, Muse will load the content of the file
|
When loading markdown files, Muse will load the content of the file
|
||||||
into a key called `content` by default. This can be changed in the binding
|
into a key called `content` by default. This can be changed in the binding
|
||||||
configuration by setting a `contentKey` value as an override.
|
configuration by setting a `contentKey` value as an override.
|
||||||
|
|
||||||
|
## Plugin API
|
||||||
|
|
||||||
|
Muse plugins are written in TypeScript/JavaScript and expose information
|
||||||
|
describing the plugin, as well as the functions to operate with:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export const name = "Plugin Name";
|
||||||
|
export const description = "Plugin Description";
|
||||||
|
export async function step(binding: Binding): Promise<Binding> {}
|
||||||
|
```
|
||||||
|
|
||||||
|
The main function of a plugin is `step`, which takes a `Binding` object
|
||||||
|
and returns a modified `Binding` object.
|
||||||
|
|
||||||
|
When returning a new Binding object, it is best practice to make immutable
|
||||||
|
changes:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export async function step(binding: Binding): Promise<Binding> {
|
||||||
|
const newBinding = { ...binding };
|
||||||
|
newBinding.options.someOption = "newValue";
|
||||||
|
return {
|
||||||
|
...binding,
|
||||||
|
meta: {
|
||||||
|
...binding.meta,
|
||||||
|
customValue: true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@endeavorance/muse",
|
"name": "@endeavorance/muse",
|
||||||
"version": "0.2.0",
|
"version": "0.3.0",
|
||||||
"module": "dist/index.js",
|
"module": "dist/index.js",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
|
|
|
@ -22,7 +22,7 @@ const BindingSchema = z.object({
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
options: z.record(z.string(), z.any()).default({}),
|
options: z.record(z.string(), z.any()).default({}),
|
||||||
processors: z.array(z.string()).default([]),
|
plugins: z.array(z.string()).default([]),
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,9 +31,6 @@ const BindingSchema = z.object({
|
||||||
* the project, and a list of entries to be processed
|
* the project, and a list of entries to be processed
|
||||||
*/
|
*/
|
||||||
export interface Binding<MetaShape = UnknownRecord> {
|
export interface Binding<MetaShape = UnknownRecord> {
|
||||||
/** The raw data read from the binding file */
|
|
||||||
readonly _raw: z.infer<typeof BindingSchema>;
|
|
||||||
|
|
||||||
/** Information about the sources used to load entries */
|
/** Information about the sources used to load entries */
|
||||||
readonly sources: MuseSource[];
|
readonly sources: MuseSource[];
|
||||||
|
|
||||||
|
@ -133,11 +130,10 @@ export async function loadBinding(initialPath: string): Promise<Binding> {
|
||||||
|
|
||||||
// Load and check plugins
|
// Load and check plugins
|
||||||
const plugins: MusePlugin[] = await Promise.all(
|
const plugins: MusePlugin[] = await Promise.all(
|
||||||
parsedBinding.processors.map(loadPlugin.bind(null, bindingDirname)),
|
parsedBinding.plugins.map(loadPlugin.bind(null, bindingDirname)),
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_raw: parsedBinding,
|
|
||||||
sources,
|
sources,
|
||||||
bindingPath,
|
bindingPath,
|
||||||
contentKey: parsedBinding.contentKey,
|
contentKey: parsedBinding.contentKey,
|
||||||
|
|
|
@ -5,5 +5,8 @@ export * from "#errors";
|
||||||
export const DEFAULT_CONTENT_KEY = "content";
|
export const DEFAULT_CONTENT_KEY = "content";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
export type * from "#types";
|
export type * from "#core/binding";
|
||||||
export type { MusePlugin } from "#core/plugins";
|
export type * from "#core/plugins";
|
||||||
|
export type * from "#core/sources";
|
||||||
|
export type * from "#core/records";
|
||||||
|
export type * from "#core/files";
|
||||||
|
|
20
src/muse.ts
20
src/muse.ts
|
@ -1,20 +0,0 @@
|
||||||
import type { Binding } from "#core/binding";
|
|
||||||
|
|
||||||
export class Muse {
|
|
||||||
bindingLoaded = false;
|
|
||||||
preliminaryBinding: Partial<Binding> = {};
|
|
||||||
additionalSources: string[] = [];
|
|
||||||
additionalPluginPaths: string[] = [];
|
|
||||||
|
|
||||||
constructor(bindingConfig: Partial<Binding>) {
|
|
||||||
this.preliminaryBinding = bindingConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
source(newSource: string) {
|
|
||||||
this.additionalSources.push(newSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin(pluginPath: string) {
|
|
||||||
this.additionalPluginPaths.push(pluginPath);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue