mirror of
https://github.com/modernweb-dev/rocket.git
synced 2026-03-21 15:54:57 +00:00
Compare commits
36 Commits
@mdjs/mdjs
...
@rocket/cl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c009801164 | ||
|
|
60310ab3dd | ||
|
|
db03f69210 | ||
|
|
e6c3d274cf | ||
|
|
f9014c15a6 | ||
|
|
7e277cd88f | ||
|
|
bc6106381c | ||
|
|
00bf3882f6 | ||
|
|
543e297c5b | ||
|
|
70b0ce8e1c | ||
|
|
9f8785a885 | ||
|
|
62637a829e | ||
|
|
81c4d7bf3c | ||
|
|
08181194e2 | ||
|
|
97cb38ccb8 | ||
|
|
26d3de1444 | ||
|
|
1f141058c1 | ||
|
|
08574c9b31 | ||
|
|
e81b77f236 | ||
|
|
456b8e78f0 | ||
|
|
0d7ea015af | ||
|
|
445b02872f | ||
|
|
1a599db3ed | ||
|
|
6b6bed5391 | ||
|
|
30eb822151 | ||
|
|
15a82c0e4d | ||
|
|
0197bee621 | ||
|
|
5c6b9c91eb | ||
|
|
6221e5f9ea | ||
|
|
06741ed729 | ||
|
|
23c164c822 | ||
|
|
c2a76c3f53 | ||
|
|
70bb7a128e | ||
|
|
3c342473d7 | ||
|
|
9e0579ab19 | ||
|
|
de202da0a5 |
@@ -8,25 +8,25 @@ First, create a fork of the [modernweb-dev/rocket](https://github.com/modernweb-
|
|||||||
|
|
||||||
Next, clone our repository onto your computer.
|
Next, clone our repository onto your computer.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
git clone git@github.com:modernweb-dev/rocket.git
|
git clone git@github.com:modernweb-dev/rocket.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Once cloning is complete, change directory to the repository.
|
Once cloning is complete, change directory to the repository.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
cd rocket
|
cd rocket
|
||||||
```
|
```
|
||||||
|
|
||||||
Now add your fork as a remote (replacing YOUR_USERNAME with your GitHub username).
|
Now add your fork as a remote (replacing YOUR_USERNAME with your GitHub username).
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
git remote add fork git@github.com:<YOUR_USERNAME>/rocket.git
|
git remote add fork git@github.com:<YOUR_USERNAME>/rocket.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a new local branch.
|
Create a new local branch.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
git checkout -b my-awesome-fix
|
git checkout -b my-awesome-fix
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ git checkout -b my-awesome-fix
|
|||||||
|
|
||||||
Now that you have cloned the repository, ensure you have [yarn](https://classic.yarnpkg.com/lang/en/) installed, then run the following commands to set up the development environment.
|
Now that you have cloned the repository, ensure you have [yarn](https://classic.yarnpkg.com/lang/en/) installed, then run the following commands to set up the development environment.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
yarn install
|
yarn install
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ This documents your intent to release, and allows you to specify a message that
|
|||||||
|
|
||||||
Run
|
Run
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
yarn changeset
|
yarn changeset
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ Exceptions:
|
|||||||
Commit messages must follow the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/)
|
Commit messages must follow the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/)
|
||||||
Modern-web uses package name as scope. So for example if you fix a _terrible bug_ in the package `@web/test-runner`, the commit message should look like this:
|
Modern-web uses package name as scope. So for example if you fix a _terrible bug_ in the package `@web/test-runner`, the commit message should look like this:
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
fix(test-runner): fix terrible bug
|
fix(test-runner): fix terrible bug
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ fix(test-runner): fix terrible bug
|
|||||||
|
|
||||||
Now it's time to push your branch that contains your committed changes to your fork.
|
Now it's time to push your branch that contains your committed changes to your fork.
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
git push -u fork my-awesome-fix
|
git push -u fork my-awesome-fix
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ The features so far are:
|
|||||||
|
|
||||||
It checks your final HTML output so you need to execute it after your Static Site Generator.
|
It checks your final HTML output so you need to execute it after your Static Site Generator.
|
||||||
|
|
||||||
```
|
```shell
|
||||||
npx check-html-links _site
|
npx check-html-links _site
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Use mdjs in your Eleventy site.
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
```
|
```shell
|
||||||
npm install @rocket/eleventy-plugin-mdjs
|
npm install @rocket/eleventy-plugin-mdjs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,68 @@ export const header = () => {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```js story-code
|
||||||
|
// not defined for android
|
||||||
|
```
|
||||||
|
|
||||||
|
```js story-code
|
||||||
|
// not defined for ios
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Story Code
|
||||||
|
|
||||||
|
If your preview is followed by a code blocks marked as `story-code` then those will be shown when switching between multiple platforms
|
||||||
|
|
||||||
|
````md
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () => html` <demo-wc-card>JS Preview Story</demo-wc-card> `;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoWcCard"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.FooComponents.Demo.Wc.Card"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import DemoWc.Card
|
||||||
|
|
||||||
|
let card = DemoWcButton()
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
See it in action by opening up the code block and switching platforms
|
||||||
|
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () => html` <demo-wc-card>JS Preview Story</demo-wc-card> `;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoWcCard"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.FooComponents.Demo.Wc.Card"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import DemoWc.Card
|
||||||
|
|
||||||
|
let card = DemoWcButton()
|
||||||
|
```
|
||||||
|
|
||||||
## Supported Systems
|
## Supported Systems
|
||||||
|
|
||||||
### Storybook
|
### Storybook
|
||||||
|
|||||||
@@ -40,6 +40,68 @@ will result in
|
|||||||
export const foo = () => html` <demo-element></demo-element> `;
|
export const foo = () => html` <demo-element></demo-element> `;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```js story-code
|
||||||
|
// not defined for android
|
||||||
|
```
|
||||||
|
|
||||||
|
```js story-code
|
||||||
|
// not defined for ios
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Story Code
|
||||||
|
|
||||||
|
If your preview is followed by a code blocks marked as `story-code` then those will be shown when switching between multiple platforms
|
||||||
|
|
||||||
|
````md
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () => html` <demo-element></demo-element> `;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoElement"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.Demo.Element"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import Demo.Element
|
||||||
|
|
||||||
|
let card = DemoElement()
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
See it in action by opening up the code block and switching platforms
|
||||||
|
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () => html` <demo-element></demo-element> `;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoElement"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.Demo.Element"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import Demo.Element
|
||||||
|
|
||||||
|
let card = DemoElement()
|
||||||
|
```
|
||||||
|
|
||||||
## HTML Story
|
## HTML Story
|
||||||
|
|
||||||
````md
|
````md
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# Presets >> Launch || 20
|
# Presets >> Launch || 20
|
||||||
|
|
||||||
- [Preset](./preset/)
|
- [Preset](./preset/)
|
||||||
- [Custom Elements](./custom-elements/)
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# Presets >> Search || 10
|
# Presets >> Search || 10
|
||||||
|
|
||||||
- [Preset](./preset/)
|
- [Preset](./preset/)
|
||||||
- [Custom Elements](./custom-elements/)
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ Read the [Introducing Check HTMl Links - no more bad links](../../blog/introduci
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```shell
|
||||||
npm i -D check-html-links
|
npm i -D check-html-links
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -3,20 +3,122 @@
|
|||||||
The Plugins Manager replaces the specific registration/execution (with options) in a given plugin system by an intend to use a plugin (with these options).
|
The Plugins Manager replaces the specific registration/execution (with options) in a given plugin system by an intend to use a plugin (with these options).
|
||||||
This allows your users to adjust the options before actually applying the plugins.
|
This allows your users to adjust the options before actually applying the plugins.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Install npm package
|
||||||
|
```bash
|
||||||
|
npm i plugins-manager
|
||||||
|
```
|
||||||
|
2. Change your public API from an array of plugin "instances" to an array of setup functions
|
||||||
|
```diff
|
||||||
|
import myPlugin from 'my-plugin';
|
||||||
|
+ import { addPlugin } from 'plugins-manager';
|
||||||
|
export default {
|
||||||
|
- plugins: [myPlugin],
|
||||||
|
+ setupPlugins: [addPlugin(myPlugin)]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
3. Convert setup function to plugins
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
|
const finalConfig = applyPlugins(config); // "converts" setupPlugins to plugins
|
||||||
|
|
||||||
|
// work with plugins or pass it on to another tool
|
||||||
|
const bundle = await rollup(finalConfig);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
As you users in most cases you will need to either add or adjust a given plugin in a config file.
|
||||||
|
|
||||||
|
👉 `my-tool.config.js`
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
||||||
|
import json from '@rollup/plugin-json';
|
||||||
|
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setupPlugins: [
|
||||||
|
// add a new plugin with optional plugin options
|
||||||
|
addPlugin(json, {
|
||||||
|
/* ... */
|
||||||
|
}),
|
||||||
|
|
||||||
|
// adjust the options of a plugin that is already registered
|
||||||
|
adjustPluginOptions(nodeResolve, {
|
||||||
|
/* ... */
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Plugins can be functions or classes
|
||||||
|
|
||||||
|
### Function Plugins
|
||||||
|
|
||||||
|
```js
|
||||||
|
function myPlugin({ lastName: 'initial-second' }) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setupPlugins: [addPlugin(myPlugin)],
|
||||||
|
};
|
||||||
|
|
||||||
|
// function parameters are type safe
|
||||||
|
addPlugin(myPlugin, { lastName: 'new name' }); // ts ok
|
||||||
|
addPlugin(myPlugin, { otherProp: 'new name' }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
|
### Class Plugins
|
||||||
|
|
||||||
|
The options are passed to the constructor.
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* @typedef {object} MyClassOptions
|
||||||
|
* @property {string} lastName
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MyClass {
|
||||||
|
/** @type {MyClassOptions} */
|
||||||
|
options = {
|
||||||
|
lastName: 'initial-second',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Partial<MyClassOptions>} options
|
||||||
|
*/
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.options = { ...this.options, ...options };
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setupPlugins: [addPlugin(MyClass)],
|
||||||
|
};
|
||||||
|
|
||||||
|
// constructor parameters are type safe
|
||||||
|
addPlugin(MyClass, { lastName: 'new name' }); // ts ok
|
||||||
|
addPlugin(MyClass, { otherProp: 'new name' }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
## Problem
|
## Problem
|
||||||
|
|
||||||
Many plugin systems require you to either execute a plugin function like in `rollup`.
|
Many plugin systems require you to either execute a plugin function like in `rollup`.
|
||||||
|
|
||||||
<!-- prettier-ignore-start -->
|
|
||||||
```js
|
```js
|
||||||
import json from '@rollup/plugin-json';
|
import json from '@rollup/plugin-json';
|
||||||
|
|
||||||
/** @type {import('rocket/cli').RocketCliConfig} */
|
export default /** @type {import('rocket/cli').RocketCliConfig} */ ({
|
||||||
export default ({
|
|
||||||
plugins: [json({ preferConst: true })],
|
plugins: [json({ preferConst: true })],
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
<!-- prettier-ignore-end -->
|
|
||||||
|
|
||||||
or add it in a special way like in `eleventy`
|
or add it in a special way like in `eleventy`
|
||||||
|
|
||||||
@@ -48,18 +150,14 @@ This means if you wish to define default plugins and allow your user to override
|
|||||||
|
|
||||||
The plugins manager lets you orchestrate a set of "meta plugins" which are defined by
|
The plugins manager lets you orchestrate a set of "meta plugins" which are defined by
|
||||||
|
|
||||||
- name
|
- plugin (class or function)
|
||||||
- plugin
|
- it's options
|
||||||
- options
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import beep from '@rollup/plugin-beep';
|
import beep from '@rollup/plugin-beep';
|
||||||
import url from '@rollup/plugin-url';
|
import url from '@rollup/plugin-url';
|
||||||
|
|
||||||
let metaPlugins = [
|
let metaPlugins = [{ plugin: beep }, { plugin: url, options: { limit: 10000 } }];
|
||||||
{ name: 'beep', plugin: beep },
|
|
||||||
{ name: 'url', plugin: url, options: { limit: 10000 } },
|
|
||||||
];
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This array can be modified by adding/removing or adjusting options.
|
This array can be modified by adding/removing or adjusting options.
|
||||||
@@ -94,16 +192,13 @@ export default {
|
|||||||
|
|
||||||
### Adding Helpers
|
### Adding Helpers
|
||||||
|
|
||||||
Doing array manipulations is kinda error-prone so we offer encourage to use an array of setup function. Where as each setup function can either add a new plugin (with a unique name) or adjust an already existing plugin.
|
Doing array manipulations is kinda error-prone so we encourage to use an array of setup function. Where as each setup function can either add a new plugin (with a unique name) or adjust an already existing plugin.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
const systemSetupFunctions = [
|
const systemSetupFunctions = [addPlugin(first), addPlugin(second)];
|
||||||
addPlugin({ name: 'first', plugin: first }),
|
const userSetupFunctions = [adjustPluginOptions(first, { my: 'options' })];
|
||||||
addPlugin({ name: 'second', plugin: second }),
|
|
||||||
];
|
|
||||||
const userSetupFunctions = [adjustPluginOptions('first', { my: 'options' })];
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Arrays of functions can by merged like so
|
Arrays of functions can by merged like so
|
||||||
@@ -115,9 +210,9 @@ const finalSetupFunctions = [...systemSetupFunctions, ...userSetupFunctions];
|
|||||||
and then converted to the final output.
|
and then converted to the final output.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { metaPluginsToRollupPlugins } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
const plugins = metaPluginsToRollupPlugins(finalSetupFunctions, metaPlugins);
|
const plugins = applyPlugins(finalSetupFunctions, metaPlugins);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding a Plugin
|
## Adding a Plugin
|
||||||
@@ -133,18 +228,39 @@ By default it adds at the bottom.
|
|||||||
import json from '@rollup/plugin-json';
|
import json from '@rollup/plugin-json';
|
||||||
import { addPlugin } from 'plugins-manager';
|
import { addPlugin } from 'plugins-manager';
|
||||||
|
|
||||||
const userSetupFunctions = [
|
const userSetupFunctions = [addPlugin(json, { preferConst: true })];
|
||||||
addPlugin({ name: 'json', plugin: json, options: { preferConst: true } }),
|
|
||||||
];
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
addPlugin({ name: 'json', plugin: json }); // Add at the bottom (default)
|
addPlugin(json); // Add at the bottom (default)
|
||||||
addPlugin({ name: 'json', plugin: json, location: 'top' }); // Add at the top/beginning of the array
|
addPlugin(json, {}, { location: 'top' }); // Add at the top/beginning of the array
|
||||||
addPlugin({ name: 'json', plugin: json, location: 'beep' }); // Add after (default) plugin 'beep'
|
addPlugin(json, {}, { location: beep }); // Add after (default) plugin 'beep'
|
||||||
addPlugin({ name: 'json', plugin: json, location: 'beep', how: 'before' }); // Add before plugin 'beep'
|
addPlugin(json, {}, { location: beep, how: 'before' }); // Add before plugin 'beep'
|
||||||
|
```
|
||||||
|
|
||||||
|
This is type safe and typescript will throw an error if you pass the wrong type.
|
||||||
|
|
||||||
|
```js
|
||||||
|
function myPlugin({ myFlag = false } = {}) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
addPlugin(myPlugin, { myFlag: true }); // ts ok
|
||||||
|
addPlugin(myPlugin, { notExisting: true }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: There is a "hidden" feature in addPlugin that if you attach a `wrapPlugin` property to the returning function it will call `wrapPlugin` on the plugin before adding it.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// example auto wrap rollup plugins for @web/dev-server
|
||||||
|
import { fromRollup } from '@web/dev-server-rollup';
|
||||||
|
|
||||||
|
const userSetupFunctions = [addPlugin(json)].map(mod => {
|
||||||
|
mod.wrapPlugin = fromRollup;
|
||||||
|
return mod;
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adjusting Plugin Options
|
## Adjusting Plugin Options
|
||||||
@@ -154,12 +270,14 @@ Adjusting options means to either
|
|||||||
- flatly merge objects (e.g. only the first level will be preserved)
|
- flatly merge objects (e.g. only the first level will be preserved)
|
||||||
- calling a function to do the merge yourself
|
- calling a function to do the merge yourself
|
||||||
- setting the raw value (if not an object or function)
|
- setting the raw value (if not an object or function)
|
||||||
|
- you need to have a reference to the plugin (which is used to auto complete the available options via typescript)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import json from '@rollup/plugin-json';
|
||||||
import { adjustPluginOptions } from 'plugins-manager';
|
import { adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
const userSetupFunctions = [
|
const userSetupFunctions = [
|
||||||
adjustPluginOptions('json', { preferConst: false, anotherOption: 'format' }),
|
adjustPluginOptions(json, { preferConst: false, anotherOption: 'format' }),
|
||||||
];
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -167,36 +285,53 @@ Example usage:
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// given
|
// given
|
||||||
addPlugin({
|
addPlugin(json, {
|
||||||
name: 'json',
|
other: {
|
||||||
plugin: json,
|
nested: 'other.nested',
|
||||||
options: {
|
nested2: 'other.nested2',
|
||||||
other: {
|
|
||||||
nested: 'other.nested',
|
|
||||||
nested2: 'other.nested2',
|
|
||||||
},
|
|
||||||
main: true,
|
|
||||||
},
|
},
|
||||||
|
main: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// merge objects flately
|
// merge objects flately
|
||||||
adjustPluginOptions('json', { other: { nested: '--overwritten--' } });
|
adjustPluginOptions(json, { other: { nested: '--overwritten--' } });
|
||||||
// resulting options = { other: { nested: '--overwritten--' }, main: true }
|
// resulting options = { other: { nested: '--overwritten--' }, main: true }
|
||||||
// NOTE: nested2 is removed
|
// NOTE: nested2 is removed
|
||||||
|
|
||||||
// merge via function
|
// merge via function
|
||||||
adjustPluginOptions('json', config => ({ other: { ...config.other, nested: '--overwritten--' } }));
|
adjustPluginOptions(json, config => ({ other: { ...config.other, nested: '--overwritten--' } }));
|
||||||
// resulting options = { other: { nested: '--overwritten--', nested2: 'other.nested2' }, main: true }
|
// resulting options = { other: { nested: '--overwritten--', nested2: 'other.nested2' }, main: true }
|
||||||
|
|
||||||
// merge via function to override full options
|
// merge via function to override full options
|
||||||
adjustPluginOptions('json', config => ({ only: 'this' }));
|
adjustPluginOptions(json, config => ({ only: 'this' }));
|
||||||
// resulting options = { only: 'this' }
|
// resulting options = { only: 'this' }
|
||||||
|
|
||||||
// setting a raw value
|
// setting a raw value
|
||||||
adjustPluginOptions('json', false);
|
adjustPluginOptions(json, false);
|
||||||
// resulting options = false
|
// resulting options = false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This is type safe and typescript will throw an error if you pass the wrong type.
|
||||||
|
|
||||||
|
```js
|
||||||
|
function myPlugin({ myFlag = false } = {}) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustPluginOptions(myPlugin, { myFlag: true }); // ts ok
|
||||||
|
adjustPluginOptions(myPlugin, { notExisting: true }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
|
## Remove Plugin
|
||||||
|
|
||||||
|
Sometimes you would like to remove a default plugin from the config.
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
setupPlugins: [removePlugin(json)],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## Converting metaPlugins to an Actual Plugin
|
## Converting metaPlugins to an Actual Plugin
|
||||||
|
|
||||||
To execute all setup function you can use this little helper
|
To execute all setup function you can use this little helper
|
||||||
@@ -227,25 +362,9 @@ Rollup has a more specific helper that handles
|
|||||||
Note: if you provide `config.plugins` then it will return that directly ignoring `setupPlugins`
|
Note: if you provide `config.plugins` then it will return that directly ignoring `setupPlugins`
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { metaConfigToRollupConfig } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
const finalConfig = metaConfigToRollupConfig(currentConfig, defaultMetaPlugins);
|
const finalConfig = applyPlugins(currentConfig, defaultMetaPlugins);
|
||||||
```
|
|
||||||
|
|
||||||
Web Dev Server has a more specific helper that handles
|
|
||||||
|
|
||||||
- `config.setupPlugins`
|
|
||||||
- `config.setupRollupPlugins`
|
|
||||||
|
|
||||||
Note: if you provide `config.plugins` then it will return that directly ignoring `setupPlugins` and `setupRollupPlugins`
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { metaConfigToWebDevServerConfig } from 'plugins-manager';
|
|
||||||
import { fromRollup } from '@web/dev-server-rollup';
|
|
||||||
|
|
||||||
const finalConfig = metaConfigToWebDevServerConfig(currentConfig, defaultMetaPlugins, {
|
|
||||||
rollupWrapperFunction: fromRollup,
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Eleventy
|
Eleventy
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Will be ordered as `First`, `Second`,
|
|||||||
|
|
||||||
Internally `# Foo >> Bar >> Baz ||20` gets converted to.
|
Internally `# Foo >> Bar >> Baz ||20` gets converted to.
|
||||||
|
|
||||||
```
|
```yml
|
||||||
---
|
---
|
||||||
title: Bar: Baz
|
title: Bar: Baz
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
|
|||||||
4
netlify.toml
Normal file
4
netlify.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[[headers]]
|
||||||
|
for = "/*"
|
||||||
|
[headers.values]
|
||||||
|
Content-Security-Policy = "default-src 'self'; script-src 'self' www.googletagmanager.com 'sha256-W6Gq+BvrdAAMbF8E7WHA7UPQxuUOfJM8E9mpKD0oihA=' 'sha256-vFU+IJ5dUUukI5Varwy49dN2d89DmFj7UNewqQv88sw='; style-src 'self' 'unsafe-inline' fonts.googleapis.com; font-src 'self' data: fonts.gstatic.com;"
|
||||||
13
package.json
13
package.json
@@ -33,8 +33,8 @@
|
|||||||
"setup": "npm run setup:ts-configs && npm run build:packages",
|
"setup": "npm run setup:ts-configs && npm run build:packages",
|
||||||
"setup:patches": "npx patch-package",
|
"setup:patches": "npx patch-package",
|
||||||
"setup:ts-configs": "node scripts/generate-ts-configs.mjs",
|
"setup:ts-configs": "node scripts/generate-ts-configs.mjs",
|
||||||
"prestart": "yarn analyze",
|
"xprestart": "yarn analyze",
|
||||||
"start": "node packages/cli/src/cli.js start",
|
"start": "node --trace-warnings packages/cli/src/cli.js start",
|
||||||
"test": "yarn test:node && yarn test:web",
|
"test": "yarn test:node && yarn test:web",
|
||||||
"test:node": "mocha \"packages/*/test-node/**/*.test.{ts,js,mjs,cjs}\" --timeout 5000 --reporter dot --exit",
|
"test:node": "mocha \"packages/*/test-node/**/*.test.{ts,js,mjs,cjs}\" --timeout 5000 --reporter dot --exit",
|
||||||
"test:web": "web-test-runner",
|
"test:web": "web-test-runner",
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
"update-package-configs": "node scripts/update-package-configs.mjs && yarn format"
|
"update-package-configs": "node scripts/update-package-configs.mjs && yarn format"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.12.0",
|
"@changesets/cli": "^2.20.0",
|
||||||
"@custom-elements-manifest/analyzer": "^0.4.12",
|
"@custom-elements-manifest/analyzer": "^0.4.12",
|
||||||
"@open-wc/testing": "^3.0.0-next.1",
|
"@open-wc/testing": "^3.0.0-next.1",
|
||||||
"@rollup/plugin-commonjs": "^17.0.0",
|
"@rollup/plugin-commonjs": "^17.0.0",
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
"@typescript-eslint/parser": "^4.13.0",
|
"@typescript-eslint/parser": "^4.13.0",
|
||||||
"@web/test-runner": "^0.12.2",
|
"@web/test-runner": "^0.12.2",
|
||||||
"@web/test-runner-commands": "^0.4.0",
|
"@web/test-runner-commands": "^0.4.0",
|
||||||
"@web/test-runner-playwright": "^0.8.0",
|
"@web/test-runner-playwright": "^0.8.8",
|
||||||
"cem-plugin-readme": "^0.1.3",
|
"cem-plugin-readme": "^0.1.3",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"concurrently": "^5.3.0",
|
"concurrently": "^5.3.0",
|
||||||
@@ -75,16 +75,15 @@
|
|||||||
"husky": "^4.3.7",
|
"husky": "^4.3.7",
|
||||||
"lint-staged": "^10.5.3",
|
"lint-staged": "^10.5.3",
|
||||||
"mocha": "^8.2.1",
|
"mocha": "^8.2.1",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.7",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"onchange": "^7.1.0",
|
"onchange": "^7.1.0",
|
||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
"prettier-plugin-package": "^1.3.0",
|
"prettier-plugin-package": "^1.3.0",
|
||||||
|
"publish-docs": "^0.1.2",
|
||||||
"puppeteer": "^9.0.0",
|
"puppeteer": "^9.0.0",
|
||||||
"remark-emoji": "^2.1.0",
|
"remark-emoji": "^2.1.0",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rocket-preset-code-tabs": "^0.2.6",
|
|
||||||
"rocket-preset-custom-elements-manifest": "^0.1.7",
|
|
||||||
"rollup": "^2.36.1",
|
"rollup": "^2.36.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"sinon": "^9.2.3",
|
"sinon": "^9.2.3",
|
||||||
|
|||||||
@@ -1,5 +1,32 @@
|
|||||||
# @rocket/blog
|
# @rocket/blog
|
||||||
|
|
||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Update to latest plugins manager to get type safe options
|
||||||
|
|
||||||
|
There is no longer a name string as a key for a plugin. It is identified by it's function/class. You will need to adjust your code if you are adding or adjusting plugins.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please see the [Changelog](https://github.com/modernweb-dev/rocket/blob/main/packages/plugins-manager/CHANGELOG.md#030) of the plugins-manager package.
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- plugins-manager@0.3.0
|
||||||
|
|
||||||
## 0.3.3
|
## 0.3.3
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/blog",
|
"name": "@rocket/blog",
|
||||||
"version": "0.3.3",
|
"version": "0.4.0",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -38,6 +38,6 @@
|
|||||||
"testing"
|
"testing"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"plugins-manager": "^0.2.4"
|
"plugins-manager": "^0.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,6 @@ export function rocketBlog({ section = SECTION, postCollection = POST_COLLECTION
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
path: path.resolve(__dirname),
|
path: path.resolve(__dirname),
|
||||||
setupEleventyPlugins: [addPlugin({ name: 'rocket-blog', plugin: eleventyPluginRocketBlog })],
|
setupEleventyPlugins: [addPlugin(eleventyPluginRocketBlog)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,22 @@
|
|||||||
# @rocket/building-rollup
|
# @rocket/building-rollup
|
||||||
|
|
||||||
|
## 0.4.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Update to latest plugins manager to get type safe options
|
||||||
|
|
||||||
|
There is no longer a name string as a key for a plugin. It is identified by it's function/class. You will need to adjust your code if you are adding or adjusting plugins.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please see the [Changelog](https://github.com/modernweb-dev/rocket/blob/main/packages/plugins-manager/CHANGELOG.md#030) of the plugins-manager package.
|
||||||
|
|
||||||
## 0.3.1
|
## 0.3.1
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/building-rollup",
|
"name": "@rocket/building-rollup",
|
||||||
"version": "0.3.1",
|
"version": "0.4.0",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import resolve from '@rollup/plugin-node-resolve';
|
|||||||
import { terser } from 'rollup-plugin-terser';
|
import { terser } from 'rollup-plugin-terser';
|
||||||
import babelPkg from '@rollup/plugin-babel';
|
import babelPkg from '@rollup/plugin-babel';
|
||||||
|
|
||||||
import { metaConfigToRollupConfig } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
const { babel } = babelPkg;
|
const { babel } = babelPkg;
|
||||||
|
|
||||||
export function createBasicConfig(userConfig) {
|
export function createBasicConfig(userConfig) {
|
||||||
const { config, metaPlugins } = createBasicMetaConfig(userConfig);
|
const { config, metaPlugins } = createBasicMetaConfig(userConfig);
|
||||||
return metaConfigToRollupConfig(config, metaPlugins);
|
return applyPlugins(config, metaPlugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBasicMetaConfig(userConfig = { output: {} }) {
|
export function createBasicMetaConfig(userConfig = { output: {} }) {
|
||||||
@@ -39,14 +39,12 @@ export function createBasicMetaConfig(userConfig = { output: {} }) {
|
|||||||
|
|
||||||
let metaPlugins = [
|
let metaPlugins = [
|
||||||
{
|
{
|
||||||
name: 'node-resolve',
|
|
||||||
plugin: resolve,
|
plugin: resolve,
|
||||||
options: {
|
options: {
|
||||||
moduleDirectories: ['node_modules', 'web_modules'],
|
moduleDirectories: ['node_modules', 'web_modules'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'babel',
|
|
||||||
plugin: babel,
|
plugin: babel,
|
||||||
options: {
|
options: {
|
||||||
babelHelpers: 'bundled',
|
babelHelpers: 'bundled',
|
||||||
@@ -73,7 +71,6 @@ export function createBasicMetaConfig(userConfig = { output: {} }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'terser',
|
|
||||||
plugin: terser,
|
plugin: terser,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { createSpaMetaConfig } from './createSpaConfig.js';
|
import { createSpaMetaConfig } from './createSpaConfig.js';
|
||||||
import { adjustPluginOptions, metaConfigToRollupConfig } from 'plugins-manager';
|
import { adjustPluginOptions, applyPlugins } from 'plugins-manager';
|
||||||
|
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
||||||
|
|
||||||
export function createMpaConfig(userConfig) {
|
export function createMpaConfig(userConfig) {
|
||||||
const { config, metaPlugins } = createMpaMetaConfig(userConfig);
|
const { config, metaPlugins } = createMpaMetaConfig(userConfig);
|
||||||
|
|
||||||
const final = metaConfigToRollupConfig(config, metaPlugins);
|
const final = applyPlugins(config, metaPlugins);
|
||||||
return final;
|
return final;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,7 +13,7 @@ export function createMpaMetaConfig(userConfig = { output: {}, setupPlugins: []
|
|||||||
const { config, metaPlugins } = createSpaMetaConfig(userConfig);
|
const { config, metaPlugins } = createSpaMetaConfig(userConfig);
|
||||||
|
|
||||||
config.setupPlugins = [
|
config.setupPlugins = [
|
||||||
adjustPluginOptions('html', {
|
adjustPluginOptions(rollupPluginHTML, {
|
||||||
flattenOutput: false,
|
flattenOutput: false,
|
||||||
}),
|
}),
|
||||||
...config.setupPlugins,
|
...config.setupPlugins,
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import { terser } from 'rollup-plugin-terser';
|
|||||||
import babelPkg from '@rollup/plugin-babel';
|
import babelPkg from '@rollup/plugin-babel';
|
||||||
import replace from '@rollup/plugin-replace';
|
import replace from '@rollup/plugin-replace';
|
||||||
|
|
||||||
import { metaConfigToRollupConfig } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
const { babel } = babelPkg;
|
const { babel } = babelPkg;
|
||||||
|
|
||||||
export function createServiceWorkerConfig(userConfig) {
|
export function createServiceWorkerConfig(userConfig) {
|
||||||
const { config, metaPlugins } = createServiceWorkerMetaConfig(userConfig);
|
const { config, metaPlugins } = createServiceWorkerMetaConfig(userConfig);
|
||||||
return metaConfigToRollupConfig(config, metaPlugins);
|
return applyPlugins(config, metaPlugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createServiceWorkerMetaConfig(userConfig = { output: {} }) {
|
export function createServiceWorkerMetaConfig(userConfig = { output: {} }) {
|
||||||
@@ -33,21 +33,19 @@ export function createServiceWorkerMetaConfig(userConfig = { output: {} }) {
|
|||||||
|
|
||||||
let metaPlugins = [
|
let metaPlugins = [
|
||||||
{
|
{
|
||||||
name: 'node-resolve',
|
|
||||||
plugin: resolve,
|
plugin: resolve,
|
||||||
options: {
|
options: {
|
||||||
moduleDirectories: ['node_modules', 'web_modules'],
|
moduleDirectories: ['node_modules', 'web_modules'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'replace',
|
|
||||||
plugin: replace,
|
plugin: replace,
|
||||||
options: {
|
options: {
|
||||||
'process.env.NODE_ENV': JSON.stringify(developmentMode ? 'development' : 'production'),
|
'process.env.NODE_ENV': JSON.stringify(developmentMode ? 'development' : 'production'),
|
||||||
|
preventAssignment: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'babel',
|
|
||||||
plugin: babel,
|
plugin: babel,
|
||||||
options: {
|
options: {
|
||||||
babelHelpers: 'bundled',
|
babelHelpers: 'bundled',
|
||||||
@@ -74,7 +72,6 @@ export function createServiceWorkerMetaConfig(userConfig = { output: {} }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'terser',
|
|
||||||
plugin: terser,
|
plugin: terser,
|
||||||
options: {
|
options: {
|
||||||
mangle: {
|
mangle: {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
||||||
import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets';
|
import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets';
|
||||||
import { polyfillsLoader } from '@web/rollup-plugin-polyfills-loader';
|
import { polyfillsLoader } from '@web/rollup-plugin-polyfills-loader';
|
||||||
import { metaConfigToRollupConfig } from 'plugins-manager';
|
import { applyPlugins } from 'plugins-manager';
|
||||||
|
|
||||||
import { createBasicMetaConfig } from './createBasicConfig.js';
|
import { createBasicMetaConfig } from './createBasicConfig.js';
|
||||||
|
|
||||||
export function createSpaConfig(userConfig) {
|
export function createSpaConfig(userConfig) {
|
||||||
const { config, metaPlugins } = createSpaMetaConfig(userConfig);
|
const { config, metaPlugins } = createSpaMetaConfig(userConfig);
|
||||||
return metaConfigToRollupConfig(config, metaPlugins);
|
return applyPlugins(config, metaPlugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSpaMetaConfig(userConfig = { output: {} }) {
|
export function createSpaMetaConfig(userConfig = { output: {} }) {
|
||||||
@@ -30,7 +30,6 @@ export function createSpaMetaConfig(userConfig = { output: {} }) {
|
|||||||
const spaMetaPlugins = [
|
const spaMetaPlugins = [
|
||||||
...metaPlugins,
|
...metaPlugins,
|
||||||
{
|
{
|
||||||
name: 'html',
|
|
||||||
plugin: rollupPluginHTML,
|
plugin: rollupPluginHTML,
|
||||||
options: {
|
options: {
|
||||||
rootDir,
|
rootDir,
|
||||||
@@ -38,11 +37,9 @@ export function createSpaMetaConfig(userConfig = { output: {} }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'import-meta-assets',
|
|
||||||
plugin: importMetaAssets,
|
plugin: importMetaAssets,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'polyfills-loader',
|
|
||||||
plugin: polyfillsLoader,
|
plugin: polyfillsLoader,
|
||||||
options: {
|
options: {
|
||||||
polyfills: {},
|
polyfills: {},
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ A fast checker for broken links/references in HTML.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```
|
```shell
|
||||||
npm i -D check-html-links
|
npm i -D check-html-links
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```bash
|
||||||
npx check-html-links _site
|
npx check-html-links _site
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,55 @@
|
|||||||
# @rocket/cli
|
# @rocket/cli
|
||||||
|
|
||||||
|
## 0.10.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 60310ab: Improve performance by initializing sax-wasm only once even when it is running in parallel
|
||||||
|
- Updated dependencies [60310ab]
|
||||||
|
- @rocket/eleventy-rocket-nav@0.3.1
|
||||||
|
|
||||||
|
## 0.10.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 15a82c0: Enable including script files into the simulator via `<script src=".." mdjs-use>`
|
||||||
|
- 15a82c0: Allow only a limited set of characters for simulator includes `[a-zA-Z0-9\/\-_]`.
|
||||||
|
Notably, there is no:
|
||||||
|
|
||||||
|
- `:` to prevent `http://...` includes
|
||||||
|
- `.` so filenames as `this.is.my.js` are not supported. Also includes will be without file endings which will be added automatically
|
||||||
|
|
||||||
|
## 0.10.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Update to latest plugins manager to get type safe options
|
||||||
|
|
||||||
|
There is no longer a name string as a key for a plugin. It is identified by it's function/class. You will need to adjust your code if you are adding or adjusting plugins.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please see the [Changelog](https://github.com/modernweb-dev/rocket/blob/main/packages/plugins-manager/CHANGELOG.md#030) of the plugins-manager package.
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- plugins-manager@0.3.0
|
||||||
|
- @rocket/eleventy-plugin-mdjs-unified@0.6.0
|
||||||
|
- @rocket/building-rollup@0.4.0
|
||||||
|
|
||||||
## 0.9.11
|
## 0.9.11
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,10 +1,26 @@
|
|||||||
const { setComputedConfig, getComputedConfig } = require('./src/public/computedConfig.cjs');
|
const { setComputedConfig, getComputedConfig } = require('./src/public/computedConfig.cjs');
|
||||||
const { generateEleventyComputed } = require('./src/public/generateEleventyComputed.cjs');
|
const {
|
||||||
|
generateEleventyComputed,
|
||||||
|
LayoutPlugin,
|
||||||
|
TitleMetaPlugin,
|
||||||
|
TitlePlugin,
|
||||||
|
EleventyNavigationPlugin,
|
||||||
|
SectionPlugin,
|
||||||
|
SocialMediaImagePlugin,
|
||||||
|
JoiningBlocksPlugin,
|
||||||
|
} = require('./src/public/generateEleventyComputed.cjs');
|
||||||
const { createSocialImage } = require('./src/public/createSocialImage.cjs');
|
const { createSocialImage } = require('./src/public/createSocialImage.cjs');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
setComputedConfig,
|
setComputedConfig,
|
||||||
getComputedConfig,
|
getComputedConfig,
|
||||||
generateEleventyComputed,
|
generateEleventyComputed,
|
||||||
|
LayoutPlugin,
|
||||||
|
TitleMetaPlugin,
|
||||||
|
TitlePlugin,
|
||||||
|
EleventyNavigationPlugin,
|
||||||
|
SectionPlugin,
|
||||||
|
SocialMediaImagePlugin,
|
||||||
|
JoiningBlocksPlugin,
|
||||||
createSocialImage,
|
createSocialImage,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,16 @@
|
|||||||
/** @typedef {import('@rocket/cli/types/main').RocketCliOptions} RocketCliOptions */
|
/** @typedef {import('@rocket/cli/types/main').RocketCliOptions} RocketCliOptions */
|
||||||
|
|
||||||
|
export { setComputedConfig, getComputedConfig } from './src/public/computedConfig.cjs';
|
||||||
|
export {
|
||||||
|
generateEleventyComputed,
|
||||||
|
LayoutPlugin,
|
||||||
|
TitleMetaPlugin,
|
||||||
|
TitlePlugin,
|
||||||
|
EleventyNavigationPlugin,
|
||||||
|
SectionPlugin,
|
||||||
|
SocialMediaImagePlugin,
|
||||||
|
JoiningBlocksPlugin,
|
||||||
|
} from './src/public/generateEleventyComputed.cjs';
|
||||||
|
export { createSocialImage } from './src/public/createSocialImage.cjs';
|
||||||
|
|
||||||
export { RocketCli } from './src/RocketCli.js';
|
export { RocketCli } from './src/RocketCli.js';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/cli",
|
"name": "@rocket/cli",
|
||||||
"version": "0.9.11",
|
"version": "0.10.2",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -57,10 +57,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@11ty/eleventy": "^0.11.1",
|
"@11ty/eleventy": "^0.11.1",
|
||||||
"@11ty/eleventy-img": "^0.9.0",
|
"@11ty/eleventy-img": "^0.9.0",
|
||||||
"@rocket/building-rollup": "^0.3.1",
|
"@rocket/building-rollup": "^0.4.0",
|
||||||
"@rocket/core": "^0.1.2",
|
"@rocket/core": "^0.1.2",
|
||||||
"@rocket/eleventy-plugin-mdjs-unified": "^0.5.2",
|
"@rocket/eleventy-plugin-mdjs-unified": "^0.6.0",
|
||||||
"@rocket/eleventy-rocket-nav": "^0.3.0",
|
"@rocket/eleventy-rocket-nav": "^0.3.1",
|
||||||
"@rollup/plugin-babel": "^5.2.2",
|
"@rollup/plugin-babel": "^5.2.2",
|
||||||
"@rollup/plugin-node-resolve": "^11.0.1",
|
"@rollup/plugin-node-resolve": "^11.0.1",
|
||||||
"@web/config-loader": "^0.1.3",
|
"@web/config-loader": "^0.1.3",
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
"command-line-usage": "^6.1.1",
|
"command-line-usage": "^6.1.1",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"micromatch": "^4.0.2",
|
"micromatch": "^4.0.2",
|
||||||
"plugins-manager": "^0.2.4",
|
"plugins-manager": "^0.3.0",
|
||||||
"slash": "^3.0.0",
|
"slash": "^3.0.0",
|
||||||
"utf8": "^3.0.0",
|
"utf8": "^3.0.0",
|
||||||
"workbox-window": "^6.1.5"
|
"workbox-window": "^6.1.5"
|
||||||
|
|||||||
@@ -14,19 +14,37 @@
|
|||||||
<script type="module">
|
<script type="module">
|
||||||
import { render } from '@mdjs/mdjs-story';
|
import { render } from '@mdjs/mdjs-story';
|
||||||
|
|
||||||
|
function sanitize(input, type) {
|
||||||
|
return `${document.location.origin}/${input.match(/[a-zA-Z0-9\/\-_]*/)[0]}.${type}`;
|
||||||
|
}
|
||||||
|
|
||||||
async function onHashChange() {
|
async function onHashChange() {
|
||||||
const urlParts = new URLSearchParams(document.location.hash.substr(1));
|
const urlParts = new URLSearchParams(document.location.hash.substr(1));
|
||||||
|
|
||||||
if (urlParts.get('stylesheets')) {
|
if (urlParts.get('stylesheets')) {
|
||||||
for (const stylesheet of urlParts.getAll('stylesheets')) {
|
for (const stylesheet of urlParts.getAll('stylesheets')) {
|
||||||
if (!document.querySelector(`link[rel="stylesheet"][href="${stylesheet}"]`)) {
|
const safeStylesheetUrl = sanitize(stylesheet, 'css');
|
||||||
|
if (!document.querySelector(`link[rel="stylesheet"][href="${safeStylesheetUrl}"]`)) {
|
||||||
const link = document.createElement('link');
|
const link = document.createElement('link');
|
||||||
link.rel = 'stylesheet';
|
link.rel = 'stylesheet';
|
||||||
link.href = stylesheet;
|
link.href = safeStylesheetUrl;
|
||||||
document.head.appendChild(link);
|
document.head.appendChild(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (urlParts.get('moduleUrls')) {
|
||||||
|
for (const moduleUrl of urlParts.getAll('moduleUrls')) {
|
||||||
|
const safeModuleUrl = sanitize(moduleUrl, 'js');
|
||||||
|
if (!document.querySelector(`script[type=module][src="${safeModuleUrl}"]`)) {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.type = 'module';
|
||||||
|
script.src = safeModuleUrl;
|
||||||
|
document.head.appendChild(script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (urlParts.get('theme')) {
|
if (urlParts.get('theme')) {
|
||||||
document.documentElement.setAttribute('theme', urlParts.get('theme'));
|
document.documentElement.setAttribute('theme', urlParts.get('theme'));
|
||||||
}
|
}
|
||||||
@@ -46,7 +64,8 @@
|
|||||||
document.documentElement.removeAttribute('edge-distance');
|
document.documentElement.removeAttribute('edge-distance');
|
||||||
}
|
}
|
||||||
|
|
||||||
const mod = await import(urlParts.get('story-file'));
|
const safeStoryUrl = sanitize(urlParts.get('story-file'), 'js');
|
||||||
|
const mod = await import(safeStoryUrl);
|
||||||
render(mod[urlParts.get('story-key')]({ shadowRoot: document }), document.body);
|
render(mod[urlParts.get('story-key')]({ shadowRoot: document }), document.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { rollup } from 'rollup';
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { copy } from '@web/rollup-plugin-copy';
|
import { copy } from '@web/rollup-plugin-copy';
|
||||||
|
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
||||||
|
|
||||||
import { createMpaConfig, createServiceWorkerConfig } from '@rocket/building-rollup';
|
import { createMpaConfig, createServiceWorkerConfig } from '@rocket/building-rollup';
|
||||||
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
||||||
@@ -25,18 +26,14 @@ async function buildAndWrite(config) {
|
|||||||
|
|
||||||
async function productionBuild(config) {
|
async function productionBuild(config) {
|
||||||
const defaultSetupPlugins = [
|
const defaultSetupPlugins = [
|
||||||
addPlugin({
|
addPlugin(copy, {
|
||||||
name: 'copy',
|
patterns: ['!(*.md|*.html)*', '_merged_assets/_static/**/*'],
|
||||||
plugin: copy,
|
rootDir: config.outputDevDir,
|
||||||
options: {
|
|
||||||
patterns: ['!(*.md|*.html)*', '_merged_assets/_static/**/*'],
|
|
||||||
rootDir: config.outputDevDir,
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
if (config.pathPrefix) {
|
if (config.pathPrefix) {
|
||||||
defaultSetupPlugins.push(
|
defaultSetupPlugins.push(
|
||||||
adjustPluginOptions('html', { absolutePathPrefix: config.pathPrefix }),
|
adjustPluginOptions(rollupPluginHTML, { absolutePathPrefix: config.pathPrefix }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ export class RocketCli {
|
|||||||
async cleanup() {
|
async cleanup() {
|
||||||
setComputedConfig({});
|
setComputedConfig({});
|
||||||
if (this.eleventy) {
|
if (this.eleventy) {
|
||||||
this.eleventy.finish();
|
// this.eleventy.finish();
|
||||||
// await this.eleventy.stopWatch();
|
// await this.eleventy.stopWatch();
|
||||||
}
|
}
|
||||||
this.stop();
|
this.stop();
|
||||||
|
|||||||
@@ -1,11 +1,61 @@
|
|||||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
import { startDevServer } from '@web/dev-server';
|
import { startDevServer } from '@web/dev-server';
|
||||||
import { fromRollup } from '@web/dev-server-rollup';
|
import { fromRollup } from '@web/dev-server-rollup';
|
||||||
import { metaConfigToWebDevServerConfig } from 'plugins-manager';
|
import { executeSetupFunctions } from 'plugins-manager';
|
||||||
|
|
||||||
/** @typedef {import('../types/main').RocketCliOptions} RocketCliOptions */
|
/** @typedef {import('../types/main').RocketCliOptions} RocketCliOptions */
|
||||||
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
/** @typedef {import('@web/dev-server').DevServerConfig} DevServerConfig */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} config
|
||||||
|
* @param {MetaPluginWrapable[]} metaPlugins
|
||||||
|
* @param {object} [options]
|
||||||
|
* @param {function | null} [options.rollupWrapperFunction]
|
||||||
|
*/
|
||||||
|
export function metaConfigToWebDevServerConfig(
|
||||||
|
config,
|
||||||
|
metaPlugins,
|
||||||
|
{ rollupWrapperFunction = null } = {},
|
||||||
|
) {
|
||||||
|
if (config.plugins) {
|
||||||
|
delete config.setupPlugins;
|
||||||
|
delete config.setupRollupPlugins;
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
const metaPluginsNoWrap = metaPlugins.map(pluginObj => {
|
||||||
|
pluginObj.__noWrap = true;
|
||||||
|
return pluginObj;
|
||||||
|
});
|
||||||
|
|
||||||
|
const rollupPlugins = /** @type {MetaPluginWrapable[]} */ (executeSetupFunctions(
|
||||||
|
config.setupRollupPlugins,
|
||||||
|
[...metaPluginsNoWrap],
|
||||||
|
));
|
||||||
|
|
||||||
|
const wrappedRollupPlugins = rollupPlugins.map(pluginObj => {
|
||||||
|
if (typeof rollupWrapperFunction === 'function' && pluginObj.__noWrap !== true) {
|
||||||
|
pluginObj.plugin = rollupWrapperFunction(pluginObj.plugin);
|
||||||
|
}
|
||||||
|
return pluginObj;
|
||||||
|
});
|
||||||
|
|
||||||
|
const _metaPlugins = executeSetupFunctions(config.setupPlugins, [...wrappedRollupPlugins]);
|
||||||
|
|
||||||
|
const plugins = _metaPlugins.map(pluginObj => {
|
||||||
|
if (pluginObj.options) {
|
||||||
|
return pluginObj.plugin(pluginObj.options);
|
||||||
|
} else {
|
||||||
|
return pluginObj.plugin();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
config.plugins = plugins;
|
||||||
|
|
||||||
|
delete config.setupPlugins;
|
||||||
|
delete config.setupRollupPlugins;
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
export class RocketStart {
|
export class RocketStart {
|
||||||
static pluginName = 'RocketStart';
|
static pluginName = 'RocketStart';
|
||||||
commands = ['start'];
|
commands = ['start'];
|
||||||
|
|||||||
@@ -243,9 +243,9 @@ async function insertResponsiveImages(html) {
|
|||||||
const config = getComputedConfig();
|
const config = getComputedConfig();
|
||||||
|
|
||||||
if (!isSetup) {
|
if (!isSetup) {
|
||||||
await parser.prepareWasm(saxWasmBuffer);
|
isSetup = parser.prepareWasm(saxWasmBuffer);
|
||||||
isSetup = true;
|
|
||||||
}
|
}
|
||||||
|
await isSetup;
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
inputPath: this.inputPath,
|
inputPath: this.inputPath,
|
||||||
|
|||||||
@@ -174,11 +174,7 @@ export async function normalizeConfig(inConfig) {
|
|||||||
config._presetPaths.push(path.resolve(_inputDirCwdRelative));
|
config._presetPaths.push(path.resolve(_inputDirCwdRelative));
|
||||||
|
|
||||||
/** @type {MetaPlugin[]} */
|
/** @type {MetaPlugin[]} */
|
||||||
let pluginsMeta = [
|
let pluginsMeta = [{ plugin: RocketStart }, { plugin: RocketBuild }, { plugin: RocketLint }];
|
||||||
{ name: 'RocketStart', plugin: RocketStart },
|
|
||||||
{ name: 'RocketBuild', plugin: RocketBuild },
|
|
||||||
{ name: 'RocketLint', plugin: RocketLint },
|
|
||||||
];
|
|
||||||
|
|
||||||
if (Array.isArray(config.setupCliPlugins)) {
|
if (Array.isArray(config.setupCliPlugins)) {
|
||||||
for (const setupFn of config.setupCliPlugins) {
|
for (const setupFn of config.setupCliPlugins) {
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ const { createSocialImage: defaultCreateSocialImage } = require('./createSocialI
|
|||||||
const { getComputedConfig } = require('./computedConfig.cjs');
|
const { getComputedConfig } = require('./computedConfig.cjs');
|
||||||
const { executeSetupFunctions } = require('plugins-manager');
|
const { executeSetupFunctions } = require('plugins-manager');
|
||||||
|
|
||||||
function titleMetaPlugin() {
|
class TitleMetaPlugin {
|
||||||
return async data => {
|
static dataName = 'titleMeta';
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.titleMeta) {
|
if (data.titleMeta) {
|
||||||
return data.titleMeta;
|
return data.titleMeta;
|
||||||
}
|
}
|
||||||
@@ -17,29 +19,35 @@ function titleMetaPlugin() {
|
|||||||
return titleMetaFromContent;
|
return titleMetaFromContent;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function titlePlugin() {
|
class TitlePlugin {
|
||||||
return async data => {
|
static dataName = 'title';
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.title) {
|
if (data.title) {
|
||||||
return data.title;
|
return data.title;
|
||||||
}
|
}
|
||||||
return data.titleMeta?.title;
|
return data.titleMeta?.title;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function eleventyNavigationPlugin() {
|
class EleventyNavigationPlugin {
|
||||||
return async data => {
|
static dataName = 'eleventyNavigation';
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.eleventyNavigation) {
|
if (data.eleventyNavigation) {
|
||||||
return data.eleventyNavigation;
|
return data.eleventyNavigation;
|
||||||
}
|
}
|
||||||
return data.titleMeta?.eleventyNavigation;
|
return data.titleMeta?.eleventyNavigation;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sectionPlugin() {
|
class SectionPlugin {
|
||||||
return async data => {
|
static dataName = 'section';
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.section) {
|
if (data.section) {
|
||||||
return data.section;
|
return data.section;
|
||||||
}
|
}
|
||||||
@@ -52,11 +60,17 @@ function sectionPlugin() {
|
|||||||
return parts[1];
|
return parts[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function layoutPlugin({ defaultLayout = 'layout-default' } = {}) {
|
class LayoutPlugin {
|
||||||
return async data => {
|
static dataName = 'layout';
|
||||||
|
|
||||||
|
constructor({ defaultLayout = 'layout-default' } = {}) {
|
||||||
|
this.defaultLayout = defaultLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.layout) {
|
if (data.layout) {
|
||||||
return data.layout;
|
return data.layout;
|
||||||
}
|
}
|
||||||
@@ -66,22 +80,29 @@ function layoutPlugin({ defaultLayout = 'layout-default' } = {}) {
|
|||||||
return 'layout-index';
|
return 'layout-index';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return defaultLayout;
|
return this.defaultLayout;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function socialMediaImagePlugin(args = {}) {
|
class SocialMediaImagePlugin {
|
||||||
const { createSocialImage = defaultCreateSocialImage, rocketConfig = {} } = args;
|
static dataName = 'socialMediaImage';
|
||||||
|
|
||||||
const cleanedUpArgs = { ...args };
|
constructor(args = {}) {
|
||||||
delete cleanedUpArgs.createSocialImage;
|
const { createSocialImage = defaultCreateSocialImage, rocketConfig = {} } = args;
|
||||||
|
|
||||||
return async data => {
|
this.cleanedUpArgs = { ...args };
|
||||||
|
delete this.cleanedUpArgs.createSocialImage;
|
||||||
|
|
||||||
|
this.rocketConfig = rocketConfig;
|
||||||
|
this.createSocialImage = createSocialImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(data) {
|
||||||
if (data.socialMediaImage) {
|
if (data.socialMediaImage) {
|
||||||
return data.socialMediaImage;
|
return data.socialMediaImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rocketConfig.createSocialMediaImages === false) {
|
if (this.rocketConfig.createSocialMediaImages === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,15 +116,15 @@ function socialMediaImagePlugin(args = {}) {
|
|||||||
const section = data.section ? ' ' + data.section[0].toUpperCase() + data.section.slice(1) : '';
|
const section = data.section ? ' ' + data.section[0].toUpperCase() + data.section.slice(1) : '';
|
||||||
const footer = `${data.site.name}${section}`;
|
const footer = `${data.site.name}${section}`;
|
||||||
|
|
||||||
const imgUrl = await createSocialImage({
|
const imgUrl = await this.createSocialImage({
|
||||||
title,
|
title,
|
||||||
subTitle,
|
subTitle,
|
||||||
footer,
|
footer,
|
||||||
section,
|
section,
|
||||||
...cleanedUpArgs,
|
...this.cleanedUpArgs,
|
||||||
});
|
});
|
||||||
return imgUrl;
|
return imgUrl;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortByOrder(a, b) {
|
function sortByOrder(a, b) {
|
||||||
@@ -146,26 +167,31 @@ async function dirToTree(sourcePath, extra = '') {
|
|||||||
return sortedTree;
|
return sortedTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
function joiningBlocksPlugin(rocketConfig) {
|
class JoiningBlocksPlugin {
|
||||||
const { _inputDirCwdRelative } = rocketConfig;
|
static dataName = '_joiningBlocks';
|
||||||
const partialsSource = path.resolve(_inputDirCwdRelative, '_merged_includes');
|
|
||||||
return async () => {
|
constructor(rocketConfig) {
|
||||||
const joiningBlocks = await dirToTree(partialsSource, '_joiningBlocks');
|
const { _inputDirCwdRelative } = rocketConfig;
|
||||||
|
this.partialsSource = path.resolve(_inputDirCwdRelative, '_merged_includes');
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute() {
|
||||||
|
const joiningBlocks = await dirToTree(this.partialsSource, '_joiningBlocks');
|
||||||
return joiningBlocks;
|
return joiningBlocks;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateEleventyComputed() {
|
function generateEleventyComputed() {
|
||||||
const rocketConfig = getComputedConfig();
|
const rocketConfig = getComputedConfig();
|
||||||
|
|
||||||
let metaPlugins = [
|
let metaPlugins = [
|
||||||
{ name: 'titleMeta', plugin: titleMetaPlugin },
|
{ plugin: TitleMetaPlugin, options: {} },
|
||||||
{ name: 'title', plugin: titlePlugin },
|
{ plugin: TitlePlugin, options: {} },
|
||||||
{ name: 'eleventyNavigation', plugin: eleventyNavigationPlugin },
|
{ plugin: EleventyNavigationPlugin, options: {} },
|
||||||
{ name: 'section', plugin: sectionPlugin },
|
{ plugin: SectionPlugin, options: {} },
|
||||||
{ name: 'socialMediaImage', plugin: socialMediaImagePlugin, options: { rocketConfig } },
|
{ plugin: SocialMediaImagePlugin, options: { rocketConfig } },
|
||||||
{ name: '_joiningBlocks', plugin: joiningBlocksPlugin, options: rocketConfig },
|
{ plugin: JoiningBlocksPlugin, options: rocketConfig },
|
||||||
{ name: 'layout', plugin: layoutPlugin },
|
{ plugin: LayoutPlugin, options: {} },
|
||||||
];
|
];
|
||||||
|
|
||||||
const finalMetaPlugins = executeSetupFunctions(
|
const finalMetaPlugins = executeSetupFunctions(
|
||||||
@@ -176,13 +202,24 @@ function generateEleventyComputed() {
|
|||||||
const eleventyComputed = {};
|
const eleventyComputed = {};
|
||||||
for (const pluginObj of finalMetaPlugins) {
|
for (const pluginObj of finalMetaPlugins) {
|
||||||
if (pluginObj.options) {
|
if (pluginObj.options) {
|
||||||
eleventyComputed[pluginObj.name] = pluginObj.plugin(pluginObj.options);
|
const inst = new pluginObj.plugin(pluginObj.options);
|
||||||
|
eleventyComputed[inst.constructor.dataName] = inst.execute.bind(inst);
|
||||||
} else {
|
} else {
|
||||||
eleventyComputed[pluginObj.name] = pluginObj.plugin();
|
const inst = new pluginObj.plugin();
|
||||||
|
eleventyComputed[inst.constructor.dataName] = inst.execute.bind(inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return eleventyComputed;
|
return eleventyComputed;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { generateEleventyComputed };
|
module.exports = {
|
||||||
|
generateEleventyComputed,
|
||||||
|
LayoutPlugin,
|
||||||
|
TitleMetaPlugin,
|
||||||
|
TitlePlugin,
|
||||||
|
EleventyNavigationPlugin,
|
||||||
|
SectionPlugin,
|
||||||
|
SocialMediaImagePlugin,
|
||||||
|
JoiningBlocksPlugin,
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const eleventyPluginMdjsUnified = require('@rocket/eleventy-plugin-mdjs-unified');
|
const eleventyPluginMdjsUnified = require('@rocket/eleventy-plugin-mdjs-unified');
|
||||||
const eleventyRocketNav = require('@rocket/eleventy-rocket-nav');
|
const eleventyRocketNav = require('@rocket/eleventy-rocket-nav');
|
||||||
|
const remark2rehype = require('remark-rehype');
|
||||||
|
|
||||||
const { getComputedConfig } = require('../public/computedConfig.cjs');
|
const { getComputedConfig } = require('../public/computedConfig.cjs');
|
||||||
const rocketFilters = require('../eleventy-plugins/rocketFilters.cjs');
|
const rocketFilters = require('../eleventy-plugins/rocketFilters.cjs');
|
||||||
@@ -9,7 +10,7 @@ const { adjustPluginOptions } = require('plugins-manager');
|
|||||||
const image = require('./mdjsImageHandler.cjs');
|
const image = require('./mdjsImageHandler.cjs');
|
||||||
|
|
||||||
const defaultSetupUnifiedPlugins = [
|
const defaultSetupUnifiedPlugins = [
|
||||||
adjustPluginOptions('remark2rehype', {
|
adjustPluginOptions(remark2rehype, {
|
||||||
handlers: {
|
handlers: {
|
||||||
image,
|
image,
|
||||||
},
|
},
|
||||||
@@ -23,28 +24,24 @@ module.exports = function (eleventyConfig) {
|
|||||||
|
|
||||||
let metaPlugins = [
|
let metaPlugins = [
|
||||||
{
|
{
|
||||||
name: 'rocket-filters',
|
|
||||||
plugin: rocketFilters,
|
plugin: rocketFilters,
|
||||||
options: { _inputDirCwdRelative },
|
options: { _inputDirCwdRelative },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'rocket-copy',
|
|
||||||
plugin: rocketCopy,
|
plugin: rocketCopy,
|
||||||
options: { _inputDirCwdRelative },
|
options: { _inputDirCwdRelative },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'eleventy-plugin-mdjs-unified',
|
|
||||||
plugin: eleventyPluginMdjsUnified,
|
plugin: eleventyPluginMdjsUnified,
|
||||||
options: {
|
options: {
|
||||||
setupUnifiedPlugins: [...defaultSetupUnifiedPlugins, ...config.setupUnifiedPlugins],
|
setupUnifiedPlugins: [...defaultSetupUnifiedPlugins, ...config.setupUnifiedPlugins],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'eleventy-rocket-nav',
|
|
||||||
plugin: eleventyRocketNav,
|
plugin: eleventyRocketNav,
|
||||||
|
options: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'rocket-collections',
|
|
||||||
plugin: rocketCollections,
|
plugin: rocketCollections,
|
||||||
options: { _inputDirCwdRelative },
|
options: { _inputDirCwdRelative },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -91,86 +91,78 @@ export async function readOutput(
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function startOutputExist(cli, fileName) {
|
|
||||||
const outputDir = cli.config.outputDevDir;
|
|
||||||
return fs.existsSync(path.join(outputDir, fileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function buildOutputExist(cli, fileName) {
|
|
||||||
const outputDir = cli.config.outputDir;
|
|
||||||
return fs.existsSync(path.join(outputDir, fileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {*} cli
|
|
||||||
* @param {string} fileName
|
|
||||||
* @param {readOutputOptions} options
|
|
||||||
*/
|
|
||||||
export async function readStartOutput(cli, fileName, options = {}) {
|
|
||||||
options.type = 'start';
|
|
||||||
return readOutput(cli, fileName, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {*} cli
|
|
||||||
* @param {string} fileName
|
|
||||||
* @param {readOutputOptions} options
|
|
||||||
*/
|
|
||||||
export async function readBuildOutput(cli, fileName, options = {}) {
|
|
||||||
options.type = 'build';
|
|
||||||
return readOutput(cli, fileName, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getfixtureExpectedFiles(pathToDir) {
|
export async function getfixtureExpectedFiles(pathToDir) {
|
||||||
const cwd = path.join(fixtureDir, pathToDir);
|
const cwd = path.join(fixtureDir, pathToDir);
|
||||||
const paths = await globby('**/*', { cwd, absolute: true, dot: true });
|
const paths = await globby('**/*', { cwd, absolute: true, dot: true });
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function execute(cli, configFileDir) {
|
export async function execute(pathToConfig, { type = 'start', captureLog = false } = {}) {
|
||||||
|
let log = [];
|
||||||
|
const origLog = console.log;
|
||||||
|
if (captureLog) {
|
||||||
|
console.log = (...args) => {
|
||||||
|
log = [...log, ...args];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const configFile = path.join(fixtureDir, pathToConfig.split('/').join(path.sep));
|
||||||
|
const configFileDir = path.dirname(configFile);
|
||||||
|
|
||||||
|
const cli = new RocketCli({
|
||||||
|
argv: [type, '--config-file', configFile],
|
||||||
|
});
|
||||||
|
|
||||||
await cli.setup();
|
await cli.setup();
|
||||||
cli.config.outputDevDir = path.join(configFileDir, '__output-dev');
|
cli.config.outputDevDir = path.join(configFileDir, '__output-dev');
|
||||||
cli.config.devServer.open = false;
|
cli.config.devServer.open = false;
|
||||||
cli.config.devServer.port = 8080;
|
cli.config.devServer.port = 8080;
|
||||||
cli.config.watch = false;
|
cli.config.watch = false;
|
||||||
cli.config.outputDir = path.join(configFileDir, '__output');
|
cli.config.outputDir = path.join(configFileDir, '__output');
|
||||||
|
|
||||||
|
await fs.emptyDir(cli.config.outputDevDir);
|
||||||
|
await fs.emptyDir(cli.config.outputDir);
|
||||||
|
|
||||||
await cli.run();
|
await cli.run();
|
||||||
return cli;
|
|
||||||
|
/**
|
||||||
|
* @param {*} cli
|
||||||
|
* @param {string} fileName
|
||||||
|
* @param {readOutputOptions} options
|
||||||
|
*/
|
||||||
|
async function readOutput2(fileName, options = {}) {
|
||||||
|
options.type = type;
|
||||||
|
return readOutput(cli, fileName, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
function outputExists(fileName) {
|
||||||
|
const outputDir = type === 'build' ? cli.config.outputDir : cli.config.outputDevDir;
|
||||||
|
const filePath = path.join(outputDir, fileName);
|
||||||
|
|
||||||
|
return fs.existsSync(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (captureLog) {
|
||||||
|
console.log = origLog;
|
||||||
|
}
|
||||||
|
return { log, readOutput: readOutput2, cli, outputExists };
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function executeBootstrap(pathToDir) {
|
export async function executeBootstrap(pathToDir) {
|
||||||
const configFileDir = path.join(fixtureDir, pathToDir.split('/').join(path.sep));
|
const configFileDir = path.join(fixtureDir, pathToDir.split('/').join(path.sep));
|
||||||
const cli = new RocketCli({ argv: ['bootstrap'] });
|
const cli = new RocketCli({ argv: ['bootstrap'] });
|
||||||
|
|
||||||
|
await cli.setup();
|
||||||
|
cli.config.outputDevDir = path.join(configFileDir, '__output-dev');
|
||||||
|
cli.config.devServer.open = false;
|
||||||
|
cli.config.devServer.port = 8080;
|
||||||
|
cli.config.watch = false;
|
||||||
|
cli.config.outputDir = path.join(configFileDir, '__output');
|
||||||
|
|
||||||
await fs.emptyDir(configFileDir);
|
await fs.emptyDir(configFileDir);
|
||||||
await execute(cli, configFileDir);
|
await cli.run();
|
||||||
return cli;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function executeStart(pathToConfig) {
|
return { cli };
|
||||||
const configFile = path.join(fixtureDir, pathToConfig.split('/').join(path.sep));
|
|
||||||
const cli = new RocketCli({
|
|
||||||
argv: ['start', '--config-file', configFile],
|
|
||||||
});
|
|
||||||
await execute(cli, path.dirname(configFile));
|
|
||||||
return cli;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function executeBuild(pathToConfig) {
|
|
||||||
const configFile = path.join(fixtureDir, pathToConfig.split('/').join(path.sep));
|
|
||||||
const cli = new RocketCli({
|
|
||||||
argv: ['build', '--config-file', configFile],
|
|
||||||
});
|
|
||||||
await execute(cli, path.dirname(configFile));
|
|
||||||
return cli;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function executeLint(pathToConfig) {
|
|
||||||
const configFile = path.join(fixtureDir, pathToConfig.split('/').join(path.sep));
|
|
||||||
const cli = new RocketCli({
|
|
||||||
argv: ['lint', '--config-file', configFile],
|
|
||||||
});
|
|
||||||
await execute(cli, path.dirname(configFile));
|
|
||||||
return cli;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function trimWhiteSpace(inString) {
|
export function trimWhiteSpace(inString) {
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import {
|
import { execute, setFixtureDir } from '@rocket/cli/test-helpers';
|
||||||
executeBuild,
|
|
||||||
executeStart,
|
|
||||||
readBuildOutput,
|
|
||||||
readStartOutput,
|
|
||||||
setFixtureDir,
|
|
||||||
} from '@rocket/cli/test-helpers';
|
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('RocketCli computedConfig', () => {
|
describe('RocketCli computedConfig', () => {
|
||||||
let cli;
|
let cleanupCli;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// ignore colors in tests as most CIs won't support it
|
// ignore colors in tests as most CIs won't support it
|
||||||
@@ -20,90 +14,117 @@ describe('RocketCli computedConfig', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (cli?.cleanup) {
|
if (cleanupCli?.cleanup) {
|
||||||
await cli.cleanup();
|
await cleanupCli.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('will extract a title from markdown and set first folder as section', async () => {
|
it('will extract a title from markdown and set first folder as section', async () => {
|
||||||
cli = await executeStart('computed-config-fixtures/headlines/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
|
'computed-config-fixtures/headlines/rocket.config.js',
|
||||||
|
{ captureLog: true },
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
const [indexTitle, indexSection] = indexHtml.split('\n');
|
const [indexTitle, indexSection] = indexHtml.split('\n');
|
||||||
expect(indexTitle).to.equal('Root');
|
expect(indexTitle).to.equal('Root');
|
||||||
expect(indexSection).to.be.undefined;
|
expect(indexSection).to.be.undefined;
|
||||||
|
|
||||||
const subHtml = await readStartOutput(cli, 'sub/index.html');
|
const subHtml = await readOutput('sub/index.html');
|
||||||
const [subTitle, subSection] = subHtml.split('\n');
|
const [subTitle, subSection] = subHtml.split('\n');
|
||||||
expect(subTitle).to.equal('Root: Sub');
|
expect(subTitle).to.equal('Root: Sub');
|
||||||
expect(subSection).to.equal('sub');
|
expect(subSection).to.equal('sub');
|
||||||
|
|
||||||
const subSubHtml = await readStartOutput(cli, 'sub/subsub/index.html');
|
const subSubHtml = await readOutput('sub/subsub/index.html');
|
||||||
const [subSubTitle, subSubSection] = subSubHtml.split('\n');
|
const [subSubTitle, subSubSection] = subSubHtml.split('\n');
|
||||||
expect(subSubTitle).to.equal('Sub: SubSub');
|
expect(subSubTitle).to.equal('Sub: SubSub');
|
||||||
expect(subSubSection).to.equal('sub');
|
expect(subSubSection).to.equal('sub');
|
||||||
|
|
||||||
const sub2Html = await readStartOutput(cli, 'sub2/index.html');
|
const sub2Html = await readOutput('sub2/index.html');
|
||||||
const [sub2Title, sub2Section] = sub2Html.split('\n');
|
const [sub2Title, sub2Section] = sub2Html.split('\n');
|
||||||
expect(sub2Title).to.equal('Root: Sub2');
|
expect(sub2Title).to.equal('Root: Sub2');
|
||||||
expect(sub2Section).to.equal('sub2');
|
expect(sub2Section).to.equal('sub2');
|
||||||
|
|
||||||
const withDataHtml = await readStartOutput(cli, 'with-data/index.html');
|
const withDataHtml = await readOutput('with-data/index.html');
|
||||||
const [withDataTitle, withDataSection] = withDataHtml.split('\n');
|
const [withDataTitle, withDataSection] = withDataHtml.split('\n');
|
||||||
expect(withDataTitle).to.equal('Set via data');
|
expect(withDataTitle).to.equal('Set via data');
|
||||||
expect(withDataSection).be.undefined;
|
expect(withDataSection).be.undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('will note create a social media image in "start"', async () => {
|
it('will note create a social media image in "start"', async () => {
|
||||||
cli = await executeStart('computed-config-fixtures/social-images-only-build/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
|
'computed-config-fixtures/social-images-only-build/rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal('');
|
expect(indexHtml).to.equal('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('will create a social media image in "build"', async () => {
|
it('will create a social media image in "build"', async () => {
|
||||||
cli = await executeBuild('computed-config-fixtures/social-images-only-build/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
|
'computed-config-fixtures/social-images-only-build/rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
type: 'build',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readBuildOutput(cli, 'index.html', {
|
const indexHtml = await readOutput('index.html', {
|
||||||
stripToBody: true,
|
stripToBody: true,
|
||||||
});
|
});
|
||||||
expect(indexHtml).to.equal('/_merged_assets/11ty-img/5893749-1200.png');
|
expect(indexHtml).to.equal('/_merged_assets/11ty-img/5893749-1200.png');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('will create a social media image for every page', async () => {
|
it('will create a social media image for every page', async () => {
|
||||||
cli = await executeStart('computed-config-fixtures/social-images/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
|
'computed-config-fixtures/social-images/rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal('/_merged_assets/11ty-img/c4c29ec7-1200.png');
|
expect(indexHtml).to.equal('/_merged_assets/11ty-img/c4c29ec7-1200.png');
|
||||||
|
|
||||||
const guidesHtml = await readStartOutput(cli, 'guides/index.html');
|
const guidesHtml = await readOutput('guides/index.html');
|
||||||
expect(guidesHtml).to.equal('/_merged_assets/11ty-img/c593a8cd-1200.png');
|
expect(guidesHtml).to.equal('/_merged_assets/11ty-img/c593a8cd-1200.png');
|
||||||
|
|
||||||
const gettingStartedHtml = await readStartOutput(
|
const gettingStartedHtml = await readOutput('guides/first-pages/getting-started/index.html');
|
||||||
cli,
|
|
||||||
'guides/first-pages/getting-started/index.html',
|
|
||||||
);
|
|
||||||
expect(gettingStartedHtml).to.equal('/_merged_assets/11ty-img/d989ab1a-1200.png');
|
expect(gettingStartedHtml).to.equal('/_merged_assets/11ty-img/d989ab1a-1200.png');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can override the svg function globally to adjust all social media image', async () => {
|
it('can override the svg function globally to adjust all social media image', async () => {
|
||||||
cli = await executeStart('computed-config-fixtures/social-images-override/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
|
'computed-config-fixtures/social-images-override/rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal('/_merged_assets/11ty-img/d76265ed-1200.png');
|
expect(indexHtml).to.equal('/_merged_assets/11ty-img/d76265ed-1200.png');
|
||||||
|
|
||||||
const guidesHtml = await readStartOutput(cli, 'guides/index.html');
|
const guidesHtml = await readOutput('guides/index.html');
|
||||||
expect(guidesHtml).to.equal('/_merged_assets/11ty-img/d76265ed-1200.png');
|
expect(guidesHtml).to.equal('/_merged_assets/11ty-img/d76265ed-1200.png');
|
||||||
|
|
||||||
const gettingStartedHtml = await readStartOutput(
|
const gettingStartedHtml = await readOutput('guides/first-pages/getting-started/index.html');
|
||||||
cli,
|
|
||||||
'guides/first-pages/getting-started/index.html',
|
|
||||||
);
|
|
||||||
expect(gettingStartedHtml).to.equal('/_merged_assets/11ty-img/d76265ed-1200.png');
|
expect(gettingStartedHtml).to.equal('/_merged_assets/11ty-img/d76265ed-1200.png');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('will add "../" for links and image urls only within named template files', async () => {
|
it('will add "../" for links and image urls only within named template files', async () => {
|
||||||
cli = await executeStart('computed-config-fixtures/image-link/rocket.config.js');
|
const {
|
||||||
|
cli,
|
||||||
|
readOutput,
|
||||||
|
} = await execute('computed-config-fixtures/image-link/rocket.config.js', { captureLog: true });
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const namedMdContent = [
|
const namedMdContent = [
|
||||||
'<p>',
|
'<p>',
|
||||||
@@ -127,22 +148,22 @@ describe('RocketCli computedConfig', () => {
|
|||||||
'</div>',
|
'</div>',
|
||||||
];
|
];
|
||||||
|
|
||||||
const templateHtml = await readStartOutput(cli, 'template/index.html', { formatHtml: true });
|
const templateHtml = await readOutput('template/index.html', { formatHtml: true });
|
||||||
expect(templateHtml, 'template/index.html does not match').to.equal(
|
expect(templateHtml, 'template/index.html does not match').to.equal(
|
||||||
namedHtmlContent.join('\n'),
|
namedHtmlContent.join('\n'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const guidesHtml = await readStartOutput(cli, 'guides/index.html', { formatHtml: true });
|
const guidesHtml = await readOutput('guides/index.html', { formatHtml: true });
|
||||||
expect(guidesHtml, 'guides/index.html does not match').to.equal(
|
expect(guidesHtml, 'guides/index.html does not match').to.equal(
|
||||||
[...namedMdContent, ...namedHtmlContent].join('\n'),
|
[...namedMdContent, ...namedHtmlContent].join('\n'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const noAdjustHtml = await readStartOutput(cli, 'no-adjust/index.html');
|
const noAdjustHtml = await readOutput('no-adjust/index.html');
|
||||||
expect(noAdjustHtml, 'no-adjust/index.html does not match').to.equal(
|
expect(noAdjustHtml, 'no-adjust/index.html does not match').to.equal(
|
||||||
'<p>Nothing to adjust in here</p>',
|
'<p>Nothing to adjust in here</p>',
|
||||||
);
|
);
|
||||||
|
|
||||||
const rawHtml = await readStartOutput(cli, 'one-level/raw/index.html');
|
const rawHtml = await readOutput('one-level/raw/index.html');
|
||||||
expect(rawHtml, 'raw/index.html does not match').to.equal(
|
expect(rawHtml, 'raw/index.html does not match').to.equal(
|
||||||
[
|
[
|
||||||
'<div>',
|
'<div>',
|
||||||
@@ -159,7 +180,7 @@ describe('RocketCli computedConfig', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// for index files no '../' will be added
|
// for index files no '../' will be added
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html', { formatHtml: true });
|
const indexHtml = await readOutput('index.html', { formatHtml: true });
|
||||||
expect(indexHtml, 'index.html does not match').to.equal(
|
expect(indexHtml, 'index.html does not match').to.equal(
|
||||||
[
|
[
|
||||||
'<p>',
|
'<p>',
|
||||||
@@ -188,19 +209,28 @@ describe('RocketCli computedConfig', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can be configured via setupEleventyComputedConfig', async () => {
|
it('can be configured via setupEleventyComputedConfig', async () => {
|
||||||
cli = await executeStart('computed-config-fixtures/setup/addPlugin.rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
|
'computed-config-fixtures/setup/addPlugin.rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal('test-value');
|
expect(indexHtml).to.equal('test-value');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('always assigns layout-default exept for index.* files who get layout-index', async () => {
|
it('always assigns layout-default exept for index.* files who get layout-index', async () => {
|
||||||
cli = await executeStart('computed-config-fixtures/layout/rocket.config.js');
|
const { cli, readOutput } = await execute('computed-config-fixtures/layout/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.include('<body layout="layout-index">');
|
expect(indexHtml).to.include('<body layout="layout-index">');
|
||||||
|
|
||||||
const pageHtml = await readStartOutput(cli, 'page/index.html');
|
const pageHtml = await readOutput('page/index.html');
|
||||||
expect(pageHtml).to.include('<body layout="layout-default">');
|
expect(pageHtml).to.include('<body layout="layout-default">');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,13 +2,9 @@ import chai from 'chai';
|
|||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import {
|
import {
|
||||||
|
execute,
|
||||||
executeBootstrap,
|
executeBootstrap,
|
||||||
executeBuild,
|
|
||||||
executeLint,
|
|
||||||
executeStart,
|
|
||||||
expectThrowsAsync,
|
expectThrowsAsync,
|
||||||
readBuildOutput,
|
|
||||||
readStartOutput,
|
|
||||||
getfixtureExpectedFiles,
|
getfixtureExpectedFiles,
|
||||||
setFixtureDir,
|
setFixtureDir,
|
||||||
} from '@rocket/cli/test-helpers';
|
} from '@rocket/cli/test-helpers';
|
||||||
@@ -17,7 +13,7 @@ import fs from 'fs-extra';
|
|||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('RocketCli e2e', () => {
|
describe('RocketCli e2e', () => {
|
||||||
let cli;
|
let cleanupCli;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// ignore colors in tests as most CIs won't support it
|
// ignore colors in tests as most CIs won't support it
|
||||||
@@ -26,20 +22,24 @@ describe('RocketCli e2e', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (cli?.cleanup) {
|
if (cleanupCli?.cleanup) {
|
||||||
await cli.cleanup();
|
await cleanupCli.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can add a unified plugin via the config', async () => {
|
it('can add a unified plugin via the config', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/unified-plugin/rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/unified-plugin/rocket.config.js', {
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal(`<p>See a 🐶</p>`);
|
expect(indexHtml).to.equal(`<p>See a 🐶</p>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('bootstrap command', () => {
|
describe('bootstrap command', () => {
|
||||||
it('can bootstrap a project', async () => {
|
it('can bootstrap a project', async () => {
|
||||||
cli = await executeBootstrap('e2e-fixtures/bootstrap/__output');
|
const { cli } = await executeBootstrap('e2e-fixtures/bootstrap/__output');
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
for (const p of await getfixtureExpectedFiles('e2e-fixtures/bootstrap/expected')) {
|
for (const p of await getfixtureExpectedFiles('e2e-fixtures/bootstrap/expected')) {
|
||||||
const actual = await fs.readFile(
|
const actual = await fs.readFile(
|
||||||
@@ -54,8 +54,11 @@ describe('RocketCli e2e', () => {
|
|||||||
|
|
||||||
describe('eleventy in config', () => {
|
describe('eleventy in config', () => {
|
||||||
it('can modify eleventy via an elventy function in the config', async () => {
|
it('can modify eleventy via an elventy function in the config', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/content/eleventy.rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/content/eleventy.rocket.config.js', {
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal(
|
expect(indexHtml).to.equal(
|
||||||
['# BEFORE #', '<p>Content inside <code>docs/index.md</code></p>'].join('\n'),
|
['# BEFORE #', '<p>Content inside <code>docs/index.md</code></p>'].join('\n'),
|
||||||
);
|
);
|
||||||
@@ -63,7 +66,8 @@ describe('RocketCli e2e', () => {
|
|||||||
|
|
||||||
it('will throw if you try to set options by returning an object', async () => {
|
it('will throw if you try to set options by returning an object', async () => {
|
||||||
await expectThrowsAsync(
|
await expectThrowsAsync(
|
||||||
() => executeStart('e2e-fixtures/content/eleventy-return.rocket.config.js'),
|
() =>
|
||||||
|
execute('e2e-fixtures/content/eleventy-return.rocket.config.js', { captureLog: true }),
|
||||||
{
|
{
|
||||||
errorMatch: /Error in your Eleventy config file.*/,
|
errorMatch: /Error in your Eleventy config file.*/,
|
||||||
},
|
},
|
||||||
@@ -73,13 +77,23 @@ describe('RocketCli e2e', () => {
|
|||||||
|
|
||||||
describe('setupDevAndBuildPlugins in config', () => {
|
describe('setupDevAndBuildPlugins in config', () => {
|
||||||
it('can add a rollup plugin via setupDevAndBuildPlugins for build command', async () => {
|
it('can add a rollup plugin via setupDevAndBuildPlugins for build command', async () => {
|
||||||
cli = await executeBuild('e2e-fixtures/rollup-plugin/devbuild.rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
const inlineModule = await readBuildOutput(cli, 'e97af63d.js');
|
'e2e-fixtures/rollup-plugin/devbuild.rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
type: 'build',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
const inlineModule = await readOutput('e97af63d.js');
|
||||||
expect(inlineModule).to.equal('var a={test:"data"};console.log(a);');
|
expect(inlineModule).to.equal('var a={test:"data"};console.log(a);');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can add a rollup plugin via setupDevAndBuildPlugins for start command', async () => {
|
it('can add a rollup plugin via setupDevAndBuildPlugins for start command', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/rollup-plugin/devbuild.rocket.config.js');
|
const { cli } = await execute('e2e-fixtures/rollup-plugin/devbuild.rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const response = await fetch('http://localhost:8080/test-data.json');
|
const response = await fetch('http://localhost:8080/test-data.json');
|
||||||
expect(response.ok).to.be.true; // no server error
|
expect(response.ok).to.be.true; // no server error
|
||||||
@@ -90,37 +104,56 @@ describe('RocketCli e2e', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can add a rollup plugin for dev & build and modify a build only plugin via the config', async () => {
|
it('can add a rollup plugin for dev & build and modify a build only plugin via the config', async () => {
|
||||||
cli = await executeBuild('e2e-fixtures/rollup-plugin/devbuild-build.rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
const inlineModule = await readBuildOutput(cli, 'e97af63d.js');
|
'e2e-fixtures/rollup-plugin/devbuild-build.rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
type: 'build',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
const inlineModule = await readOutput('e97af63d.js');
|
||||||
expect(inlineModule).to.equal('var a={test:"data"};console.log(a);');
|
expect(inlineModule).to.equal('var a={test:"data"};console.log(a);');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can adjust the inputDir', async () => {
|
it('can adjust the inputDir', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/change-input-dir/rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/change-input-dir/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal('<p>Markdown in <code>docs/page/index.md</code></p>');
|
expect(indexHtml).to.equal('<p>Markdown in <code>docs/page/index.md</code></p>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can access main rocket config values via {{rocketConfig.value}}', async () => {
|
it('can access main rocket config values via {{rocketConfig.value}}', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/rocket-config-in-template/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
|
'e2e-fixtures/rocket-config-in-template/rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal(
|
expect(indexHtml).to.equal(
|
||||||
'<p>You can show Rocket config data like rocketConfig.absoluteBaseUrl = <a href="http://test-domain.com/">http://test-domain.com/</a></p>',
|
'<p>You can show Rocket config data like rocketConfig.absoluteBaseUrl = <a href="http://test-domain.com/">http://test-domain.com/</a></p>',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can add a pathPrefix that will not influence the start command', async () => {
|
it('can add a pathPrefix that will not influence the start command', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/content/pathPrefix.rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/content/pathPrefix.rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const linkHtml = await readStartOutput(cli, 'link/index.html');
|
const linkHtml = await readOutput('link/index.html');
|
||||||
expect(linkHtml).to.equal(
|
expect(linkHtml).to.equal(
|
||||||
['<p><a href="../">home</a></p>', '<p><a href="/">absolute home</a></p>'].join('\n'),
|
['<p><a href="../">home</a></p>', '<p><a href="/">absolute home</a></p>'].join('\n'),
|
||||||
);
|
);
|
||||||
const assetHtml = await readStartOutput(cli, 'use-assets/index.html');
|
const assetHtml = await readOutput('use-assets/index.html');
|
||||||
expect(assetHtml).to.equal('<link rel="stylesheet" href="/_merged_assets/some.css">');
|
expect(assetHtml).to.equal('<link rel="stylesheet" href="/_merged_assets/some.css">');
|
||||||
const imageHtml = await readStartOutput(cli, 'image/index.html', { replaceImageHashes: true });
|
const imageHtml = await readOutput('image/index.html', { replaceImageHashes: true });
|
||||||
expect(imageHtml).to.equal(
|
expect(imageHtml).to.equal(
|
||||||
[
|
[
|
||||||
'<p>',
|
'<p>',
|
||||||
@@ -147,9 +180,13 @@ describe('RocketCli e2e', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can add a pathPrefix that will be used in the build command', async () => {
|
it('can add a pathPrefix that will be used in the build command', async () => {
|
||||||
cli = await executeBuild('e2e-fixtures/content/pathPrefix.rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/content/pathPrefix.rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
type: 'build',
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const linkHtml = await readBuildOutput(cli, 'link/index.html', {
|
const linkHtml = await readOutput('link/index.html', {
|
||||||
stripToBody: true,
|
stripToBody: true,
|
||||||
});
|
});
|
||||||
expect(linkHtml).to.equal(
|
expect(linkHtml).to.equal(
|
||||||
@@ -157,11 +194,11 @@ describe('RocketCli e2e', () => {
|
|||||||
'\n',
|
'\n',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const assetHtml = await readBuildOutput(cli, 'use-assets/index.html');
|
const assetHtml = await readOutput('use-assets/index.html');
|
||||||
expect(assetHtml).to.equal(
|
expect(assetHtml).to.equal(
|
||||||
'<html><head><link rel="stylesheet" href="../41297ffa.css">\n\n</head><body>\n\n</body></html>',
|
'<html><head><link rel="stylesheet" href="../41297ffa.css">\n\n</head><body>\n\n</body></html>',
|
||||||
);
|
);
|
||||||
let imageHtml = await readBuildOutput(cli, 'image/index.html');
|
let imageHtml = await readOutput('image/index.html');
|
||||||
imageHtml = imageHtml.replace(/\.\.\/([a-z0-9]+)\./g, '../__HASH__.');
|
imageHtml = imageHtml.replace(/\.\.\/([a-z0-9]+)\./g, '../__HASH__.');
|
||||||
expect(imageHtml).to.equal(
|
expect(imageHtml).to.equal(
|
||||||
[
|
[
|
||||||
@@ -184,15 +221,22 @@ describe('RocketCli e2e', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('smoke test for link checking', async () => {
|
it('smoke test for link checking', async () => {
|
||||||
await expectThrowsAsync(() => executeLint('e2e-fixtures/lint-links/rocket.config.js'), {
|
await expectThrowsAsync(
|
||||||
errorMatch: /Found 1 missing reference targets/,
|
() => execute('e2e-fixtures/lint-links/rocket.config.js', { captureLog: true, type: 'lint' }),
|
||||||
});
|
{
|
||||||
|
errorMatch: /Found 1 missing reference targets/,
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can completely take over the rollup config', async () => {
|
it('can completely take over the rollup config', async () => {
|
||||||
cli = await executeBuild('e2e-fixtures/rollup-override/rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/rollup-override/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
type: 'build',
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readBuildOutput(cli, 'index.html', {
|
const indexHtml = await readOutput('index.html', {
|
||||||
stripToBody: true,
|
stripToBody: true,
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
});
|
});
|
||||||
@@ -210,14 +254,27 @@ describe('RocketCli e2e', () => {
|
|||||||
|
|
||||||
describe('can adjust the eleventy config while having access to the rocketConfig', () => {
|
describe('can adjust the eleventy config while having access to the rocketConfig', () => {
|
||||||
it('testing start', async () => {
|
it('testing start', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/adjust-eleventy-config/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
'e2e-fixtures/adjust-eleventy-config/rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.equal('<p><a href="start:/path/to/page/">link</a></p>');
|
expect(indexHtml).to.equal('<p><a href="start:/path/to/page/">link</a></p>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('testing build', async () => {
|
it('testing build', async () => {
|
||||||
cli = await executeBuild('e2e-fixtures/adjust-eleventy-config/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
const indexBuildHtml = await readBuildOutput(cli, 'index.html', {
|
'e2e-fixtures/adjust-eleventy-config/rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
type: 'build',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexBuildHtml = await readOutput('index.html', {
|
||||||
stripToBody: true,
|
stripToBody: true,
|
||||||
});
|
});
|
||||||
expect(indexBuildHtml).to.equal('<p><a href="build:/path/to/page/">link</a></p>');
|
expect(indexBuildHtml).to.equal('<p><a href="build:/path/to/page/">link</a></p>');
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { executeStart, readStartOutput, setFixtureDir } from '@rocket/cli/test-helpers';
|
import { execute, setFixtureDir } from '@rocket/cli/test-helpers';
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('RocketCli images', () => {
|
describe('RocketCli images', () => {
|
||||||
let cli;
|
let cleanupCli;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// ignore colors in tests as most CIs won't support it
|
// ignore colors in tests as most CIs won't support it
|
||||||
@@ -14,15 +14,18 @@ describe('RocketCli images', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (cli?.cleanup) {
|
if (cleanupCli?.cleanup) {
|
||||||
await cli.cleanup();
|
await cleanupCli.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Images', () => {
|
describe('Images', () => {
|
||||||
it('does render content images responsive', async () => {
|
it('does render content images responsive', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/images/rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/images/rocket.config.js', {
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html', {
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
@@ -57,7 +60,7 @@ describe('RocketCli images', () => {
|
|||||||
].join('\n'),
|
].join('\n'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const keepSvgHtml = await readStartOutput(cli, 'ignores/index.html', {
|
const keepSvgHtml = await readOutput('ignores/index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
@@ -102,7 +105,7 @@ describe('RocketCli images', () => {
|
|||||||
].join('\n'),
|
].join('\n'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const tableHtml = await readStartOutput(cli, 'table/index.html', {
|
const tableHtml = await readOutput('table/index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
@@ -150,8 +153,12 @@ describe('RocketCli images', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can configure more patterns to ignore', async () => {
|
it('can configure more patterns to ignore', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/images/ignore-more.rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
const keepSvgHtml = await readStartOutput(cli, 'ignores/index.html', {
|
'e2e-fixtures/images/ignore-more.rocket.config.js',
|
||||||
|
{ captureLog: true },
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
const keepSvgHtml = await readOutput('ignores/index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
@@ -178,8 +185,11 @@ describe('RocketCli images', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders multiple images in the correct order', async () => {
|
it('renders multiple images in the correct order', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/images/rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/images/rocket.config.js', {
|
||||||
const indexHtml = await readStartOutput(cli, 'two-images/index.html', {
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('two-images/index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
@@ -242,8 +252,11 @@ describe('RocketCli images', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can configure those responsive images', async () => {
|
it('can configure those responsive images', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/images/small.rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/images/small.rocket.config.js', {
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html', {
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
@@ -280,8 +293,11 @@ describe('RocketCli images', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('will only render a figure & figcaption if there is a caption/title', async () => {
|
it('will only render a figure & figcaption if there is a caption/title', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/images/small.rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/images/small.rocket.config.js', {
|
||||||
const indexHtml = await readStartOutput(cli, 'no-title/index.html', {
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('no-title/index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
@@ -315,8 +331,12 @@ describe('RocketCli images', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('will render an img with srcset and sizes if there is only one image format', async () => {
|
it('will render an img with srcset and sizes if there is only one image format', async () => {
|
||||||
cli = await executeStart('e2e-fixtures/images/single-format.rocket.config.js');
|
const {
|
||||||
const indexHtml = await readStartOutput(cli, 'no-title/index.html', {
|
cli,
|
||||||
|
readOutput,
|
||||||
|
} = await execute('e2e-fixtures/images/single-format.rocket.config.js', { captureLog: true });
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('no-title/index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import {
|
import { execute, trimWhiteSpace, setFixtureDir } from '@rocket/cli/test-helpers';
|
||||||
executeStart,
|
|
||||||
readStartOutput,
|
|
||||||
trimWhiteSpace,
|
|
||||||
setFixtureDir,
|
|
||||||
} from '@rocket/cli/test-helpers';
|
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('RocketCli mergeTemplates', () => {
|
describe('RocketCli mergeTemplates', () => {
|
||||||
let cli;
|
let cleanupCli;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// ignore colors in tests as most CIs won't support it
|
// ignore colors in tests as most CIs won't support it
|
||||||
@@ -19,15 +14,18 @@ describe('RocketCli mergeTemplates', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (cli?.cleanup) {
|
if (cleanupCli?.cleanup) {
|
||||||
await cli.cleanup();
|
await cleanupCli.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('merges it in the defined order', async () => {
|
it('merges it in the defined order', async () => {
|
||||||
cli = await executeStart('merge-templates-fixtures/order/rocket.config.js');
|
const { cli, readOutput } = await execute('merge-templates-fixtures/order/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(trimWhiteSpace(indexHtml)).to.equal(
|
expect(trimWhiteSpace(indexHtml)).to.equal(
|
||||||
[
|
[
|
||||||
'<p>30-first</p>',
|
'<p>30-first</p>',
|
||||||
@@ -40,9 +38,13 @@ describe('RocketCli mergeTemplates', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('presets can overwrite in order', async () => {
|
it('presets can overwrite in order', async () => {
|
||||||
cli = await executeStart('merge-templates-fixtures/overwrite/rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
|
'merge-templates-fixtures/overwrite/rocket.config.js',
|
||||||
|
{ captureLog: true },
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(trimWhiteSpace(indexHtml)).to.equal(
|
expect(trimWhiteSpace(indexHtml)).to.equal(
|
||||||
['<p>overwritten second</p>', '<p>third</p>', '<p>overwritten first to be last</p>'].join(
|
['<p>overwritten second</p>', '<p>third</p>', '<p>overwritten first to be last</p>'].join(
|
||||||
'\n',
|
'\n',
|
||||||
@@ -51,9 +53,12 @@ describe('RocketCli mergeTemplates', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('presets can add inbetween', async () => {
|
it('presets can add inbetween', async () => {
|
||||||
cli = await executeStart('merge-templates-fixtures/add/rocket.config.js');
|
const { cli, readOutput } = await execute('merge-templates-fixtures/add/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(trimWhiteSpace(indexHtml)).to.equal(
|
expect(trimWhiteSpace(indexHtml)).to.equal(
|
||||||
[
|
[
|
||||||
'<p>first</p>',
|
'<p>first</p>',
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { executeStart, readStartOutput, setFixtureDir } from '@rocket/cli/test-helpers';
|
import { execute, setFixtureDir } from '@rocket/cli/test-helpers';
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('RocketCli preset', () => {
|
describe('RocketCli preset', () => {
|
||||||
let cli;
|
let cleanupCli;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// ignore colors in tests as most CIs won't support it
|
// ignore colors in tests as most CIs won't support it
|
||||||
@@ -14,21 +14,24 @@ describe('RocketCli preset', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (cli?.cleanup) {
|
if (cleanupCli?.cleanup) {
|
||||||
await cli.cleanup();
|
await cleanupCli.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only('offers a default layout (with head, header, content, footer, bottom) and raw layout', async () => {
|
it('offers a default layout (with head, header, content, footer, bottom) and raw layout', async () => {
|
||||||
cli = await executeStart('preset-fixtures/default/rocket.config.js');
|
const { cli, readOutput } = await execute('preset-fixtures/default/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const rawHtml = await readStartOutput(cli, 'raw/index.html');
|
const rawHtml = await readOutput('raw/index.html');
|
||||||
expect(rawHtml).to.equal('<p>Just raw</p>');
|
expect(rawHtml).to.equal('<p>Just raw</p>');
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.include('<body layout="layout-index">');
|
expect(indexHtml).to.include('<body layout="layout-index">');
|
||||||
|
|
||||||
const pageHtml = await readStartOutput(cli, 'page/index.html', {
|
const pageHtml = await readOutput('page/index.html', {
|
||||||
stripScripts: true,
|
stripScripts: true,
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
});
|
});
|
||||||
@@ -93,16 +96,22 @@ describe('RocketCli preset', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('allows to add content to the head without overriding', async () => {
|
it('allows to add content to the head without overriding', async () => {
|
||||||
cli = await executeStart('preset-fixtures/add-to-head/rocket.config.js');
|
const { cli, readOutput } = await execute('preset-fixtures/add-to-head/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
const indexHtml = await readOutput('index.html');
|
||||||
expect(indexHtml).to.include('<meta name="added" content="at the top" />');
|
expect(indexHtml).to.include('<meta name="added" content="at the top" />');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('a preset can provide an adjustImagePresets() function', async () => {
|
it('a preset can provide an adjustImagePresets() function', async () => {
|
||||||
cli = await executeStart('preset-fixtures/use-preset/rocket.config.js');
|
const { cli, readOutput } = await execute('preset-fixtures/use-preset/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html', {
|
const indexHtml = await readOutput('index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
replaceImageHashes: true,
|
replaceImageHashes: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { executeBuild, readStartOutput, setFixtureDir } from '@rocket/cli/test-helpers';
|
import { execute, setFixtureDir } from '@rocket/cli/test-helpers';
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ function getServiceWorkerUrl(text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('RocketCli e2e', () => {
|
describe('RocketCli e2e', () => {
|
||||||
let cli;
|
let cleanupCli;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// ignore colors in tests as most CIs won't support it
|
// ignore colors in tests as most CIs won't support it
|
||||||
@@ -26,20 +26,28 @@ describe('RocketCli e2e', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (cli?.cleanup) {
|
if (cleanupCli?.cleanup) {
|
||||||
await cli.cleanup();
|
await cleanupCli.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only('will add a script to inject the service worker', async () => {
|
it('will add a script to inject the service worker', async () => {
|
||||||
cli = await executeBuild('e2e-fixtures/service-worker/rocket.config.js');
|
const { cli, readOutput } = await execute('e2e-fixtures/service-worker/rocket.config.js', {
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
captureLog: true,
|
||||||
|
type: 'build',
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
|
// we check the start output here as in the rollup build version it's hard to find
|
||||||
|
const indexHtml = await readOutput('../__output-dev/index.html');
|
||||||
const indexInject = getInjectServiceWorker(indexHtml);
|
const indexInject = getInjectServiceWorker(indexHtml);
|
||||||
expect(indexInject).to.equal(
|
expect(indexInject).to.equal(
|
||||||
'<script type="module" inject-service-worker="" src="/_merged_assets/scripts/registerServiceWorker.js"></script>',
|
'<script type="module" inject-service-worker="" src="/_merged_assets/scripts/registerServiceWorker.js"></script>',
|
||||||
);
|
);
|
||||||
expect(getServiceWorkerUrl(indexHtml)).to.equal('/service-worker.js');
|
expect(getServiceWorkerUrl(indexHtml)).to.equal('/service-worker.js');
|
||||||
const subHtml = await readStartOutput(cli, 'sub/index.html');
|
|
||||||
|
// we check the start output here as in the rollup build version it's hard to find
|
||||||
|
const subHtml = await readOutput('../__output-dev/sub/index.html');
|
||||||
const subInject = getInjectServiceWorker(subHtml);
|
const subInject = getInjectServiceWorker(subHtml);
|
||||||
expect(subInject).to.equal(
|
expect(subInject).to.equal(
|
||||||
'<script type="module" inject-service-worker="" src="/_merged_assets/scripts/registerServiceWorker.js"></script>',
|
'<script type="module" inject-service-worker="" src="/_merged_assets/scripts/registerServiceWorker.js"></script>',
|
||||||
@@ -49,14 +57,21 @@ describe('RocketCli e2e', () => {
|
|||||||
|
|
||||||
// TODO: find a way to run these test either by forcing pathPrefix in start or skipping asset gathering for build or ...
|
// TODO: find a way to run these test either by forcing pathPrefix in start or skipping asset gathering for build or ...
|
||||||
it.skip('will add a script to inject the service worker', async () => {
|
it.skip('will add a script to inject the service worker', async () => {
|
||||||
cli = await executeBuild('e2e-fixtures/service-worker/pathPrefix.rocket.config.js');
|
const { cli, readOutput } = await execute(
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html');
|
'e2e-fixtures/service-worker/pathPrefix.rocket.config.js',
|
||||||
|
{
|
||||||
|
captureLog: true,
|
||||||
|
type: 'build',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
cleanupCli = cli;
|
||||||
|
const indexHtml = await readOutput('index.html');
|
||||||
const indexInject = getInjectServiceWorker(indexHtml);
|
const indexInject = getInjectServiceWorker(indexHtml);
|
||||||
expect(indexInject).to.equal(
|
expect(indexInject).to.equal(
|
||||||
'<script type="module" inject-service-worker="" src="/my-prefix-folder/_merged_assets/scripts/registerServiceWorker.js"></script>',
|
'<script type="module" inject-service-worker="" src="/my-prefix-folder/_merged_assets/scripts/registerServiceWorker.js"></script>',
|
||||||
);
|
);
|
||||||
expect(getServiceWorkerUrl(indexHtml)).to.equal('/my-prefix-folder/service-worker.js');
|
expect(getServiceWorkerUrl(indexHtml)).to.equal('/my-prefix-folder/service-worker.js');
|
||||||
const subHtml = await readStartOutput(cli, 'sub/index.html');
|
const subHtml = await readOutput('sub/index.html');
|
||||||
const subInject = getInjectServiceWorker(subHtml);
|
const subInject = getInjectServiceWorker(subHtml);
|
||||||
expect(subInject).to.equal(
|
expect(subInject).to.equal(
|
||||||
'<script type="module" inject-service-worker="" src="/my-prefix-folder/_merged_assets/scripts/registerServiceWorker.js"></script>',
|
'<script type="module" inject-service-worker="" src="/my-prefix-folder/_merged_assets/scripts/registerServiceWorker.js"></script>',
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import {
|
import { execute, setFixtureDir } from '@rocket/cli/test-helpers';
|
||||||
executeStart,
|
|
||||||
readStartOutput,
|
|
||||||
setFixtureDir,
|
|
||||||
startOutputExist,
|
|
||||||
} from '@rocket/cli/test-helpers';
|
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('RocketCli use cases', () => {
|
describe('RocketCli use cases', () => {
|
||||||
let cli;
|
let cleanupCli;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// ignore colors in tests as most CIs won't support it
|
// ignore colors in tests as most CIs won't support it
|
||||||
@@ -19,18 +14,22 @@ describe('RocketCli use cases', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (cli?.cleanup) {
|
if (cleanupCli?.cleanup) {
|
||||||
await cli.cleanup();
|
await cleanupCli.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports dynamic imports', async () => {
|
it('supports dynamic imports', async () => {
|
||||||
cli = await executeStart('use-cases/dynamic-imports/rocket.config.js');
|
const {
|
||||||
|
cli,
|
||||||
|
readOutput,
|
||||||
|
outputExists,
|
||||||
|
} = await execute('use-cases/dynamic-imports/rocket.config.js', { captureLog: true });
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
expect(startOutputExist(cli, 'sub/assets/myData.js'), 'static files did not get copied').to.be
|
expect(outputExists('sub/assets/myData.js'), 'static files did not get copied').to.be.true;
|
||||||
.true;
|
|
||||||
|
|
||||||
const aboutHtml = await readStartOutput(cli, 'about/index.html', { formatHtml: true });
|
const aboutHtml = await readOutput('about/index.html', { formatHtml: true });
|
||||||
expect(aboutHtml).to.equal(
|
expect(aboutHtml).to.equal(
|
||||||
[
|
[
|
||||||
'<p><code>about.md</code></p>',
|
'<p><code>about.md</code></p>',
|
||||||
@@ -38,7 +37,7 @@ describe('RocketCli use cases', () => {
|
|||||||
].join('\n'),
|
].join('\n'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const subHtml = await readStartOutput(cli, 'sub/index.html', { formatHtml: true });
|
const subHtml = await readOutput('sub/index.html', { formatHtml: true });
|
||||||
expect(subHtml).to.equal(
|
expect(subHtml).to.equal(
|
||||||
[
|
[
|
||||||
'<p><code>sub/index.md</code></p>',
|
'<p><code>sub/index.md</code></p>',
|
||||||
@@ -46,7 +45,7 @@ describe('RocketCli use cases', () => {
|
|||||||
].join('\n'),
|
].join('\n'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const subDetailsHtml = await readStartOutput(cli, 'sub/details/index.html', {
|
const subDetailsHtml = await readOutput('sub/details/index.html', {
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
});
|
});
|
||||||
expect(subDetailsHtml).to.equal(
|
expect(subDetailsHtml).to.equal(
|
||||||
@@ -56,7 +55,7 @@ describe('RocketCli use cases', () => {
|
|||||||
].join('\n'),
|
].join('\n'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html', { formatHtml: true });
|
const indexHtml = await readOutput('index.html', { formatHtml: true });
|
||||||
expect(indexHtml).to.equal(
|
expect(indexHtml).to.equal(
|
||||||
[
|
[
|
||||||
'<p><code>index.md</code></p>',
|
'<p><code>index.md</code></p>',
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import remark2rehype from 'remark-rehype';
|
||||||
import { adjustPluginOptions } from 'plugins-manager';
|
import { adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
function image(h, node) {
|
function image(h, node) {
|
||||||
@@ -10,7 +11,7 @@ function image(h, node) {
|
|||||||
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
||||||
const config = {
|
const config = {
|
||||||
setupUnifiedPlugins: [
|
setupUnifiedPlugins: [
|
||||||
adjustPluginOptions('remark2rehype', {
|
adjustPluginOptions(remark2rehype, {
|
||||||
handlers: {
|
handlers: {
|
||||||
image,
|
image,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
import { addPlugin } from 'plugins-manager';
|
import { addPlugin } from 'plugins-manager';
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static dataName = 'test';
|
||||||
|
|
||||||
|
execute() {
|
||||||
|
return 'test-value';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
||||||
const config = {
|
const config = {
|
||||||
setupEleventyComputedConfig: [addPlugin({ name: 'test', plugin: () => 'test-value' })],
|
setupEleventyComputedConfig: [addPlugin(Test)],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { adjustPluginOptions } from 'plugins-manager';
|
import { adjustPluginOptions } from 'plugins-manager';
|
||||||
|
import { SocialMediaImagePlugin } from '@rocket/cli';
|
||||||
|
|
||||||
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
||||||
const config = {
|
const config = {
|
||||||
@@ -6,7 +7,7 @@ const config = {
|
|||||||
createSocialMediaImages: true,
|
createSocialMediaImages: true,
|
||||||
},
|
},
|
||||||
setupEleventyComputedConfig: [
|
setupEleventyComputedConfig: [
|
||||||
adjustPluginOptions('socialMediaImage', {
|
adjustPluginOptions(SocialMediaImagePlugin, {
|
||||||
createSocialImageSvg: async () => {
|
createSocialImageSvg: async () => {
|
||||||
return `
|
return `
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630">
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
// @ts-no-check
|
// @ts-no-check
|
||||||
import json from '@rollup/plugin-json';
|
import json from '@rollup/plugin-json';
|
||||||
|
import { rollupPluginHTML } from '@web/rollup-plugin-html';
|
||||||
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
import { addPlugin, adjustPluginOptions } from 'plugins-manager';
|
||||||
|
|
||||||
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
||||||
const config = {
|
const config = {
|
||||||
setupDevAndBuildPlugins: [addPlugin({ name: 'json', plugin: json, location: 'top' })],
|
setupDevAndBuildPlugins: [addPlugin(json, {}, { location: 'top' })],
|
||||||
setupBuildPlugins: [adjustPluginOptions('html', { absoluteBaseUrl: 'https://test-me.com' })],
|
setupBuildPlugins: [
|
||||||
|
adjustPluginOptions(rollupPluginHTML, { absoluteBaseUrl: 'https://test-me.com' }),
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
// @ts-no-check
|
|
||||||
import json from '@rollup/plugin-json';
|
import json from '@rollup/plugin-json';
|
||||||
import { addPlugin } from 'plugins-manager';
|
import { addPlugin } from 'plugins-manager';
|
||||||
|
|
||||||
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
||||||
const config = {
|
const config = {
|
||||||
setupDevAndBuildPlugins: [addPlugin({ name: 'json', plugin: json, location: 'top' })],
|
setupDevAndBuildPlugins: [addPlugin(json, {}, { location: 'top' })],
|
||||||
devServer: {
|
devServer: {
|
||||||
mimeTypes: {
|
mimeTypes: {
|
||||||
// serve all json files as js
|
// serve all json files as js
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
import emoji from 'remark-emoji';
|
import emoji from 'remark-emoji';
|
||||||
import { addPlugin } from 'plugins-manager';
|
import { addPlugin } from 'plugins-manager';
|
||||||
|
import markdown from 'remark-parse';
|
||||||
|
|
||||||
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
/** @type {Partial<import("../../../types/main").RocketCliOptions>} */
|
||||||
const config = {
|
const config = {
|
||||||
setupUnifiedPlugins: [addPlugin({ location: 'markdown', name: 'emoji', plugin: emoji })],
|
setupUnifiedPlugins: [addPlugin(emoji, {}, { location: markdown })],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
import chai from 'chai';
|
|
||||||
import { RocketCli } from '../src/RocketCli.js';
|
|
||||||
import path from 'path';
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
import fs from 'fs-extra';
|
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
||||||
|
|
||||||
const { expect } = chai;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {function} method
|
|
||||||
* @param {string} errorMessage
|
|
||||||
*/
|
|
||||||
export async function expectThrowsAsync(method, { errorMatch, errorMessage } = {}) {
|
|
||||||
let error = null;
|
|
||||||
try {
|
|
||||||
await method();
|
|
||||||
} catch (err) {
|
|
||||||
error = err;
|
|
||||||
}
|
|
||||||
expect(error).to.be.an('Error', 'No error was thrown');
|
|
||||||
if (errorMatch) {
|
|
||||||
expect(error.message).to.match(errorMatch);
|
|
||||||
}
|
|
||||||
if (errorMessage) {
|
|
||||||
expect(error.message).to.equal(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function readOutput(
|
|
||||||
cli,
|
|
||||||
fileName,
|
|
||||||
{ stripToBody = false, stripStartEndWhitespace = true, type = 'build' } = {},
|
|
||||||
) {
|
|
||||||
const outputDir = type === 'build' ? cli.config.outputDir : cli.config.outputDevDir;
|
|
||||||
let text = await fs.promises.readFile(path.join(outputDir, fileName));
|
|
||||||
text = text.toString();
|
|
||||||
if (stripToBody) {
|
|
||||||
const bodyOpenTagEnd = text.indexOf('>', text.indexOf('<body') + 1) + 1;
|
|
||||||
const bodyCloseTagStart = text.indexOf('</body>');
|
|
||||||
text = text.substring(bodyOpenTagEnd, bodyCloseTagStart);
|
|
||||||
}
|
|
||||||
if (stripStartEndWhitespace) {
|
|
||||||
text = text.trim();
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function readStartOutput(cli, fileName, options = {}) {
|
|
||||||
options.type = 'start';
|
|
||||||
return readOutput(cli, fileName, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function execute(cli, configFileDir) {
|
|
||||||
await cli.setup();
|
|
||||||
cli.config.outputDevDir = path.join(configFileDir, '__output-dev');
|
|
||||||
cli.config.devServer.open = false;
|
|
||||||
cli.config.watch = false;
|
|
||||||
cli.config.outputDir = path.join(configFileDir, '__output');
|
|
||||||
await cli.run();
|
|
||||||
return cli;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function executeStart(pathToConfig) {
|
|
||||||
const configFile = path.join(__dirname, pathToConfig.split('/').join(path.sep));
|
|
||||||
const cli = new RocketCli({
|
|
||||||
argv: ['start', '--config-file', configFile],
|
|
||||||
});
|
|
||||||
await execute(cli, path.dirname(configFile));
|
|
||||||
return cli;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function executeLint(pathToConfig) {
|
|
||||||
const configFile = path.join(__dirname, pathToConfig.split('/').join(path.sep));
|
|
||||||
const cli = new RocketCli({
|
|
||||||
argv: ['lint', '--config-file', configFile],
|
|
||||||
});
|
|
||||||
await execute(cli, path.dirname(configFile));
|
|
||||||
return cli;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function trimWhiteSpace(inString) {
|
|
||||||
return inString
|
|
||||||
.split('\n')
|
|
||||||
.map(line => line.trim())
|
|
||||||
.filter(line => line)
|
|
||||||
.join('\n');
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,17 @@
|
|||||||
# @rocket/drawer
|
# @rocket/drawer
|
||||||
|
|
||||||
|
## 0.1.5
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 1f14105: Add export map which enables side effect import via `@rocket/drawer/define`
|
||||||
|
|
||||||
|
## 0.1.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 445b028: Update to latest lit, @open-wc, @lion packages
|
||||||
|
|
||||||
## 0.1.3
|
## 0.1.3
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/drawer",
|
"name": "@rocket/drawer",
|
||||||
"version": "0.1.3",
|
"version": "0.1.5",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -13,6 +13,11 @@
|
|||||||
},
|
},
|
||||||
"author": "Modern Web <hello@modern-web.dev> (https://modern-web.dev/)",
|
"author": "Modern Web <hello@modern-web.dev> (https://modern-web.dev/)",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
"exports": {
|
||||||
|
".": "./index.js",
|
||||||
|
"./rocket-drawer.js": "./rocket-drawer.js",
|
||||||
|
"./define": "./rocket-drawer.js"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "web-dev-server --node-resolve --root-dir ../../ --open packages/drawer/ --watch",
|
"dev": "web-dev-server --node-resolve --root-dir ../../ --open packages/drawer/ --watch",
|
||||||
"rocket:build": "node src/build/cli.js -c demo/docs",
|
"rocket:build": "node src/build/cli.js -c demo/docs",
|
||||||
@@ -33,8 +38,8 @@
|
|||||||
"testing"
|
"testing"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lion/overlays": "^0.26.1",
|
"@lion/overlays": "^0.29.1",
|
||||||
"lit-element": "^2.4.0"
|
"lit": "^2.0.0"
|
||||||
},
|
},
|
||||||
"types": "dist-types/index.d.ts"
|
"types": "dist-types/index.d.ts"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
# @rocket/eleventy-plugin-mdjs-unified
|
# @rocket/eleventy-plugin-mdjs-unified
|
||||||
|
|
||||||
|
## 0.6.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Updating to latest version of `@mdjs/core` which requires the latest version of `plugins-manager`
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- @mdjs/core@0.9.0
|
||||||
|
|
||||||
## 0.5.2
|
## 0.5.2
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/eleventy-plugin-mdjs-unified",
|
"name": "@rocket/eleventy-plugin-mdjs-unified",
|
||||||
"version": "0.5.2",
|
"version": "0.6.0",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"mdjs"
|
"mdjs"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdjs/core": "^0.8.2",
|
"@mdjs/core": "^0.9.0",
|
||||||
"es-module-lexer": "^0.3.26",
|
"es-module-lexer": "^0.3.26",
|
||||||
"unist-util-visit": "^2.0.3"
|
"unist-util-visit": "^2.0.3"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const fs = require('fs');
|
|||||||
const { mdjsProcess } = require('@mdjs/core');
|
const { mdjsProcess } = require('@mdjs/core');
|
||||||
const visit = require('unist-util-visit');
|
const visit = require('unist-util-visit');
|
||||||
const { init, parse } = require('es-module-lexer');
|
const { init, parse } = require('es-module-lexer');
|
||||||
|
const markdown = require('remark-parse');
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { parseTitle } = require('@rocket/core/title');
|
const { parseTitle } = require('@rocket/core/title');
|
||||||
@@ -45,12 +46,12 @@ function cleanupTitleHeadline() {
|
|||||||
* @param {MdjsProcessPlugin[]} plugins
|
* @param {MdjsProcessPlugin[]} plugins
|
||||||
*/
|
*/
|
||||||
function addCleanupTitleHeadline(plugins) {
|
function addCleanupTitleHeadline(plugins) {
|
||||||
if (plugins.findIndex(plugin => plugin.name === 'cleanupTitleHeadline') === -1) {
|
if (plugins.findIndex(pluginObj => pluginObj.plugin === cleanupTitleHeadline) === -1) {
|
||||||
// add plugins right after markdown
|
// add plugins right after markdown
|
||||||
const markdownPluginIndex = plugins.findIndex(plugin => plugin.name === 'markdown');
|
const markdownPluginIndex = plugins.findIndex(pluginObj => pluginObj.plugin === markdown);
|
||||||
plugins.splice(markdownPluginIndex + 1, 0, {
|
plugins.splice(markdownPluginIndex + 1, 0, {
|
||||||
name: 'cleanupTitleHeadline',
|
|
||||||
plugin: cleanupTitleHeadline,
|
plugin: cleanupTitleHeadline,
|
||||||
|
options: {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return plugins;
|
return plugins;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
const htmlHeading = require('rehype-autolink-headings');
|
||||||
const pluginMdjs = require('../../../index.js');
|
const pluginMdjs = require('../../../index.js');
|
||||||
|
|
||||||
function addClassAnchorToHtmlHeading(plugins) {
|
function addClassAnchorToHtmlHeading(plugins) {
|
||||||
return plugins.map(pluginObj => {
|
return plugins.map(pluginObj => {
|
||||||
if (pluginObj.name === 'htmlHeading') {
|
if (pluginObj.plugin === htmlHeading) {
|
||||||
return {
|
return {
|
||||||
...pluginObj,
|
...pluginObj,
|
||||||
options: {
|
options: {
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# @rocket/eleventy-rocket-nav
|
# @rocket/eleventy-rocket-nav
|
||||||
|
|
||||||
|
## 0.3.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 60310ab: Improve performance by initializing sax-wasm only once even when it is running in parallel
|
||||||
|
|
||||||
## 0.3.0
|
## 0.3.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/eleventy-rocket-nav",
|
"name": "@rocket/eleventy-rocket-nav",
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ function getHeadingsOfHtml(html) {
|
|||||||
return { headings, insertPoint };
|
return { headings, insertPoint };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @type {boolean | Promise<unknown>} */
|
||||||
let isSetup = false;
|
let isSetup = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,9 +105,9 @@ let isSetup = false;
|
|||||||
*/
|
*/
|
||||||
async function addPageAnchors(content) {
|
async function addPageAnchors(content) {
|
||||||
if (!isSetup) {
|
if (!isSetup) {
|
||||||
await parser.prepareWasm(saxWasmBuffer);
|
isSetup = parser.prepareWasm(saxWasmBuffer);
|
||||||
isSetup = true;
|
|
||||||
}
|
}
|
||||||
|
await isSetup;
|
||||||
|
|
||||||
const { headings, insertPoint } = getHeadingsOfHtml(content);
|
const { headings, insertPoint } = getHeadingsOfHtml(content);
|
||||||
const pageAnchorsHtml = [];
|
const pageAnchorsHtml = [];
|
||||||
|
|||||||
@@ -1,5 +1,22 @@
|
|||||||
# @rocket/launch
|
# @rocket/launch
|
||||||
|
|
||||||
|
## 0.6.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Update to latest plugins manager to get type safe options
|
||||||
|
|
||||||
|
There is no longer a name string as a key for a plugin. It is identified by it's function/class. You will need to adjust your code if you are adding or adjusting plugins.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please see the [Changelog](https://github.com/modernweb-dev/rocket/blob/main/packages/plugins-manager/CHANGELOG.md#030) of the plugins-manager package.
|
||||||
|
|
||||||
## 0.5.6
|
## 0.5.6
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@rocket/launch",
|
"name": "@rocket/launch",
|
||||||
"version": "0.5.6",
|
"version": "0.6.0",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ import path from 'path';
|
|||||||
import { adjustPluginOptions } from 'plugins-manager';
|
import { adjustPluginOptions } from 'plugins-manager';
|
||||||
// import { addPlugin } from 'plugins-manager';
|
// import { addPlugin } from 'plugins-manager';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
import { LayoutPlugin } from '@rocket/cli';
|
||||||
|
import htmlHeading from 'rehype-autolink-headings';
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
function addOcticonToHeadlines(plugins) {
|
function addOcticonToHeadlines(plugins) {
|
||||||
return plugins.map(pluginObj => {
|
return plugins.map(pluginObj => {
|
||||||
if (pluginObj.name === 'htmlHeading') {
|
if (pluginObj.plugin === htmlHeading) {
|
||||||
return {
|
return {
|
||||||
...pluginObj,
|
...pluginObj,
|
||||||
options: {
|
options: {
|
||||||
@@ -50,7 +52,7 @@ export function rocketLaunch() {
|
|||||||
path: path.resolve(__dirname),
|
path: path.resolve(__dirname),
|
||||||
setupUnifiedPlugins: [addOcticonToHeadlines],
|
setupUnifiedPlugins: [addOcticonToHeadlines],
|
||||||
setupEleventyComputedConfig: [
|
setupEleventyComputedConfig: [
|
||||||
adjustPluginOptions('layout', { defaultLayout: 'layout-sidebar' }),
|
adjustPluginOptions(LayoutPlugin, { defaultLayout: 'layout-sidebar' }),
|
||||||
],
|
],
|
||||||
adjustImagePresets: imagePresets => ({
|
adjustImagePresets: imagePresets => ({
|
||||||
...imagePresets,
|
...imagePresets,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { executeStart, readStartOutput, setFixtureDir } from '@rocket/cli/test-helpers';
|
import { execute, setFixtureDir } from '@rocket/cli/test-helpers';
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('RocketLaunch preset', () => {
|
describe('RocketLaunch preset', () => {
|
||||||
let cli;
|
let cleanupCli;
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
// ignore colors in tests as most CIs won't support it
|
// ignore colors in tests as most CIs won't support it
|
||||||
@@ -14,15 +14,18 @@ describe('RocketLaunch preset', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
if (cli?.cleanup) {
|
if (cleanupCli?.cleanup) {
|
||||||
await cli.cleanup();
|
await cleanupCli.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only('sets layout-sidebar as default', async () => {
|
it('sets layout-sidebar as default', async () => {
|
||||||
cli = await executeStart('fixtures/layout-sidebar/rocket.config.js');
|
const { cli, readOutput } = await execute('fixtures/layout-sidebar/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'page/index.html', {
|
const indexHtml = await readOutput('page/index.html', {
|
||||||
stripScripts: true,
|
stripScripts: true,
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
});
|
});
|
||||||
@@ -251,9 +254,12 @@ describe('RocketLaunch preset', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('offers a layout-home', async () => {
|
it('offers a layout-home', async () => {
|
||||||
cli = await executeStart('fixtures/layout-home/rocket.config.js');
|
const { cli, readOutput } = await execute('fixtures/layout-home/rocket.config.js', {
|
||||||
|
captureLog: true,
|
||||||
|
});
|
||||||
|
cleanupCli = cli;
|
||||||
|
|
||||||
const indexHtml = await readStartOutput(cli, 'index.html', {
|
const indexHtml = await readOutput('index.html', {
|
||||||
stripScripts: true,
|
stripScripts: true,
|
||||||
formatHtml: true,
|
formatHtml: true,
|
||||||
});
|
});
|
||||||
@@ -502,12 +508,6 @@ describe('RocketLaunch preset', () => {
|
|||||||
' </footer>',
|
' </footer>',
|
||||||
'',
|
'',
|
||||||
' <script type="module" src="/_merged_assets/scripts/init-navigation.js"></script>',
|
' <script type="module" src="/_merged_assets/scripts/init-navigation.js"></script>',
|
||||||
'',
|
|
||||||
' <script',
|
|
||||||
' type="module"',
|
|
||||||
' inject-service-worker=""',
|
|
||||||
' src="/_merged_assets/scripts/registerServiceWorker.js"',
|
|
||||||
' ></script>',
|
|
||||||
' </body>',
|
' </body>',
|
||||||
'</html>',
|
'</html>',
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
|
|||||||
@@ -1,5 +1,88 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 0.9.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- e6c3d27: Support `js client` as an alias to `js script`
|
||||||
|
|
||||||
|
## 0.9.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 62637a8: Replaces `rehype-prism-template` with `rehype-prism` to get a newer version of prism with essential security updates
|
||||||
|
|
||||||
|
## 0.9.2
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 97cb38c: Add missing slash dependency
|
||||||
|
|
||||||
|
## 0.9.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 6221e5f: If your preview is followed by a code blocks marked as `story-code` then those will be shown when switching between multiple platforms
|
||||||
|
|
||||||
|
````md
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () =>
|
||||||
|
html`
|
||||||
|
<demo-wc-card>JS Preview Story</demo-wc-card>
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoWcCard"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.FooComponents.Demo.Wc.Card"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import DemoWc.Card
|
||||||
|
|
||||||
|
let card = DemoWcButton()
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
- Updated dependencies [5c6b9c9]
|
||||||
|
- Updated dependencies [6221e5f]
|
||||||
|
- @mdjs/mdjs-preview@0.5.3
|
||||||
|
|
||||||
|
## 0.9.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: Update to latest plugins manager to get type safe options
|
||||||
|
|
||||||
|
There is no longer a name string as a key for a plugin. It is identified by it's function/class. You will need to adjust your code if you are adding or adjusting plugins.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please see the [Changelog](https://github.com/modernweb-dev/rocket/blob/main/packages/plugins-manager/CHANGELOG.md#030) of the plugins-manager package.
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- Updated dependencies [70bb7a1]
|
||||||
|
- plugins-manager@0.3.0
|
||||||
|
|
||||||
## 0.8.2
|
## 0.8.2
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
# Markdown with JavaScript (mdjs)
|
# Markdown with JavaScript (mdjs)
|
||||||
|
|
||||||
Combine Markdown with JavaScript
|
[=> See Source <=](../../docs/docs/markdown-javascript/overview.md)
|
||||||
|
|
||||||
For docs please see our homepage [https://rocket.modern-web.dev/docs/markdown-javascript/overview/](https://rocket.modern-web.dev/docs/markdown-javascript/overview/).
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
/** @typedef {import('@mdjs/core/types/code').MdjsProcessPlugin} MdjsProcessPlugin */
|
/** @typedef {import('@mdjs/core/types/code').MdjsProcessPlugin} MdjsProcessPlugin */
|
||||||
|
|
||||||
const { mdjsParse } = require('./src/mdjsParse.js');
|
const { mdjsParse } = require('./src/mdjsParse.js');
|
||||||
|
const { mdjsSetupCode } = require('./src/mdjsSetupCode.js');
|
||||||
const { mdjsStoryParse } = require('./src/mdjsStoryParse.js');
|
const { mdjsStoryParse } = require('./src/mdjsStoryParse.js');
|
||||||
const { mdjsDocPage } = require('./src/mdjsDocPage.js');
|
const { mdjsDocPage } = require('./src/mdjsDocPage.js');
|
||||||
const { mdjsProcess } = require('./src/mdjsProcess.js');
|
const { mdjsProcess } = require('./src/mdjsProcess.js');
|
||||||
@@ -14,4 +15,5 @@ module.exports = {
|
|||||||
mdjsDocPage,
|
mdjsDocPage,
|
||||||
mdjsProcess,
|
mdjsProcess,
|
||||||
isMdjsContent,
|
isMdjsContent,
|
||||||
|
mdjsSetupCode,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
import cjsEntrypoint from './index.js';
|
import cjsEntrypoint from './index.js';
|
||||||
|
|
||||||
const { mdjsParse, mdjsStoryParse, mdjsDocPage, mdjsProcess, isMdjsContent } = cjsEntrypoint;
|
const {
|
||||||
|
mdjsParse,
|
||||||
|
mdjsStoryParse,
|
||||||
|
mdjsDocPage,
|
||||||
|
mdjsProcess,
|
||||||
|
isMdjsContent,
|
||||||
|
mdjsSetupCode,
|
||||||
|
} = cjsEntrypoint;
|
||||||
|
|
||||||
export { mdjsParse, mdjsStoryParse, mdjsDocPage, mdjsProcess, isMdjsContent };
|
export { mdjsParse, mdjsStoryParse, mdjsDocPage, mdjsProcess, isMdjsContent, mdjsSetupCode };
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mdjs/core",
|
"name": "@mdjs/core",
|
||||||
"version": "0.8.2",
|
"version": "0.9.4",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"prepublishOnly": "publish-docs --github-url https://github.com/modernweb-dev/rocket/ --git-root-dir ../../",
|
||||||
"start": "npm run start:stories",
|
"start": "npm run start:stories",
|
||||||
"start:script": "web-dev-server -c demo/script/server.js --root-dir ../../",
|
"start:script": "web-dev-server -c demo/script/server.js --root-dir ../../",
|
||||||
"start:stories": "web-dev-server -c demo/stories/server.js --root-dir ../../",
|
"start:stories": "web-dev-server -c demo/stories/server.js --root-dir ../../",
|
||||||
@@ -44,14 +45,14 @@
|
|||||||
"remark"
|
"remark"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdjs/mdjs-preview": "^0.5.1",
|
"@mdjs/mdjs-preview": "^0.5.3",
|
||||||
"@mdjs/mdjs-story": "^0.3.0",
|
"@mdjs/mdjs-story": "^0.3.0",
|
||||||
"@types/unist": "^2.0.3",
|
"@types/unist": "^2.0.3",
|
||||||
"es-module-lexer": "^0.3.26",
|
"es-module-lexer": "^0.3.26",
|
||||||
"github-markdown-css": "^4.0.0",
|
"github-markdown-css": "^4.0.0",
|
||||||
"plugins-manager": "^0.2.4",
|
"plugins-manager": "^0.3.0",
|
||||||
"rehype-autolink-headings": "^5.0.1",
|
"rehype-autolink-headings": "^5.0.1",
|
||||||
"rehype-prism-template": "^0.4.1",
|
"rehype-prism": "^1.0.0",
|
||||||
"rehype-raw": "^5.0.0",
|
"rehype-raw": "^5.0.0",
|
||||||
"rehype-slug": "^4.0.1",
|
"rehype-slug": "^4.0.1",
|
||||||
"rehype-stringify": "^8.0.0",
|
"rehype-stringify": "^8.0.0",
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
"remark-gfm": "^1.0.0",
|
"remark-gfm": "^1.0.0",
|
||||||
"remark-parse": "^9.0.0",
|
"remark-parse": "^9.0.0",
|
||||||
"remark-rehype": "^8.0.0",
|
"remark-rehype": "^8.0.0",
|
||||||
|
"slash": "^3.0.0",
|
||||||
"unified": "^9.2.0",
|
"unified": "^9.2.0",
|
||||||
"unist-util-remove": "^2.0.1",
|
"unist-util-remove": "^2.0.1",
|
||||||
"unist-util-visit": "^2.0.3"
|
"unist-util-visit": "^2.0.3"
|
||||||
@@ -66,7 +68,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"demo-wc-card": "^0.1.0",
|
"demo-wc-card": "^0.1.0",
|
||||||
"remark-autolink-headings": "^6.0.1",
|
"remark-autolink-headings": "^6.0.1",
|
||||||
"remark-html": "^13.0.1",
|
"remark-html": "^13.0.2",
|
||||||
"remark-slug": "^6.0.0",
|
"remark-slug": "^6.0.0",
|
||||||
"remark-stringify": "^9.0.1"
|
"remark-stringify": "^9.0.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ function mdjsParse() {
|
|||||||
if (node.lang === 'js' && node.meta === 'script') {
|
if (node.lang === 'js' && node.meta === 'script') {
|
||||||
jsCode += node.value;
|
jsCode += node.value;
|
||||||
}
|
}
|
||||||
|
if (node.lang === 'js' && node.meta === 'client') {
|
||||||
|
jsCode += node.value;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// we can only return/modify the tree but jsCode should not be part of the tree
|
// we can only return/modify the tree but jsCode should not be part of the tree
|
||||||
// so we attach it globally to the file.data
|
// so we attach it globally to the file.data
|
||||||
@@ -26,7 +29,9 @@ function mdjsParse() {
|
|||||||
* @param {Node} node
|
* @param {Node} node
|
||||||
*/
|
*/
|
||||||
const removeFunction = node =>
|
const removeFunction = node =>
|
||||||
node.type === 'code' && node.lang === 'js' && node.meta === 'script';
|
node.type === 'code' &&
|
||||||
|
node.lang === 'js' &&
|
||||||
|
(node.meta === 'script' || node.meta === 'client');
|
||||||
remove(tree, removeFunction);
|
remove(tree, removeFunction);
|
||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
/** @typedef {import('@mdjs/core/types/code').Story} Story */
|
/** @typedef {import('../types/code').Story} Story */
|
||||||
/** @typedef {import('@mdjs/core/types/code').ParseResult} ParseResult */
|
/** @typedef {import('../types/code').ParseResult} ParseResult */
|
||||||
/** @typedef {import('@mdjs/core/types/code').ProcessResult} ProcessResult */
|
/** @typedef {import('../types/code').ProcessResult} ProcessResult */
|
||||||
/** @typedef {import('@mdjs/core/types/code').MdjsProcessPlugin} MdjsProcessPlugin */
|
/** @typedef {import('../types/code').MdjsProcessPlugin} MdjsProcessPlugin */
|
||||||
|
|
||||||
const unified = require('unified');
|
const unified = require('unified');
|
||||||
const markdown = require('remark-parse');
|
const markdown = require('remark-parse');
|
||||||
@@ -12,33 +12,33 @@ const raw = require('rehype-raw');
|
|||||||
const htmlStringify = require('rehype-stringify');
|
const htmlStringify = require('rehype-stringify');
|
||||||
const htmlSlug = require('rehype-slug');
|
const htmlSlug = require('rehype-slug');
|
||||||
const htmlHeading = require('rehype-autolink-headings');
|
const htmlHeading = require('rehype-autolink-headings');
|
||||||
const rehypePrism = require('rehype-prism-template');
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { executeSetupFunctions } = require('plugins-manager');
|
const { executeSetupFunctions } = require('plugins-manager');
|
||||||
|
const loadLanguages = require('prismjs/components/');
|
||||||
|
|
||||||
const { mdjsParse } = require('./mdjsParse.js');
|
const { mdjsParse } = require('./mdjsParse.js');
|
||||||
const { mdjsStoryParse } = require('./mdjsStoryParse.js');
|
const { mdjsStoryParse } = require('./mdjsStoryParse.js');
|
||||||
const { mdjsSetupCode } = require('./mdjsSetupCode.js');
|
const { mdjsSetupCode } = require('./mdjsSetupCode.js');
|
||||||
|
|
||||||
|
let prismLoaded = false;
|
||||||
|
|
||||||
/** @type {MdjsProcessPlugin[]} */
|
/** @type {MdjsProcessPlugin[]} */
|
||||||
const defaultMetaPlugins = [
|
const defaultMetaPlugins = [
|
||||||
{ name: 'markdown', plugin: markdown },
|
{ plugin: markdown, options: {} },
|
||||||
{ name: 'gfm', plugin: gfm },
|
{ plugin: gfm, options: {} },
|
||||||
{ name: 'mdjsParse', plugin: mdjsParse },
|
{ plugin: mdjsParse, options: {} },
|
||||||
{ name: 'mdjsStoryParse', plugin: mdjsStoryParse },
|
{ plugin: mdjsStoryParse, options: {} },
|
||||||
{ name: 'mdjsSetupCode', plugin: mdjsSetupCode },
|
{ plugin: mdjsSetupCode, options: {} },
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{ name: 'remark2rehype', plugin: remark2rehype, options: { allowDangerousHtml: true } },
|
{ plugin: remark2rehype, options: { allowDangerousHtml: true } },
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{ name: 'rehypePrism', plugin: rehypePrism },
|
{ plugin: raw, options: {} },
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{ name: 'raw', plugin: raw },
|
{ plugin: htmlSlug, options: {} },
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{ name: 'htmlSlug', plugin: htmlSlug },
|
{ plugin: htmlHeading, options: {} },
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
{ name: 'htmlHeading', plugin: htmlHeading },
|
{ plugin: htmlStringify, options: {} },
|
||||||
// @ts-ignore
|
|
||||||
{ name: 'htmlStringify', plugin: htmlStringify },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,36 +54,17 @@ const defaultMetaPlugins = [
|
|||||||
*/
|
*/
|
||||||
async function mdjsProcess(mdjs, { setupUnifiedPlugins = [] } = {}) {
|
async function mdjsProcess(mdjs, { setupUnifiedPlugins = [] } = {}) {
|
||||||
const parser = unified();
|
const parser = unified();
|
||||||
|
if (!prismLoaded) {
|
||||||
|
prismLoaded = true;
|
||||||
|
const rehypePrism = (await import('rehype-prism/lib/src/index.js')).default;
|
||||||
|
loadLanguages(['md', 'shell', 'yml']);
|
||||||
|
defaultMetaPlugins.splice(6, 0, { plugin: rehypePrism, options: {} });
|
||||||
|
}
|
||||||
|
|
||||||
const metaPlugins = executeSetupFunctions(setupUnifiedPlugins, defaultMetaPlugins);
|
const metaPlugins = executeSetupFunctions(setupUnifiedPlugins, defaultMetaPlugins);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} code
|
|
||||||
*/
|
|
||||||
async function highlightCode(code) {
|
|
||||||
// @ts-ignore
|
|
||||||
const codePlugins = metaPlugins.filter(pluginObj =>
|
|
||||||
['markdown', 'remark2rehype', 'rehypePrism', 'htmlStringify'].includes(pluginObj.name),
|
|
||||||
);
|
|
||||||
const codeParser = unified();
|
|
||||||
// @ts-ignore
|
|
||||||
for (const pluginObj of codePlugins) {
|
|
||||||
codeParser.use(pluginObj.plugin, pluginObj.options);
|
|
||||||
}
|
|
||||||
const codeResult = await codeParser.process(code);
|
|
||||||
return codeResult.contents;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
for (const pluginObj of metaPlugins) {
|
for (const pluginObj of metaPlugins) {
|
||||||
if (pluginObj.name === 'mdjsSetupCode') {
|
// @ts-ignore
|
||||||
if (pluginObj.options && !pluginObj.options.highlightCode) {
|
|
||||||
pluginObj.options.highlightCode = highlightCode;
|
|
||||||
}
|
|
||||||
if (!pluginObj.options) {
|
|
||||||
pluginObj.options = { highlightCode };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parser.use(pluginObj.plugin, pluginObj.options);
|
parser.use(pluginObj.plugin, pluginObj.options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,17 +77,32 @@ function mdjsStoryParse({
|
|||||||
const newValue = previewStoryTag(storyData.name);
|
const newValue = previewStoryTag(storyData.name);
|
||||||
if (newValue.includes('[[CODE SLOT]]')) {
|
if (newValue.includes('[[CODE SLOT]]')) {
|
||||||
const tagParts = newValue.split('[[CODE SLOT]]');
|
const tagParts = newValue.split('[[CODE SLOT]]');
|
||||||
|
|
||||||
|
const inside = [node];
|
||||||
|
let skipAmount = 1;
|
||||||
|
const next = parent.children[index + 1];
|
||||||
|
if (next && next.type === 'code' && next.meta === 'story-code') {
|
||||||
|
inside.push(next);
|
||||||
|
skipAmount += 1;
|
||||||
|
|
||||||
|
const next2 = parent.children[index + 2];
|
||||||
|
if (next2 && next2.type === 'code' && next2.meta === 'story-code') {
|
||||||
|
inside.push(next2);
|
||||||
|
skipAmount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
node = {
|
node = {
|
||||||
type: 'root',
|
type: 'root',
|
||||||
children: [
|
children: [
|
||||||
{ type: 'html', value: tagParts[0] },
|
{ type: 'html', value: tagParts[0] },
|
||||||
{ type: 'text', value: '\n\n' },
|
{ type: 'text', value: '\n\n' },
|
||||||
node,
|
...inside,
|
||||||
{ type: 'text', value: '\n\n' },
|
{ type: 'text', value: '\n\n' },
|
||||||
{ type: 'html', value: tagParts[1] },
|
{ type: 'html', value: tagParts[1] },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
parent.children.splice(index, 1, node);
|
parent.children.splice(index, skipAmount, node);
|
||||||
} else {
|
} else {
|
||||||
node.type = 'html';
|
node.type = 'html';
|
||||||
node.value = previewStoryTag(storyData.name);
|
node.value = previewStoryTag(storyData.name);
|
||||||
@@ -115,17 +130,31 @@ function mdjsStoryParse({
|
|||||||
const newValue = previewStoryTag(storyData.name);
|
const newValue = previewStoryTag(storyData.name);
|
||||||
if (newValue.includes('[[CODE SLOT]]')) {
|
if (newValue.includes('[[CODE SLOT]]')) {
|
||||||
const tagParts = newValue.split('[[CODE SLOT]]');
|
const tagParts = newValue.split('[[CODE SLOT]]');
|
||||||
|
const inside = [node];
|
||||||
|
let skipAmount = 1;
|
||||||
|
const next = parent.children[index + 1];
|
||||||
|
if (next && next.type === 'code' && next.meta === 'story-code') {
|
||||||
|
inside.push(next);
|
||||||
|
skipAmount += 1;
|
||||||
|
|
||||||
|
const next2 = parent.children[index + 2];
|
||||||
|
if (next2 && next2.type === 'code' && next2.meta === 'story-code') {
|
||||||
|
inside.push(next2);
|
||||||
|
skipAmount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
node = {
|
node = {
|
||||||
type: 'root',
|
type: 'root',
|
||||||
children: [
|
children: [
|
||||||
{ type: 'html', value: tagParts[0] },
|
{ type: 'html', value: tagParts[0] },
|
||||||
{ type: 'text', value: '\n\n' },
|
{ type: 'text', value: '\n\n' },
|
||||||
node,
|
...inside,
|
||||||
{ type: 'text', value: '\n\n' },
|
{ type: 'text', value: '\n\n' },
|
||||||
{ type: 'html', value: tagParts[1] },
|
{ type: 'html', value: tagParts[1] },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
parent.children.splice(index, 1, node);
|
parent.children.splice(index, skipAmount, node);
|
||||||
} else {
|
} else {
|
||||||
node.type = 'html';
|
node.type = 'html';
|
||||||
node.value = previewStoryTag(storyData.name);
|
node.value = previewStoryTag(storyData.name);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ describe('Integration', () => {
|
|||||||
})
|
})
|
||||||
.use(mdSlug)
|
.use(mdSlug)
|
||||||
.use(mdHeadings)
|
.use(mdHeadings)
|
||||||
.use(mdStringify);
|
.use(mdStringify, { sanitize: false });
|
||||||
const result = await parser.process(input);
|
const result = await parser.process(input);
|
||||||
expect(result.contents).to.equal(expected);
|
expect(result.contents).to.equal(expected);
|
||||||
expect(/** @type {MDJSVFileData} */ (result.data).stories).to.deep.equal([
|
expect(/** @type {MDJSVFileData} */ (result.data).stories).to.deep.equal([
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
const chai = require('chai');
|
const chai = require('chai');
|
||||||
const { adjustPluginOptions } = require('plugins-manager');
|
const { adjustPluginOptions } = require('plugins-manager');
|
||||||
const { mdjsProcess } = require('../src/mdjsProcess.js');
|
const { mdjsProcess } = require('../src/mdjsProcess.js');
|
||||||
|
const { mdjsSetupCode } = require('../src/mdjsSetupCode.js');
|
||||||
|
const { mdjsStoryParse } = require('../src/mdjsStoryParse.js');
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
@@ -33,7 +35,7 @@ describe('mdjsProcess', () => {
|
|||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
'<pre class="language-js"><code class="language-js"><span class="token keyword module">export</span> <span class="token keyword">const</span> <span class="token function-variable function">fooPreviewStory</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span>',
|
'<pre class="language-js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">fooPreviewStory</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span>',
|
||||||
'</code></pre>',
|
'</code></pre>',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
@@ -106,7 +108,7 @@ describe('mdjsProcess', () => {
|
|||||||
|
|
||||||
function replaceStoryTag(plugins) {
|
function replaceStoryTag(plugins) {
|
||||||
return plugins.map(pluginObj => {
|
return plugins.map(pluginObj => {
|
||||||
if (pluginObj.name === 'mdjsStoryParse') {
|
if (pluginObj.plugin === mdjsStoryParse) {
|
||||||
return {
|
return {
|
||||||
...pluginObj,
|
...pluginObj,
|
||||||
options: {
|
options: {
|
||||||
@@ -136,7 +138,7 @@ describe('mdjsProcess', () => {
|
|||||||
|
|
||||||
function replaceStoryTag2(plugins) {
|
function replaceStoryTag2(plugins) {
|
||||||
return plugins.map(pluginObj => {
|
return plugins.map(pluginObj => {
|
||||||
if (pluginObj.name === 'mdjsStoryParse') {
|
if (pluginObj.plugin === mdjsStoryParse) {
|
||||||
return {
|
return {
|
||||||
...pluginObj,
|
...pluginObj,
|
||||||
options: {
|
options: {
|
||||||
@@ -202,7 +204,7 @@ describe('mdjsProcess', () => {
|
|||||||
].join('\n');
|
].join('\n');
|
||||||
const result = await mdjsProcess(input, {
|
const result = await mdjsProcess(input, {
|
||||||
setupUnifiedPlugins: [
|
setupUnifiedPlugins: [
|
||||||
adjustPluginOptions('mdjsSetupCode', {
|
adjustPluginOptions(mdjsSetupCode, {
|
||||||
simulationSettings: { languages: [{ key: 'en', name: 'English' }] },
|
simulationSettings: { languages: [{ key: 'en', name: 'English' }] },
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -20,7 +20,25 @@ describe('mdjsParse', () => {
|
|||||||
'const bar = 22;',
|
'const bar = 22;',
|
||||||
'```',
|
'```',
|
||||||
].join('\n');
|
].join('\n');
|
||||||
const parser = unified().use(markdown).use(mdjsParse).use(html);
|
const parser = unified().use(markdown).use(mdjsParse).use(html, { sanitize: false });
|
||||||
|
const result = await parser.process(input);
|
||||||
|
expect(result.contents).to.equal(
|
||||||
|
'<h2>Intro</h2>\n<pre><code class="language-js">const foo = 1;\n</code></pre>\n',
|
||||||
|
);
|
||||||
|
expect(/** @type {MDJSVFileData} */ (result.data).jsCode).to.equal('const bar = 22;');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('extracts "js client" code blocks', async () => {
|
||||||
|
const input = [
|
||||||
|
'## Intro',
|
||||||
|
'```js',
|
||||||
|
'const foo = 1;',
|
||||||
|
'```',
|
||||||
|
'```js client',
|
||||||
|
'const bar = 22;',
|
||||||
|
'```',
|
||||||
|
].join('\n');
|
||||||
|
const parser = unified().use(markdown).use(mdjsParse).use(html, { sanitize: false });
|
||||||
const result = await parser.process(input);
|
const result = await parser.process(input);
|
||||||
expect(result.contents).to.equal(
|
expect(result.contents).to.equal(
|
||||||
'<h2>Intro</h2>\n<pre><code class="language-js">const foo = 1;\n</code></pre>\n',
|
'<h2>Intro</h2>\n<pre><code class="language-js">const foo = 1;\n</code></pre>\n',
|
||||||
@@ -36,7 +54,7 @@ describe('mdjsParse', () => {
|
|||||||
'const bar = 22;',
|
'const bar = 22;',
|
||||||
'```',
|
'```',
|
||||||
].join('\n');
|
].join('\n');
|
||||||
const parser = unified().use(markdown).use(mdjsParse).use(html);
|
const parser = unified().use(markdown).use(mdjsParse).use(html, { sanitize: false });
|
||||||
const result = await parser.process(input);
|
const result = await parser.process(input);
|
||||||
expect(result.contents).to.equal('');
|
expect(result.contents).to.equal('');
|
||||||
expect(/** @type {MDJSVFileData} */ (result.data).jsCode).to.equal('const bar = 22;');
|
expect(/** @type {MDJSVFileData} */ (result.data).jsCode).to.equal('const bar = 22;');
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ describe('mdjsStoryParse', () => {
|
|||||||
'',
|
'',
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
const parser = unified().use(markdown).use(mdjsStoryParse).use(html);
|
const parser = unified().use(markdown).use(mdjsStoryParse).use(html, { sanitize: false });
|
||||||
const result = await parser.process(input);
|
const result = await parser.process(input);
|
||||||
expect(result.contents).to.equal(expected);
|
expect(result.contents).to.equal(expected);
|
||||||
expect(/** @type {MDJSVFileData} */ (result.data).stories).to.deep.equal([
|
expect(/** @type {MDJSVFileData} */ (result.data).stories).to.deep.equal([
|
||||||
@@ -110,7 +110,139 @@ describe('mdjsStoryParse', () => {
|
|||||||
storyTag: name => `<Story name="${name}"></Story>`,
|
storyTag: name => `<Story name="${name}"></Story>`,
|
||||||
previewStoryTag: name => `<Preview><Story name="${name}"></Story></Preview>`,
|
previewStoryTag: name => `<Preview><Story name="${name}"></Story></Preview>`,
|
||||||
})
|
})
|
||||||
.use(html);
|
.use(html, { sanitize: false });
|
||||||
|
const result = await parser.process(input);
|
||||||
|
expect(result.contents).to.equal(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will wrap following story-code blocks', async () => {
|
||||||
|
const input = [
|
||||||
|
'```js preview-story',
|
||||||
|
'export const foo = () => {};',
|
||||||
|
'```',
|
||||||
|
'',
|
||||||
|
'```swift story-code',
|
||||||
|
'CODE for iOS',
|
||||||
|
'```',
|
||||||
|
'',
|
||||||
|
'```xml story-code',
|
||||||
|
'CODE for Android',
|
||||||
|
'```',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
'<mdjs-preview mdjs-story-name="foo">',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'<pre><code class="language-js">export const foo = () => {};',
|
||||||
|
'</code></pre>',
|
||||||
|
'<pre><code class="language-swift">CODE for iOS',
|
||||||
|
'</code></pre>',
|
||||||
|
'<pre><code class="language-xml">CODE for Android',
|
||||||
|
'</code></pre>',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'</mdjs-preview>',
|
||||||
|
'',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const parser = unified().use(markdown).use(mdjsStoryParse).use(html, { sanitize: false });
|
||||||
|
const result = await parser.process(input);
|
||||||
|
expect(result.contents).to.equal(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will wrap following story-code blocks also for html stories', async () => {
|
||||||
|
const input = [
|
||||||
|
'```html preview-story',
|
||||||
|
'<my-el></my-el>',
|
||||||
|
'```',
|
||||||
|
'',
|
||||||
|
'```swift story-code',
|
||||||
|
'CODE for iOS',
|
||||||
|
'```',
|
||||||
|
'',
|
||||||
|
'```xml story-code',
|
||||||
|
'CODE for Android',
|
||||||
|
'```',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
'<mdjs-preview mdjs-story-name="HtmlStory0">',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'<pre><code class="language-html"><my-el></my-el>',
|
||||||
|
'</code></pre>',
|
||||||
|
'<pre><code class="language-swift">CODE for iOS',
|
||||||
|
'</code></pre>',
|
||||||
|
'<pre><code class="language-xml">CODE for Android',
|
||||||
|
'</code></pre>',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'</mdjs-preview>',
|
||||||
|
'',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const parser = unified().use(markdown).use(mdjsStoryParse).use(html, { sanitize: false });
|
||||||
|
const result = await parser.process(input);
|
||||||
|
expect(result.contents).to.equal(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will wrap only following story-code blocks', async () => {
|
||||||
|
const input = [
|
||||||
|
'```js preview-story',
|
||||||
|
'export const foo = () => {};',
|
||||||
|
'```',
|
||||||
|
'```swift story-code',
|
||||||
|
'CODE for iOS',
|
||||||
|
'```',
|
||||||
|
'# hey',
|
||||||
|
'```swift story-code',
|
||||||
|
'SHOULD BE OUTSIDE',
|
||||||
|
'```',
|
||||||
|
'```js preview-story',
|
||||||
|
'export const foo2 = () => {};',
|
||||||
|
'```',
|
||||||
|
'```xml story-code',
|
||||||
|
'CODE for Android',
|
||||||
|
'```',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const expected = [
|
||||||
|
'<mdjs-preview mdjs-story-name="foo">',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'<pre><code class="language-js">export const foo = () => {};',
|
||||||
|
'</code></pre>',
|
||||||
|
'<pre><code class="language-swift">CODE for iOS',
|
||||||
|
'</code></pre>',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'</mdjs-preview>',
|
||||||
|
'<h1>hey</h1>',
|
||||||
|
'<pre><code class="language-swift">SHOULD BE OUTSIDE',
|
||||||
|
'</code></pre>',
|
||||||
|
'<mdjs-preview mdjs-story-name="foo2">',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'<pre><code class="language-js">export const foo2 = () => {};',
|
||||||
|
'</code></pre>',
|
||||||
|
'<pre><code class="language-xml">CODE for Android',
|
||||||
|
'</code></pre>',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'</mdjs-preview>',
|
||||||
|
'',
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
const parser = unified().use(markdown).use(mdjsStoryParse).use(html, { sanitize: false });
|
||||||
const result = await parser.process(input);
|
const result = await parser.process(input);
|
||||||
expect(result.contents).to.equal(expected);
|
expect(result.contents).to.equal(expected);
|
||||||
});
|
});
|
||||||
|
|||||||
2
packages/mdjs-core/types/code.d.ts
vendored
2
packages/mdjs-core/types/code.d.ts
vendored
@@ -31,4 +31,4 @@ export interface ParseResult {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MdjsProcessPlugin = MetaPlugin<unified.Plugin, unified.Settings>;
|
export type MdjsProcessPlugin = MetaPlugin<unified.Plugin>;
|
||||||
|
|||||||
6
packages/mdjs-core/types/remark.d.ts
vendored
6
packages/mdjs-core/types/remark.d.ts
vendored
@@ -28,12 +28,6 @@ declare module 'rehype-autolink-headings' {
|
|||||||
export = unified.Plugin;
|
export = unified.Plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'rehype-prism-template' {
|
|
||||||
import unified from 'unified';
|
|
||||||
|
|
||||||
export = unified.Plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'unist-util-remove' {
|
declare module 'unist-util-remove' {
|
||||||
import unified from 'unified';
|
import unified from 'unified';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,84 @@
|
|||||||
# @mdjs/mdjs-preview
|
# @mdjs/mdjs-preview
|
||||||
|
|
||||||
|
## 0.5.6
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- e81b77f: Change theme attribute into preview-theme attribute to separate theme styling of the preview section and the full mdjs viewer.
|
||||||
|
- 456b8e7: Add css variable to style border-color of the mdjs-viewer
|
||||||
|
|
||||||
|
## 0.5.5
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 445b028: Update to latest lit, @open-wc, @lion packages
|
||||||
|
|
||||||
|
## 0.5.4
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 15a82c0: Enable including script files into the simulator via `<script src=".." mdjs-use>`
|
||||||
|
- 15a82c0: Allow only a limited set of characters for simulator includes `[a-zA-Z0-9\/\-_]`.
|
||||||
|
Notably, there is no:
|
||||||
|
|
||||||
|
- `:` to prevent `http://...` includes
|
||||||
|
- `.` so filenames as `this.is.my.js` are not supported. Also includes will be without file endings which will be added automatically
|
||||||
|
|
||||||
|
## 0.5.3
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 5c6b9c9: The Platform and Size controls are now moved above the preview.
|
||||||
|
For the web platform we added a special "inline" size.
|
||||||
|
Only when platform=web & size=webInline it will render to dom.
|
||||||
|
On all other selections it will render the preview via an iframe.
|
||||||
|
|
||||||
|
```js
|
||||||
|
sizes: [
|
||||||
|
{
|
||||||
|
key: 'webInline',
|
||||||
|
name: 'Inline',
|
||||||
|
platform: 'web',
|
||||||
|
width: 360,
|
||||||
|
height: 640,
|
||||||
|
dpr: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
},
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
- 6221e5f: If your preview is followed by a code blocks marked as `story-code` then those will be shown when switching between multiple platforms
|
||||||
|
|
||||||
|
````md
|
||||||
|
```js preview-story
|
||||||
|
// will be visible when platform web is selected
|
||||||
|
export const JsPreviewStory = () =>
|
||||||
|
html`
|
||||||
|
<demo-wc-card>JS Preview Story</demo-wc-card>
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
```xml story-code
|
||||||
|
<!-- will be visible when platform android is selected -->
|
||||||
|
<Button
|
||||||
|
android:id="@+id/demoWcCard"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Android Code"
|
||||||
|
style="@style/Widget.FooComponents.Demo.Wc.Card"
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
```swift story-code
|
||||||
|
// will be visible when platform ios is selected
|
||||||
|
import DemoWc.Card
|
||||||
|
|
||||||
|
let card = DemoWcButton()
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
## 0.5.2
|
## 0.5.2
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# Preview element for mdjs
|
# Preview element for mdjs
|
||||||
|
|
||||||
For docs please see our homepage [https://rocket.modern-web.dev/docs/markdown-javascript/preview/](https://rocket.modern-web.dev/docs/markdown-javascript/preview/).
|
[=> See Source <=](../../docs/docs/markdown-javascript/preview.md)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mdjs/mdjs-preview",
|
"name": "@mdjs/mdjs-preview",
|
||||||
"version": "0.5.2",
|
"version": "0.5.6",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"debug": "cd ../../ && npm run debug -- --group mdjs-preview",
|
"debug": "cd ../../ && npm run debug -- --group mdjs-preview",
|
||||||
|
"prepublishOnly": "publish-docs --github-url https://github.com/modernweb-dev/rocket/ --git-root-dir ../../",
|
||||||
"test": "npm run test:web",
|
"test": "npm run test:web",
|
||||||
"test:web": "cd ../../ && npm run test:web -- --group mdjs-preview"
|
"test:web": "cd ../../ && npm run test:web -- --group mdjs-preview"
|
||||||
},
|
},
|
||||||
@@ -31,9 +32,9 @@
|
|||||||
"src"
|
"src"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lion/accordion": "^0.6.1",
|
"@lion/accordion": "^0.7.2",
|
||||||
"@open-wc/scoped-elements": "^2.0.0-next.3",
|
"@open-wc/scoped-elements": "^2.0.0",
|
||||||
"lit": "^2.0.0-rc.2"
|
"lit": "^2.0.0"
|
||||||
},
|
},
|
||||||
"types": "dist-types/index.d.ts"
|
"types": "dist-types/index.d.ts"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,16 @@ import {
|
|||||||
} from './mdjsViewerSharedStates.js';
|
} from './mdjsViewerSharedStates.js';
|
||||||
import { addResizeHandler } from './resizeHandler.js';
|
import { addResizeHandler } from './resizeHandler.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {'js'|'css'} type
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function sanitize(input, type) {
|
||||||
|
const url = new URL(input);
|
||||||
|
return url.pathname.slice(1, (type.length + 1) * -1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {object} StoryOptions
|
* @typedef {object} StoryOptions
|
||||||
* @property {HTMLElement | null} StoryOptions.shadowRoot
|
* @property {HTMLElement | null} StoryOptions.shadowRoot
|
||||||
@@ -47,11 +57,11 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
contentHeight: { type: Number },
|
contentHeight: { type: Number },
|
||||||
simulatorUrl: { type: String },
|
simulatorUrl: { type: String },
|
||||||
// page settings
|
// page settings
|
||||||
platform: { type: String },
|
platform: { type: String, reflect: true },
|
||||||
platforms: { type: Array },
|
platforms: { type: Array },
|
||||||
size: { type: String },
|
size: { type: String },
|
||||||
sizes: { type: Array },
|
sizes: { type: Array },
|
||||||
theme: { type: String, reflect: true },
|
previewTheme: { type: String, reflect: true, attribute: 'preview-theme' },
|
||||||
themes: { type: Array },
|
themes: { type: Array },
|
||||||
language: { type: String },
|
language: { type: String },
|
||||||
languages: { type: Array },
|
languages: { type: Array },
|
||||||
@@ -72,7 +82,7 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
this.__supportsClipboard = 'clipboard' in navigator;
|
this.__supportsClipboard = 'clipboard' in navigator;
|
||||||
this.__copyButtonText = 'Copy Code';
|
this.__copyButtonText = 'Copy Code';
|
||||||
|
|
||||||
this.theme = 'light';
|
this.previewTheme = 'light';
|
||||||
/** @type {{ key: string, name: string }[]} */
|
/** @type {{ key: string, name: string }[]} */
|
||||||
this.themes = [
|
this.themes = [
|
||||||
// { key: 'light', name: 'Light' },
|
// { key: 'light', name: 'Light' },
|
||||||
@@ -107,8 +117,16 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
// { key: 'ios', name: 'iOS' },
|
// { key: 'ios', name: 'iOS' },
|
||||||
];
|
];
|
||||||
|
|
||||||
this.size = 'webSmall';
|
this.size = 'webInline';
|
||||||
this.sizes = [
|
this.sizes = [
|
||||||
|
{
|
||||||
|
key: 'webInline',
|
||||||
|
name: 'Inline',
|
||||||
|
platform: 'web',
|
||||||
|
width: 360,
|
||||||
|
height: 640,
|
||||||
|
dpr: 1,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'webSmall',
|
key: 'webSmall',
|
||||||
name: 'Small',
|
name: 'Small',
|
||||||
@@ -241,6 +259,10 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
if (this.lightDomRenderTarget && changeProps.has('story')) {
|
if (this.lightDomRenderTarget && changeProps.has('story')) {
|
||||||
render(this.story({ shadowRoot: this }), this.lightDomRenderTarget);
|
render(this.story({ shadowRoot: this }), this.lightDomRenderTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changeProps.has('platform') || changeProps.has('size')) {
|
||||||
|
this.deviceMode = this.platform === 'web' && this.size === 'webInline' ? false : true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
@@ -261,11 +283,10 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
if (!mdjsSetupScript) {
|
if (!mdjsSetupScript) {
|
||||||
throw new Error('Could not find a <script type="module" src="..." mdjs-setup></script>');
|
throw new Error('Could not find a <script type="module" src="..." mdjs-setup></script>');
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.set('story-file', mdjsSetupScript.src);
|
params.set('story-file', sanitize(mdjsSetupScript.src, 'js'));
|
||||||
params.set('story-key', this.key);
|
params.set('story-key', this.key);
|
||||||
params.set('theme', this.theme);
|
params.set('theme', this.previewTheme);
|
||||||
params.set('platform', this.platform);
|
params.set('platform', this.platform);
|
||||||
params.set('language', this.language);
|
params.set('language', this.language);
|
||||||
params.set('edge-distance', this.edgeDistance.toString());
|
params.set('edge-distance', this.edgeDistance.toString());
|
||||||
@@ -275,7 +296,16 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
]);
|
]);
|
||||||
for (const link of links) {
|
for (const link of links) {
|
||||||
if (link.href) {
|
if (link.href) {
|
||||||
params.append('stylesheets', link.href);
|
params.append('stylesheets', sanitize(link.href, 'css'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleUrls = /** @type {HTMLScriptElement[]} */ ([
|
||||||
|
...document.querySelectorAll('script[type=module][mdjs-use]'),
|
||||||
|
]);
|
||||||
|
for (const moduleUrl of moduleUrls) {
|
||||||
|
if (moduleUrl.src) {
|
||||||
|
params.append('moduleUrls', sanitize(moduleUrl.src, 'js'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,8 +322,15 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async onCopy() {
|
async onCopy() {
|
||||||
if (this.textContent) {
|
let nodeToConsider = this.children[0];
|
||||||
await navigator.clipboard.writeText(this.textContent.trim());
|
if (this.platform === 'android') {
|
||||||
|
nodeToConsider = this.children[1];
|
||||||
|
}
|
||||||
|
if (this.platform === 'ios') {
|
||||||
|
nodeToConsider = this.children[2];
|
||||||
|
}
|
||||||
|
if (nodeToConsider && nodeToConsider.textContent) {
|
||||||
|
await navigator.clipboard.writeText(nodeToConsider.textContent.trim());
|
||||||
this.__copyButtonText = 'Copied ✅';
|
this.__copyButtonText = 'Copied ✅';
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.__copyButtonText = 'Copy code';
|
this.__copyButtonText = 'Copy code';
|
||||||
@@ -304,7 +341,6 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
renderPlatforms() {
|
renderPlatforms() {
|
||||||
if (this.platforms.length) {
|
if (this.platforms.length) {
|
||||||
return html`
|
return html`
|
||||||
<h4>Platform</h4>
|
|
||||||
<div
|
<div
|
||||||
class="segmented-control"
|
class="segmented-control"
|
||||||
@change=${
|
@change=${
|
||||||
@@ -337,17 +373,27 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
if (this.platforms.length) {
|
if (this.platforms.length) {
|
||||||
return html`
|
return html`
|
||||||
<div>
|
<div>
|
||||||
<h3>Platform</h3>
|
<h4>Platform</h4>
|
||||||
${this.renderPlatforms()}
|
${this.renderPlatforms()}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderSize() {
|
||||||
|
if (this.sizes.length) {
|
||||||
|
return html`
|
||||||
|
<div>
|
||||||
|
<h4>Size</h4>
|
||||||
|
${this.renderSizes()}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderSizes() {
|
renderSizes() {
|
||||||
if (this.sizes.length) {
|
if (this.sizes.length) {
|
||||||
return html`
|
return html`
|
||||||
<h4>Size</h4>
|
|
||||||
<div
|
<div
|
||||||
class="segmented-control"
|
class="segmented-control"
|
||||||
@change=${
|
@change=${
|
||||||
@@ -380,7 +426,7 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
return html`
|
return html`
|
||||||
<div>
|
<div>
|
||||||
<h3>Viewport</h3>
|
<h3>Viewport</h3>
|
||||||
${this.renderSizes()} ${this.renderAutoHeight()}
|
${this.renderAutoHeight()}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -393,20 +439,20 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
@change=${
|
@change=${
|
||||||
/** @param {Event} ev */ ev => {
|
/** @param {Event} ev */ ev => {
|
||||||
if (ev.target) {
|
if (ev.target) {
|
||||||
this.theme = /** @type {HTMLInputElement} */ (ev.target).value;
|
this.previewTheme = /** @type {HTMLInputElement} */ (ev.target).value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
${this.themes.map(
|
${this.themes.map(
|
||||||
theme => html`
|
previewTheme => html`
|
||||||
<label class="${this.theme === theme.key ? 'selected' : ''}">
|
<label class="${this.previewTheme === previewTheme.key ? 'selected' : ''}">
|
||||||
<span>${theme.name}</span>
|
<span>${previewTheme.name}</span>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="theme"
|
name="theme"
|
||||||
value="${theme.key}"
|
value="${previewTheme.key}"
|
||||||
?checked=${this.theme === theme.key}
|
?checked=${this.previewTheme === previewTheme.key}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
`,
|
`,
|
||||||
@@ -564,6 +610,11 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
|
${this.simulatorUrl
|
||||||
|
? html`
|
||||||
|
<div class="platform-size-controls">${this.renderPlatform()} ${this.renderSize()}</div>
|
||||||
|
`
|
||||||
|
: ``}
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<slot name="story"></slot>
|
<slot name="story"></slot>
|
||||||
${this.deviceMode === true
|
${this.deviceMode === true
|
||||||
@@ -581,19 +632,28 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
: nothing}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
<lion-accordion class="options">
|
<lion-accordion class="options">
|
||||||
${this.deviceMode
|
${this.simulatorUrl
|
||||||
? html`
|
? html`
|
||||||
<h3 slot="invoker">
|
<h3 slot="invoker">
|
||||||
<button>Settings</button>
|
<button>Settings</button>
|
||||||
</h3>
|
</h3>
|
||||||
<div slot="content">
|
<div slot="content">
|
||||||
|
${this.deviceMode
|
||||||
|
? ``
|
||||||
|
: html`<div>
|
||||||
|
Note: Additional settings become available when not in web inline mode
|
||||||
|
</div>`}
|
||||||
<div class="settings-wrapper">
|
<div class="settings-wrapper">
|
||||||
${this.renderPlatform()} ${this.renderViewport()} ${this.renderVisual()}
|
${this.deviceMode
|
||||||
${this.renderLocalization()} ${this.renderSyncSettings()}
|
? html`
|
||||||
|
${this.renderViewport()} ${this.renderVisual()} ${this.renderLocalization()}
|
||||||
|
${this.renderSyncSettings()}
|
||||||
|
`
|
||||||
|
: html` ${this.renderSyncSettings()} `}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ''}
|
: ``}
|
||||||
<h3 slot="invoker">
|
<h3 slot="invoker">
|
||||||
<button>Code</button>
|
<button>Code</button>
|
||||||
</h3>
|
</h3>
|
||||||
@@ -608,12 +668,6 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
? html`
|
? html`
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<a href=${this.iframeUrl} target="_blank">Open simulation in new window</a>
|
<a href=${this.iframeUrl} target="_blank">Open simulation in new window</a>
|
||||||
<button
|
|
||||||
@click=${() => (this.deviceMode = !this.deviceMode)}
|
|
||||||
class="simulation-toggle"
|
|
||||||
>
|
|
||||||
${this.deviceMode ? html`Disable` : html`Enable`} device simulation
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ''}
|
: ''}
|
||||||
@@ -631,8 +685,12 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host(:not([device-mode])) #wrapper {
|
||||||
|
border: 2px solid var(--primary-lines-color, #4caf50);
|
||||||
|
}
|
||||||
|
|
||||||
iframe {
|
iframe {
|
||||||
border: 2px solid #4caf50;
|
border: 2px solid var(--primary-lines-color, #4caf50);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,6 +783,15 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.platform-size-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.platform-size-controls > * {
|
||||||
|
margin-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
.controls {
|
.controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -845,6 +912,21 @@ export class MdJsPreview extends ScopedElementsMixin(LitElement) {
|
|||||||
border: 1px solid #333;
|
border: 1px solid #333;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Showing/Hiding additional code blocks **/
|
||||||
|
::slotted(pre) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host([platform='web']) ::slotted(pre:nth-child(1)) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
:host([platform='android']) ::slotted(pre:nth-child(2)) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
:host([platform='ios']) ::slotted(pre:nth-child(3)) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const _sharedStates = {
|
const _sharedStates = {
|
||||||
platform: 'web',
|
platform: 'web',
|
||||||
size: 'webSmall',
|
size: 'webSmall',
|
||||||
theme: 'light',
|
previewTheme: 'light',
|
||||||
language: 'en',
|
language: 'en',
|
||||||
autoHeight: true,
|
autoHeight: true,
|
||||||
deviceMode: false,
|
deviceMode: false,
|
||||||
|
|||||||
@@ -28,11 +28,8 @@ describe('mdjs-preview', () => {
|
|||||||
expect(preview1.edgeDistance).to.be.true;
|
expect(preview1.edgeDistance).to.be.true;
|
||||||
expect(preview2.edgeDistance).to.be.true;
|
expect(preview2.edgeDistance).to.be.true;
|
||||||
|
|
||||||
preview1.platform = 'android';
|
|
||||||
preview1.edgeDistance = false;
|
preview1.edgeDistance = false;
|
||||||
await preview1.updateComplete;
|
await preview1.updateComplete;
|
||||||
expect(preview1.platform).to.equal('android');
|
|
||||||
expect(preview2.platform).to.equal('android');
|
|
||||||
expect(preview1.edgeDistance).to.be.false;
|
expect(preview1.edgeDistance).to.be.false;
|
||||||
expect(preview2.edgeDistance).to.be.false;
|
expect(preview2.edgeDistance).to.be.false;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# @mdjs/mdjs-story
|
# @mdjs/mdjs-story
|
||||||
|
|
||||||
|
## 0.3.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 445b028: Update to latest lit, @open-wc, @lion packages
|
||||||
|
|
||||||
## 0.3.0
|
## 0.3.0
|
||||||
|
|
||||||
### Minor Changes
|
### Minor Changes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mdjs/mdjs-story",
|
"name": "@mdjs/mdjs-story",
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"src"
|
"src"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lit": "^2.0.0-rc.2"
|
"lit": "^2.0.0"
|
||||||
},
|
},
|
||||||
"types": "dist-types/index.d.ts"
|
"types": "dist-types/index.d.ts"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,98 @@
|
|||||||
# plugins-manager
|
# plugins-manager
|
||||||
|
|
||||||
|
## 0.3.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- 7e277cd: Add a "hidden" feature in addPlugin that if you attach a `wrapPlugin` property to the returning function it will call `wrapPlugin` on the plugin before adding it.
|
||||||
|
|
||||||
|
## 0.3.0
|
||||||
|
|
||||||
|
### Minor Changes
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: `addPlugin` API changed
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- addPlugin({ name: 'my-plugin', plugin: myPlugin, options: { myFlag: true }, location: 'top' });
|
||||||
|
+ addPlugin(myPlugin, { myFlag: true }, { location: 'top' });
|
||||||
|
```
|
||||||
|
|
||||||
|
This is now type safe and typescript will throw an error if you pass the wrong type.
|
||||||
|
|
||||||
|
```js
|
||||||
|
function myPlugin({ myFlag = false } = {}) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
addPlugin(myPlugin, { myFlag: true }); // ts ok
|
||||||
|
addPlugin(myPlugin, { notExisting: true }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: `adjustPluginOptions` API changed
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- adjustPluginOptions('my-plugin', { myFlag: true });
|
||||||
|
+ adjustPluginOptions(myPlugin, { myFlag: true });
|
||||||
|
```
|
||||||
|
|
||||||
|
This is now type safe and typescript will throw an error if you pass the wrong type.
|
||||||
|
|
||||||
|
```js
|
||||||
|
function myPlugin({ myFlag = false } = {}) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustPluginOptions(myPlugin, { myFlag: true }); // ts ok
|
||||||
|
adjustPluginOptions(myPlugin, { notExisting: true }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
|
- 70bb7a1: Add `removePlugin` functionality
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default {
|
||||||
|
setupPlugins: [removePlugin(json)],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: `metaConfigToRollupConfig` has been renamed to `applyPlugins`
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- const finalConfig = metaConfigToRollupConfig(currentConfig, defaultMetaPlugins);
|
||||||
|
+ const finalConfig = applyPlugins(currentConfig, defaultMetaPlugins);
|
||||||
|
```
|
||||||
|
|
||||||
|
- 70bb7a1: BREAKING CHANGE: `metaConfigToWebDevServerConfig` has been removed
|
||||||
|
- 70bb7a1: Plugins can now be classes as well. The options are passed to the constructor.
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
* @typedef {object} MyClassOptions
|
||||||
|
* @property {string} lastName
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MyClass {
|
||||||
|
/** @type {MyClassOptions} */
|
||||||
|
options = {
|
||||||
|
lastName: 'initial-second',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Partial<MyClassOptions>} options
|
||||||
|
*/
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.options = { ...this.options, ...options };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setupPlugins: [addPlugin(MyClass)],
|
||||||
|
};
|
||||||
|
|
||||||
|
// constructor parameters are type safe
|
||||||
|
addPlugin(MyClass, { lastName: 'new name' }); // ts ok
|
||||||
|
addPlugin(MyClass, { otherProp: 'new name' }); // ts error
|
||||||
|
```
|
||||||
|
|
||||||
## 0.2.4
|
## 0.2.4
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
# Plugins Manager
|
# Plugins Manager
|
||||||
|
|
||||||
The Plugins Manager replaces the specific registration/execution (with options) in a given plugin system by an intent to use a plugin (with these options).
|
[=> See Source <=](../../docs/docs/tools/plugins-manager.md)
|
||||||
This allows your users to adjust the options before actually applying the plugins.
|
|
||||||
|
|
||||||
For docs please see our homepage [https://rocket.modern-web.dev/docs/plugins-manager/overview/](https://rocket.modern-web.dev/docs/plugins-manager/overview/).
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
/** @typedef {import('./types/main').MetaPlugin} MetaPlugin */
|
/**
|
||||||
/** @typedef {import('./types/main').AddPluginFn} AddPluginFn */
|
* @template T
|
||||||
/** @typedef {import('./types/main').AddPluginType} AddPluginType */
|
* @typedef {import('./types/main').MetaPlugin<T>} MetaPlugin
|
||||||
|
**/
|
||||||
|
/** @typedef {import('./types/main').Plugin} Plugin */
|
||||||
|
|
||||||
export { addPlugin } from './src/addPlugin.js';
|
export { addPlugin } from './src/addPlugin.js';
|
||||||
|
export { removePlugin } from './src/removePlugin.js';
|
||||||
export { adjustPluginOptions } from './src/adjustPluginOptions.js';
|
export { adjustPluginOptions } from './src/adjustPluginOptions.js';
|
||||||
export { metaConfigToRollupConfig } from './src/metaConfigToRollupConfig.js';
|
export { applyPlugins } from './src/applyPlugins.js';
|
||||||
export { metaConfigToWebDevServerConfig } from './src/metaConfigToWebDevServerConfig.js';
|
|
||||||
export { executeSetupFunctions } from './src/executeSetupFunctions.js';
|
export { executeSetupFunctions } from './src/executeSetupFunctions.js';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "plugins-manager",
|
"name": "plugins-manager",
|
||||||
"version": "0.2.4",
|
"version": "0.3.1",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:package": "rimraf dist && esbuild --platform=node --format=cjs --bundle --outfile=dist/index.cjs ./index.js",
|
"build:package": "rimraf dist && esbuild --platform=node --format=cjs --bundle --outfile=dist/index.cjs ./index.js",
|
||||||
|
"prepublishOnly": "publish-docs --github-url https://github.com/modernweb-dev/rocket/ --git-root-dir ../../",
|
||||||
"test": "mocha --timeout 5000 test-node/**/*.test.{js,cjs} test-node/*.test.{js,cjs}",
|
"test": "mocha --timeout 5000 test-node/**/*.test.{js,cjs} test-node/*.test.{js,cjs}",
|
||||||
"test:watch": "onchange 'src/**/*.{js,cjs}' 'test-node/**/*.{js,cjs}' -- npm test",
|
"test:watch": "onchange 'src/**/*.{js,cjs}' 'test-node/**/*.{js,cjs}' -- npm test",
|
||||||
"types:copy": "copyfiles \"./types/**/*.d.ts\" dist-types/"
|
"types:copy": "copyfiles \"./types/**/*.d.ts\" dist-types/"
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
/** @typedef {import('../types/main').MetaPlugin} MetaPlugin */
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @template {Function} T
|
* @template {import('../types/main').Plugin} T
|
||||||
* @param {import('../types/main').AddPluginOptions<T>} metaPluginAndOptions
|
* @param {T} plugin
|
||||||
|
* @param {import('../types/main').GetPluginOptions<T>} [options]
|
||||||
|
* @param {import('../types/main').ManagerOptions} [managerOptions]
|
||||||
*/
|
*/
|
||||||
export function addPlugin(metaPluginAndOptions) {
|
export function addPlugin(plugin, options = {}, { how = 'after', location = 'bottom' } = {}) {
|
||||||
const {
|
|
||||||
name,
|
|
||||||
plugin,
|
|
||||||
options = undefined,
|
|
||||||
how = 'after',
|
|
||||||
location = 'bottom',
|
|
||||||
} = metaPluginAndOptions;
|
|
||||||
/**
|
/**
|
||||||
* @param {MetaPlugin[]} plugins
|
* @param {import('../types/main').MetaPlugin<T>[]} plugins
|
||||||
*/
|
*/
|
||||||
const addPluginFn = plugins => {
|
const addPluginFn = plugins => {
|
||||||
if (plugins === undefined) {
|
if (plugins === undefined) {
|
||||||
plugins = [];
|
plugins = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const usePlugin = addPluginFn.wrapPlugin ? addPluginFn.wrapPlugin(plugin) : plugin;
|
||||||
|
|
||||||
// only add if name is not already in the meta plugin list
|
// only add if name is not already in the meta plugin list
|
||||||
if (plugins.findIndex(pluginObj => pluginObj.name === name) === -1) {
|
if (plugins.findIndex(pluginObj => pluginObj.plugin === plugin) === -1) {
|
||||||
let index = -1;
|
let index = -1;
|
||||||
let _how = how;
|
let _how = how;
|
||||||
switch (location) {
|
switch (location) {
|
||||||
@@ -33,11 +31,12 @@ export function addPlugin(metaPluginAndOptions) {
|
|||||||
_how = 'fixed';
|
_how = 'fixed';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
index = plugins.findIndex(plugin => plugin.name === location);
|
index = plugins.findIndex(pluginObj => pluginObj.plugin === location);
|
||||||
}
|
}
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
|
const errorName = location === 'top' || location === 'bottom' ? location : location.name;
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Could not find a plugin with the name "${location}" to insert "${name}" ${how} it.`,
|
`Could not find a plugin with the name "${errorName}" to insert "${plugin.name}" ${how} it.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,8 +45,7 @@ export function addPlugin(metaPluginAndOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins.splice(index, 0, {
|
plugins.splice(index, 0, {
|
||||||
name,
|
plugin: usePlugin,
|
||||||
plugin,
|
|
||||||
options,
|
options,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/** @typedef {import('../types/main').MetaPlugin} MetaPlugin */
|
/** @typedef {import('../types/main').Plugin} Plugin */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {any} obj
|
* @param {any} obj
|
||||||
@@ -8,23 +8,35 @@ function isObject(obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} pluginName
|
* @param {*} x
|
||||||
* @param {any} mergeOptions
|
* @returns {x is function}
|
||||||
*/
|
*/
|
||||||
export function adjustPluginOptions(pluginName, mergeOptions) {
|
function isFunction(x) {
|
||||||
|
return typeof x === 'function';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {import('../types/main').Plugin} T
|
||||||
|
* @param {T} plugin
|
||||||
|
* @param {import('../types/main').adjustPluginOptionsOptions<T>} mergeOptions
|
||||||
|
*/
|
||||||
|
export function adjustPluginOptions(plugin, mergeOptions) {
|
||||||
/**
|
/**
|
||||||
* @param {MetaPlugin[]} plugins
|
* @template {Function} T
|
||||||
|
* @param {import('../types/main').MetaPlugin<T>[]} plugins
|
||||||
*/
|
*/
|
||||||
const adjustPluginOptionsFn = plugins => {
|
const adjustPluginOptionsFn = plugins => {
|
||||||
const index = plugins.findIndex(plugin => plugin.name === pluginName);
|
const index = plugins.findIndex(pluginObj => pluginObj.plugin === plugin);
|
||||||
|
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Could not find a plugin with the name "${pluginName}" to adjust the options.`,
|
`Could not find a plugin with the name "${
|
||||||
|
plugin.name
|
||||||
|
}" to adjust it's options with:\n${JSON.stringify(mergeOptions, null, 2)}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof mergeOptions === 'function') {
|
if (isFunction(mergeOptions)) {
|
||||||
plugins[index].options = mergeOptions(plugins[index].options);
|
plugins[index].options = mergeOptions(plugins[index].options);
|
||||||
} else if (isObject(plugins[index].options)) {
|
} else if (isObject(plugins[index].options)) {
|
||||||
plugins[index].options = { ...plugins[index].options, ...mergeOptions };
|
plugins[index].options = { ...plugins[index].options, ...mergeOptions };
|
||||||
|
|||||||
46
packages/plugins-manager/src/applyPlugins.js
Normal file
46
packages/plugins-manager/src/applyPlugins.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { executeSetupFunctions } from './executeSetupFunctions.js';
|
||||||
|
|
||||||
|
/** @typedef {import('../types/main').Constructor} Constructor */
|
||||||
|
/** @typedef {import('../types/main').AnyFn} AnyFn */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {unknown} func
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isClass(func) {
|
||||||
|
if (typeof func === 'function' && func.prototype) {
|
||||||
|
try {
|
||||||
|
func.arguments && func.caller;
|
||||||
|
} catch (error) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {import('../types/main').Plugin} T
|
||||||
|
* @param {any} config
|
||||||
|
* @param {import('../types/main').MetaPlugin<T>[]} [defaultPlugins]
|
||||||
|
*/
|
||||||
|
export function applyPlugins(config, defaultPlugins = []) {
|
||||||
|
if (config.plugins) {
|
||||||
|
delete config.setupPlugins;
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
const _metaPlugins = executeSetupFunctions(config.setupPlugins, [...defaultPlugins]);
|
||||||
|
|
||||||
|
const plugins = _metaPlugins.map(pluginObj => {
|
||||||
|
if (isClass(pluginObj.plugin)) {
|
||||||
|
const ClassPlugin = /** @type {Constructor} */ (pluginObj.plugin);
|
||||||
|
return pluginObj.options ? new ClassPlugin(pluginObj.options) : new ClassPlugin();
|
||||||
|
} else {
|
||||||
|
const fnPlugin = /** @type {AnyFn} */ (pluginObj.plugin);
|
||||||
|
return pluginObj.options ? fnPlugin(pluginObj.options) : fnPlugin();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
config.plugins = plugins;
|
||||||
|
|
||||||
|
delete config.setupPlugins;
|
||||||
|
return config;
|
||||||
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
/** @typedef {import('../types/main').MetaPlugin} MetaPlugin */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @template T
|
||||||
* @param {function[]} setupFunctions
|
* @param {function[]} setupFunctions
|
||||||
* @param {MetaPlugin[]} metaPlugins
|
* @param {import('../types/main').MetaPlugin<T>[]} metaPlugins
|
||||||
* @return {MetaPlugin[]}
|
* @return {import('../types/main').MetaPlugin<T>[]}
|
||||||
*/
|
*/
|
||||||
export function executeSetupFunctions(setupFunctions, metaPlugins = []) {
|
export function executeSetupFunctions(setupFunctions, metaPlugins = []) {
|
||||||
let _metaPlugins = [...metaPlugins];
|
let _metaPlugins = [...metaPlugins];
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
/** @typedef {import('../types/main').MetaPlugin} MetaPlugin */
|
|
||||||
|
|
||||||
import { executeSetupFunctions } from 'plugins-manager';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {any} config
|
|
||||||
* @param {MetaPlugin[]} [metaPlugins]
|
|
||||||
*/
|
|
||||||
export function metaConfigToRollupConfig(config, metaPlugins = []) {
|
|
||||||
if (config.plugins) {
|
|
||||||
delete config.setupPlugins;
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
const _metaPlugins = executeSetupFunctions(config.setupPlugins, [...metaPlugins]);
|
|
||||||
|
|
||||||
const plugins = _metaPlugins.map(pluginObj => {
|
|
||||||
if (pluginObj.options) {
|
|
||||||
return pluginObj.plugin(pluginObj.options);
|
|
||||||
} else {
|
|
||||||
return pluginObj.plugin();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
config.plugins = plugins;
|
|
||||||
|
|
||||||
delete config.setupPlugins;
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/** @typedef {import('../types/main').MetaPluginWrapable} MetaPluginWrapable */
|
|
||||||
|
|
||||||
import { executeSetupFunctions } from 'plugins-manager';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {any} config
|
|
||||||
* @param {MetaPluginWrapable[]} metaPlugins
|
|
||||||
* @param {object} [options]
|
|
||||||
* @param {function | null} [options.rollupWrapperFunction]
|
|
||||||
*/
|
|
||||||
export function metaConfigToWebDevServerConfig(
|
|
||||||
config,
|
|
||||||
metaPlugins,
|
|
||||||
{ rollupWrapperFunction = null } = {},
|
|
||||||
) {
|
|
||||||
if (config.plugins) {
|
|
||||||
delete config.setupPlugins;
|
|
||||||
delete config.setupRollupPlugins;
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
const metaPluginsNoWrap = metaPlugins.map(pluginObj => {
|
|
||||||
pluginObj.__noWrap = true;
|
|
||||||
return pluginObj;
|
|
||||||
});
|
|
||||||
|
|
||||||
const rollupPlugins = /** @type {MetaPluginWrapable[]} */ (executeSetupFunctions(
|
|
||||||
config.setupRollupPlugins,
|
|
||||||
[...metaPluginsNoWrap],
|
|
||||||
));
|
|
||||||
|
|
||||||
const wrappedRollupPlugins = rollupPlugins.map(pluginObj => {
|
|
||||||
if (typeof rollupWrapperFunction === 'function' && pluginObj.__noWrap !== true) {
|
|
||||||
pluginObj.plugin = rollupWrapperFunction(pluginObj.plugin);
|
|
||||||
}
|
|
||||||
return pluginObj;
|
|
||||||
});
|
|
||||||
|
|
||||||
const _metaPlugins = executeSetupFunctions(config.setupPlugins, [...wrappedRollupPlugins]);
|
|
||||||
|
|
||||||
const plugins = _metaPlugins.map(pluginObj => {
|
|
||||||
if (pluginObj.options) {
|
|
||||||
return pluginObj.plugin(pluginObj.options);
|
|
||||||
} else {
|
|
||||||
return pluginObj.plugin();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
config.plugins = plugins;
|
|
||||||
|
|
||||||
delete config.setupPlugins;
|
|
||||||
delete config.setupRollupPlugins;
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
23
packages/plugins-manager/src/removePlugin.js
Normal file
23
packages/plugins-manager/src/removePlugin.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/** @typedef {import('../types/main').Plugin} Plugin */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('../types/main').Plugin} plugin
|
||||||
|
*/
|
||||||
|
export function removePlugin(plugin) {
|
||||||
|
/**
|
||||||
|
* @template {Function} T
|
||||||
|
* @param {import('../types/main').MetaPlugin<T>[]} plugins
|
||||||
|
*/
|
||||||
|
const removePluginFn = plugins => {
|
||||||
|
const index = plugins.findIndex(pluginObj => pluginObj.plugin === plugin);
|
||||||
|
|
||||||
|
if (index === -1) {
|
||||||
|
throw new Error(`Could not find a plugin with the name "${plugin.name}" to remove.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins.splice(index, 1);
|
||||||
|
|
||||||
|
return plugins;
|
||||||
|
};
|
||||||
|
return removePluginFn;
|
||||||
|
}
|
||||||
@@ -1,82 +1,93 @@
|
|||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
|
|
||||||
import { addPlugin, metaConfigToRollupConfig } from 'plugins-manager';
|
import { addPlugin, applyPlugins } from '../index.js';
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('addPlugin', () => {
|
describe('addPlugin', () => {
|
||||||
const insertPlugin = (options = 'insert') => `-- ${options}Plugin --`;
|
const insertPlugin = ({ firstName = 'first', lastName = 'last' } = {}) =>
|
||||||
const oneExistingPlugin = [{ name: 'first', plugin: () => 'firstPlugin' }];
|
`-- ${firstName} ${lastName} Plugin --`;
|
||||||
|
const firstPlugin = () => 'firstPlugin';
|
||||||
|
const secondPlugin = () => 'secondPlugin';
|
||||||
|
const thirdPlugin = () => 'thirdPlugin';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @type {import('../types/main.js').MetaPlugin<T>[]}
|
||||||
|
*/
|
||||||
|
const oneExistingPlugin = [{ plugin: firstPlugin, options: {} }];
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @type {import('../types/main.js').MetaPlugin<T>[]}
|
||||||
|
*/
|
||||||
const threeExistingPlugins = [
|
const threeExistingPlugins = [
|
||||||
{ name: 'first', plugin: () => 'firstPlugin' },
|
{ plugin: firstPlugin, options: {} },
|
||||||
{ name: 'second', plugin: () => 'secondPlugin' },
|
{ plugin: secondPlugin, options: {} },
|
||||||
{ name: 'third', plugin: () => 'thirdPlugin' },
|
{ plugin: thirdPlugin, options: {} },
|
||||||
];
|
];
|
||||||
|
|
||||||
it('adds plugins at the bottom by default', async () => {
|
it('adds plugins at the bottom by default', async () => {
|
||||||
const config = metaConfigToRollupConfig({
|
const config = applyPlugins({
|
||||||
setupPlugins: [addPlugin({ name: 'insert', plugin: insertPlugin })],
|
setupPlugins: [addPlugin(insertPlugin)],
|
||||||
});
|
});
|
||||||
expect(config.plugins).to.deep.equal(['-- insertPlugin --']);
|
expect(config.plugins).to.deep.equal(['-- first last Plugin --']);
|
||||||
|
|
||||||
const config2 = metaConfigToRollupConfig(
|
const config2 = applyPlugins(
|
||||||
{
|
{
|
||||||
setupPlugins: [addPlugin({ name: 'insert', plugin: insertPlugin })],
|
setupPlugins: [addPlugin(insertPlugin)],
|
||||||
},
|
},
|
||||||
oneExistingPlugin,
|
oneExistingPlugin,
|
||||||
);
|
);
|
||||||
expect(config2.plugins).to.deep.equal(['firstPlugin', '-- insertPlugin --']);
|
expect(config2.plugins).to.deep.equal(['firstPlugin', '-- first last Plugin --']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can add at the top', async () => {
|
it('can add at the top', async () => {
|
||||||
const config = metaConfigToRollupConfig(
|
const config = applyPlugins(
|
||||||
{
|
{
|
||||||
setupPlugins: [addPlugin({ name: 'insert', plugin: insertPlugin, location: 'top' })],
|
setupPlugins: [addPlugin(insertPlugin, undefined, { location: 'top' })],
|
||||||
},
|
},
|
||||||
oneExistingPlugin,
|
oneExistingPlugin,
|
||||||
);
|
);
|
||||||
expect(config.plugins).to.deep.equal(['-- insertPlugin --', 'firstPlugin']);
|
expect(config.plugins).to.deep.equal(['-- first last Plugin --', 'firstPlugin']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles inserting "before" the 0 index ', async () => {
|
it('handles inserting "before" the 0 index ', async () => {
|
||||||
const config = metaConfigToRollupConfig(
|
const config = applyPlugins(
|
||||||
{
|
{
|
||||||
setupPlugins: [
|
setupPlugins: [addPlugin(insertPlugin, undefined, { location: 'top', how: 'before' })],
|
||||||
addPlugin({ name: 'insert', plugin: insertPlugin, location: 'top', how: 'before' }),
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
oneExistingPlugin,
|
oneExistingPlugin,
|
||||||
);
|
);
|
||||||
expect(config.plugins).to.deep.equal(['-- insertPlugin --', 'firstPlugin']);
|
expect(config.plugins).to.deep.equal(['-- first last Plugin --', 'firstPlugin']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds after a given location by default', async () => {
|
it('adds after a given location by default', async () => {
|
||||||
const config = metaConfigToRollupConfig(
|
const config = applyPlugins(
|
||||||
{
|
{
|
||||||
setupPlugins: [addPlugin({ name: 'insert', plugin: insertPlugin, location: 'second' })],
|
setupPlugins: [addPlugin(insertPlugin, undefined, { location: secondPlugin })],
|
||||||
},
|
},
|
||||||
threeExistingPlugins,
|
threeExistingPlugins,
|
||||||
);
|
);
|
||||||
expect(config.plugins).to.deep.equal([
|
expect(config.plugins).to.deep.equal([
|
||||||
'firstPlugin',
|
'firstPlugin',
|
||||||
'secondPlugin',
|
'secondPlugin',
|
||||||
'-- insertPlugin --',
|
'-- first last Plugin --',
|
||||||
'thirdPlugin',
|
'thirdPlugin',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can adds before a given location', async () => {
|
it('can adds before a given location', async () => {
|
||||||
const config = metaConfigToRollupConfig(
|
const config = applyPlugins(
|
||||||
{
|
{
|
||||||
setupPlugins: [
|
setupPlugins: [
|
||||||
addPlugin({ name: 'insert', plugin: insertPlugin, location: 'second', how: 'before' }),
|
addPlugin(insertPlugin, undefined, { location: secondPlugin, how: 'before' }),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
threeExistingPlugins,
|
threeExistingPlugins,
|
||||||
);
|
);
|
||||||
expect(config.plugins).to.deep.equal([
|
expect(config.plugins).to.deep.equal([
|
||||||
'firstPlugin',
|
'firstPlugin',
|
||||||
'-- insertPlugin --',
|
'-- first last Plugin --',
|
||||||
'secondPlugin',
|
'secondPlugin',
|
||||||
'thirdPlugin',
|
'thirdPlugin',
|
||||||
]);
|
]);
|
||||||
@@ -84,16 +95,32 @@ describe('addPlugin', () => {
|
|||||||
|
|
||||||
it('throws if given location does not exist', async () => {
|
it('throws if given location does not exist', async () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
metaConfigToRollupConfig({
|
applyPlugins({
|
||||||
setupPlugins: [addPlugin({ name: 'insert', plugin: insertPlugin, location: 'not-found' })],
|
setupPlugins: [addPlugin(insertPlugin, undefined, { location: firstPlugin })],
|
||||||
});
|
});
|
||||||
}).to.throw('Could not find a plugin with the name "not-found" to insert "insert" after it.');
|
}).to.throw(
|
||||||
|
'Could not find a plugin with the name "firstPlugin" to insert "insertPlugin" after it.',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('accepts options', async () => {
|
it('accepts options', async () => {
|
||||||
const config = metaConfigToRollupConfig({
|
const config = applyPlugins({
|
||||||
setupPlugins: [addPlugin({ name: 'insert', plugin: insertPlugin, options: 'extra' })],
|
setupPlugins: [addPlugin(insertPlugin, { firstName: 'newFirst' })],
|
||||||
});
|
});
|
||||||
expect(config.plugins).to.deep.equal(['-- extraPlugin --']);
|
expect(config.plugins).to.deep.equal(['-- newFirst last Plugin --']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('[advanced] can add a `wrapPlugin` property to the function itself which will call it on the plugin on init', async () => {
|
||||||
|
function myWrapper(plugin) {
|
||||||
|
return () => 'wrapped' + plugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = applyPlugins({
|
||||||
|
setupPlugins: [addPlugin(insertPlugin)].map(mod => {
|
||||||
|
mod.wrapPlugin = myWrapper;
|
||||||
|
return mod;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
expect(config.plugins).to.deep.equal(['wrapped-- first last Plugin --']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,33 +1,43 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
import chai from 'chai';
|
import chai from 'chai';
|
||||||
|
|
||||||
import { adjustPluginOptions, metaConfigToRollupConfig } from 'plugins-manager';
|
import { adjustPluginOptions, applyPlugins } from '../index.js';
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
describe('adjustPluginOptions', () => {
|
describe('adjustPluginOptions', () => {
|
||||||
|
const firstPlugin = ({ flag = 'default-flag' } = {}) => `firstPlugin-${flag}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} options
|
||||||
|
* @param {object} [options.other]
|
||||||
|
* @param {string} [options.other.nested]
|
||||||
|
* @param {string} [options.other.nested2]
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const secondPlugin = ({ other = { nested: 'other.nested', nested2: 'other.nested2' } } = {}) =>
|
||||||
|
`secondPlugin-${other.nested}-${other.nested2}`;
|
||||||
|
const thirdPlugin = ({ name = 'name' }) => `thirdPlugin-${name}`;
|
||||||
|
|
||||||
const defaultCurrentMetaPlugins = [
|
const defaultCurrentMetaPlugins = [
|
||||||
|
{ plugin: firstPlugin, options: { flag: 'firstSettings' } },
|
||||||
{
|
{
|
||||||
name: 'first',
|
plugin: secondPlugin,
|
||||||
plugin: options => `firstPlugin-${options.flag}`,
|
|
||||||
options: { flag: 'firstSettings' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'second',
|
|
||||||
plugin: options => `secondPlugin-${options.other.nested}-${options.other.nested2}`,
|
|
||||||
options: { other: { nested: 'other.nested', nested2: 'other.nested2' } },
|
options: { other: { nested: 'other.nested', nested2: 'other.nested2' } },
|
||||||
},
|
},
|
||||||
{ name: 'third', plugin: options => `thirdPlugin-${options}`, options: 'aString' },
|
{ plugin: thirdPlugin, options: { name: 'name' } },
|
||||||
];
|
];
|
||||||
function newCurrentMetaPlugins() {
|
function newCurrentMetaPlugins() {
|
||||||
return defaultCurrentMetaPlugins.map(obj => ({ ...obj }));
|
return defaultCurrentMetaPlugins.map(obj => ({ ...obj }));
|
||||||
}
|
}
|
||||||
|
|
||||||
it('will merge options objects (flatly)', async () => {
|
it('will merge options objects (flatly)', async () => {
|
||||||
const config = metaConfigToRollupConfig(
|
const config = applyPlugins(
|
||||||
{
|
{
|
||||||
setupPlugins: [
|
setupPlugins: [
|
||||||
adjustPluginOptions('first', { flag: '#mod#FirstSettings' }),
|
adjustPluginOptions(firstPlugin, { flag: '#mod#FirstSettings' }),
|
||||||
adjustPluginOptions('second', { other: { nested: '#mod#other.nested' } }),
|
adjustPluginOptions(secondPlugin, { other: { nested: '#mod#other.nested' } }),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
newCurrentMetaPlugins(),
|
newCurrentMetaPlugins(),
|
||||||
@@ -35,14 +45,14 @@ describe('adjustPluginOptions', () => {
|
|||||||
expect(config.plugins).to.deep.equal([
|
expect(config.plugins).to.deep.equal([
|
||||||
'firstPlugin-#mod#FirstSettings',
|
'firstPlugin-#mod#FirstSettings',
|
||||||
'secondPlugin-#mod#other.nested-undefined',
|
'secondPlugin-#mod#other.nested-undefined',
|
||||||
'thirdPlugin-aString',
|
'thirdPlugin-name',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('will override non object settings', async () => {
|
it('will override non object settings', async () => {
|
||||||
const config = metaConfigToRollupConfig(
|
const config = applyPlugins(
|
||||||
{
|
{
|
||||||
setupPlugins: [adjustPluginOptions('third', '#mod#aString')],
|
setupPlugins: [adjustPluginOptions(thirdPlugin, { name: '#mod#aString' })],
|
||||||
},
|
},
|
||||||
newCurrentMetaPlugins(),
|
newCurrentMetaPlugins(),
|
||||||
);
|
);
|
||||||
@@ -54,11 +64,11 @@ describe('adjustPluginOptions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('accepts a function as a setting to manually merge objects', async () => {
|
it('accepts a function as a setting to manually merge objects', async () => {
|
||||||
const config = metaConfigToRollupConfig(
|
const config = applyPlugins(
|
||||||
{
|
{
|
||||||
setupPlugins: [
|
setupPlugins: [
|
||||||
adjustPluginOptions('second', config => ({
|
adjustPluginOptions(secondPlugin, config => ({
|
||||||
other: { ...config.other, nested: '#mod#other.nested' },
|
other: { ...config?.other, nested: '#mod#other.nested' },
|
||||||
})),
|
})),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -67,15 +77,76 @@ describe('adjustPluginOptions', () => {
|
|||||||
expect(config.plugins).to.deep.equal([
|
expect(config.plugins).to.deep.equal([
|
||||||
'firstPlugin-firstSettings',
|
'firstPlugin-firstSettings',
|
||||||
'secondPlugin-#mod#other.nested-other.nested2',
|
'secondPlugin-#mod#other.nested-other.nested2',
|
||||||
'thirdPlugin-aString',
|
'thirdPlugin-name',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws if given location does not exist', async () => {
|
it('throws if given plugin does not exist', async () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
metaConfigToRollupConfig({
|
applyPlugins({
|
||||||
setupPlugins: [adjustPluginOptions('not-found', '#mod#aString')],
|
setupPlugins: [adjustPluginOptions(firstPlugin, { flag: 'newFlag' })],
|
||||||
});
|
});
|
||||||
}).to.throw('Could not find a plugin with the name "not-found" to adjust the options.');
|
}).to.throw(
|
||||||
|
[
|
||||||
|
'Could not find a plugin with the name "firstPlugin" to adjust it\'s options with:',
|
||||||
|
'{',
|
||||||
|
' "flag": "newFlag"',
|
||||||
|
'}',
|
||||||
|
].join('\n'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with classes', async () => {
|
||||||
|
class FirstClass {
|
||||||
|
constructor({ firstName = 'initial-first' } = {}) {
|
||||||
|
this.options = { firstName };
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return `[[ firstName: ${this.options.firstName} ]]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} SecondClassOptions
|
||||||
|
* @property {string} lastName
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SecondClass {
|
||||||
|
/** @type {SecondClassOptions} */
|
||||||
|
options = {
|
||||||
|
lastName: 'initial-second',
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Partial<SecondClassOptions>} options
|
||||||
|
*/
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.options = { ...this.options, ...options };
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return `[[ lastName: ${this.options.lastName} ]]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = applyPlugins(
|
||||||
|
{
|
||||||
|
setupPlugins: [
|
||||||
|
adjustPluginOptions(SecondClass, { lastName: 'set-via-adjustPluginOptions' }),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{ plugin: FirstClass, options: {} },
|
||||||
|
{ plugin: SecondClass, options: {} },
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
config.plugins.map(/** @param {FirstClass | SecondClass} cls */ cls => cls.render()),
|
||||||
|
).to.deep.equal([
|
||||||
|
'[[ firstName: initial-first ]]',
|
||||||
|
'[[ lastName: set-via-adjustPluginOptions ]]',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
92
packages/plugins-manager/test-node/applyPlugins.test.js
Normal file
92
packages/plugins-manager/test-node/applyPlugins.test.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import chai from 'chai';
|
||||||
|
|
||||||
|
import { applyPlugins, addPlugin } from '../index.js';
|
||||||
|
|
||||||
|
const { expect } = chai;
|
||||||
|
|
||||||
|
describe('applyPlugins', () => {
|
||||||
|
const insertPlugin = () => `-- insertPlugin --`;
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @type {import('../types/main.js').MetaPlugin<T>[]}
|
||||||
|
*/
|
||||||
|
const oneExistingPlugin = [{ plugin: () => 'firstPlugin', options: {} }];
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @type {import('../types/main.js').MetaPlugin<T>[]}
|
||||||
|
*/
|
||||||
|
const threeExistingPlugin = [
|
||||||
|
{ plugin: () => 'firstPlugin', options: {} },
|
||||||
|
{ plugin: () => 'secondPlugin', options: {} },
|
||||||
|
{ plugin: () => 'thirdPlugin', options: {} },
|
||||||
|
];
|
||||||
|
|
||||||
|
it('converts meta config by executing the plugins and assigning it to the config', async () => {
|
||||||
|
const config = applyPlugins({}, threeExistingPlugin);
|
||||||
|
expect(config.plugins).to.deep.equal(['firstPlugin', 'secondPlugin', 'thirdPlugin']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('incorporates "setupPlugin" functions in the config & removes "setupPlugins"', async () => {
|
||||||
|
const config = applyPlugins(
|
||||||
|
{
|
||||||
|
setupPlugins: [addPlugin(insertPlugin)],
|
||||||
|
},
|
||||||
|
oneExistingPlugin,
|
||||||
|
);
|
||||||
|
expect(config.plugins).to.deep.equal(['firstPlugin', '-- insertPlugin --']);
|
||||||
|
expect(config.setupPlugins).to.be.undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('a provided plugins property will always win even if it is an empty array', async () => {
|
||||||
|
const config = applyPlugins({
|
||||||
|
setupPlugins: [addPlugin(insertPlugin)],
|
||||||
|
plugins: [],
|
||||||
|
});
|
||||||
|
expect(config.plugins).to.deep.equal([]);
|
||||||
|
expect(config.setupPlugins).to.be.undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prefers a user set config.plugins', async () => {
|
||||||
|
const config = applyPlugins(
|
||||||
|
{
|
||||||
|
setupPlugins: [addPlugin(insertPlugin)],
|
||||||
|
plugins: ['user-set'],
|
||||||
|
},
|
||||||
|
threeExistingPlugin,
|
||||||
|
);
|
||||||
|
expect(config.plugins).to.deep.equal(['user-set']);
|
||||||
|
expect(config.setupPlugins).to.be.undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with classes', async () => {
|
||||||
|
class FirstClass {
|
||||||
|
constructor({ firstName = 'initial-first' } = {}) {
|
||||||
|
this.options = { firstName };
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return `[[ firstName: ${this.options.firstName} ]]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class SecondClass {
|
||||||
|
constructor({ lastName = 'initial-second' } = {}) {
|
||||||
|
this.options = { lastName };
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return `[[ lastName: ${this.options.lastName} ]]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = applyPlugins({
|
||||||
|
setupPlugins: [
|
||||||
|
addPlugin(FirstClass),
|
||||||
|
addPlugin(SecondClass, { lastName: 'set-via-addPlugin' }),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
config.plugins.map(/** @param {FirstClass | SecondClass} cls */ cls => cls.render()),
|
||||||
|
).to.deep.equal(['[[ firstName: initial-first ]]', '[[ lastName: set-via-addPlugin ]]']);
|
||||||
|
});
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user