nuxt-content-assets 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -23
- package/dist/module.d.ts +1 -1
- package/dist/module.json +5 -2
- package/dist/module.mjs +50 -38
- package/dist/runtime/options.d.ts +9 -0
- package/dist/runtime/options.mjs +14 -0
- package/dist/runtime/{server/plugins/plugin.mjs → plugin.mjs} +7 -4
- package/dist/runtime/utils/assets.d.ts +33 -0
- package/dist/runtime/utils/assets.mjs +42 -0
- package/dist/runtime/utils/content.d.ts +7 -0
- package/dist/runtime/utils/content.mjs +12 -0
- package/dist/runtime/utils/debug.d.ts +2 -0
- package/dist/runtime/utils/debug.mjs +7 -0
- package/dist/runtime/utils/index.d.ts +4 -0
- package/dist/runtime/utils/index.mjs +4 -0
- package/dist/runtime/utils/object.d.ts +10 -0
- package/dist/runtime/utils/object.mjs +22 -0
- package/package.json +1 -1
- /package/dist/runtime/{server/plugins/plugin.d.ts → plugin.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# Nuxt Content Assets
|
|
2
2
|
|
|
3
|
-
> Enable locally-located assets in Nuxt Content
|
|
4
|
-
|
|
5
3
|
[![npm version][npm-version-src]][npm-version-href]
|
|
6
4
|
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
7
5
|
[![License][license-src]][license-href]
|
|
8
6
|
[![Nuxt][nuxt-src]][nuxt-href]
|
|
9
7
|
|
|
8
|
+
> Enable locally-located assets in Nuxt Content
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<img src="https://raw.githubusercontent.com/davestewart/nuxt-content-assets/main/demo/content/splash.png" alt="Nuxt Content Assets logo">
|
|
12
|
+
</p>
|
|
13
|
+
|
|
10
14
|
## Overview
|
|
11
15
|
|
|
12
16
|
Nuxt Content Assets enables locally-located assets in your [Nuxt Content](https://content.nuxtjs.org/) folder:
|
|
@@ -53,7 +57,7 @@ To run the demo online, go to:
|
|
|
53
57
|
|
|
54
58
|
You can browse the demo files in:
|
|
55
59
|
|
|
56
|
-
-
|
|
60
|
+
- https://github.com/davestewart/nuxt-content-assets/tree/main/demo
|
|
57
61
|
|
|
58
62
|
To run the demo locally, clone the application and from the root, run:
|
|
59
63
|
|
|
@@ -74,7 +78,7 @@ Configure `nuxt.config.ts`:
|
|
|
74
78
|
```js
|
|
75
79
|
export default defineNuxtConfig({
|
|
76
80
|
modules: [
|
|
77
|
-
'nuxt-content-
|
|
81
|
+
'nuxt-content-assets', // make sure to add before content!
|
|
78
82
|
'@nuxt/content',
|
|
79
83
|
]
|
|
80
84
|
})
|
|
@@ -111,21 +115,28 @@ See the [configuration](#output) section for more options.
|
|
|
111
115
|
|
|
112
116
|
### Images
|
|
113
117
|
|
|
114
|
-
The module [optionally](#image-attributes)
|
|
118
|
+
The module can [optionally](#image-attributes) write `width`, `height` and `aspect-ratio` information to generated `<img>` tags:
|
|
115
119
|
|
|
116
120
|
```html
|
|
117
|
-
<img src="..." width="640" height="480">
|
|
121
|
+
<img src="..." width="640" height="480" style="aspect-ratio:640/480">
|
|
118
122
|
```
|
|
119
123
|
|
|
120
|
-
This
|
|
124
|
+
This can prevent content jumps on page load. If you add `attributes` only, include the following CSS in your app:
|
|
125
|
+
|
|
126
|
+
```css
|
|
127
|
+
img {
|
|
128
|
+
max-width: 100%;
|
|
129
|
+
height: auto;
|
|
130
|
+
}
|
|
131
|
+
```
|
|
121
132
|
|
|
122
|
-
If you use custom [ProseImg](https://content.nuxtjs.org/api/components/prose) components, you can
|
|
133
|
+
If you use custom [ProseImg](https://content.nuxtjs.org/api/components/prose) components, you can use these values in your own markup:
|
|
123
134
|
|
|
124
135
|
```vue
|
|
125
136
|
<template>
|
|
126
|
-
<
|
|
127
|
-
<img :src="$attrs.src" :style="
|
|
128
|
-
</
|
|
137
|
+
<span class="image">
|
|
138
|
+
<img :src="$attrs.src" :style="$attrs.style" />
|
|
139
|
+
</span>
|
|
129
140
|
</template>
|
|
130
141
|
|
|
131
142
|
<script>
|
|
@@ -154,8 +165,8 @@ export default defineNuxtConfig({
|
|
|
154
165
|
// completely replace supported extensions
|
|
155
166
|
extensions: 'png jpg',
|
|
156
167
|
|
|
157
|
-
//
|
|
158
|
-
|
|
168
|
+
// use aspect-ratio rather than attributes
|
|
169
|
+
imageSize: 'ratio',
|
|
159
170
|
|
|
160
171
|
// print debug messages to the console
|
|
161
172
|
debug: true,
|
|
@@ -168,7 +179,7 @@ export default defineNuxtConfig({
|
|
|
168
179
|
The output path can be customised using a template string:
|
|
169
180
|
|
|
170
181
|
```
|
|
171
|
-
assets/
|
|
182
|
+
assets/content/[name]-[hash].[ext]
|
|
172
183
|
```
|
|
173
184
|
|
|
174
185
|
The first part of the path should be public root-relative folder:
|
|
@@ -177,7 +188,7 @@ The first part of the path should be public root-relative folder:
|
|
|
177
188
|
assets/img/content
|
|
178
189
|
```
|
|
179
190
|
|
|
180
|
-
The optional second part of the path indicates
|
|
191
|
+
The optional second part of the path indicates the relative location of each image:
|
|
181
192
|
|
|
182
193
|
| Token | Description | Example |
|
|
183
194
|
|-------------|--------------------------------------------|--------------------|
|
|
@@ -196,15 +207,15 @@ For example:
|
|
|
196
207
|
| `assets/img/[name]-[hash].[ext]` | `assets/img/featured-9M00N4l9A0.jpg` |
|
|
197
208
|
| `content/[hash].[ext]` | `content/9M00N4l9A0.jpg` |
|
|
198
209
|
|
|
199
|
-
Note that the module defaults to
|
|
210
|
+
Note that the module defaults to:
|
|
200
211
|
|
|
201
212
|
```
|
|
202
|
-
/assets/content/[
|
|
213
|
+
/assets/content/[folder]/[file]
|
|
203
214
|
```
|
|
204
215
|
|
|
205
216
|
### Extensions
|
|
206
217
|
|
|
207
|
-
You can add or replace supported extensions if you need to:
|
|
218
|
+
You can add (or replace) supported extensions if you need to:
|
|
208
219
|
|
|
209
220
|
To add extensions, use `additionalExtensions`:
|
|
210
221
|
|
|
@@ -214,26 +225,36 @@ To add extensions, use `additionalExtensions`:
|
|
|
214
225
|
}
|
|
215
226
|
```
|
|
216
227
|
|
|
217
|
-
To
|
|
228
|
+
To replace extensions, use `extensions`:
|
|
218
229
|
|
|
219
230
|
```ts
|
|
220
231
|
{
|
|
221
|
-
|
|
232
|
+
extensions: 'png jpg' // serve png and jpg files only
|
|
222
233
|
}
|
|
223
234
|
```
|
|
224
235
|
|
|
225
236
|
### Image attributes
|
|
226
237
|
|
|
227
|
-
|
|
238
|
+
You can add image size hints to the generated images.
|
|
228
239
|
|
|
229
|
-
|
|
240
|
+
To add `style` aspect-ratio:
|
|
230
241
|
|
|
231
242
|
```ts
|
|
232
243
|
{
|
|
233
|
-
|
|
244
|
+
imageSize: 'style'
|
|
234
245
|
}
|
|
235
246
|
```
|
|
236
247
|
|
|
248
|
+
To add `width` and `height` attributes:
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
{
|
|
252
|
+
imageSize: 'attrs'
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
You can even add both if you need to.
|
|
257
|
+
|
|
237
258
|
## Development
|
|
238
259
|
|
|
239
260
|
Should you wish to develop the project, the scripts are:
|
package/dist/module.d.ts
CHANGED
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -6,8 +6,37 @@ import * as Path from 'path';
|
|
|
6
6
|
import Path__default from 'path';
|
|
7
7
|
import { hash } from 'ohash';
|
|
8
8
|
|
|
9
|
+
function getSources(sources) {
|
|
10
|
+
return Object.keys(sources).reduce((output, key) => {
|
|
11
|
+
const source = sources[key];
|
|
12
|
+
if (source) {
|
|
13
|
+
const { driver, base } = source;
|
|
14
|
+
if (driver === "fs") {
|
|
15
|
+
output[key] = base;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return output;
|
|
19
|
+
}, {});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const defaults = {
|
|
23
|
+
assetsDir: "assets/content",
|
|
24
|
+
assetsPattern: "[folder]/[file]"
|
|
25
|
+
};
|
|
26
|
+
const imageExtensions = matchWords("png jpg jpeg gif svg webp ico");
|
|
27
|
+
const mediaExtensions = matchWords("mp3 m4a wav mp4 mov webm ogg avi flv avchd");
|
|
28
|
+
const fileExtensions = matchWords("pdf doc docx xls xlsx ppt pptx odp key");
|
|
29
|
+
const extensions = [
|
|
30
|
+
...imageExtensions,
|
|
31
|
+
...mediaExtensions,
|
|
32
|
+
...fileExtensions
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const moduleName = "nuxt-content-assets";
|
|
36
|
+
const moduleKey = "content-assets";
|
|
37
|
+
|
|
9
38
|
function log(...data) {
|
|
10
|
-
console.info(`[${
|
|
39
|
+
console.info(`[${moduleKey}]`, ...data);
|
|
11
40
|
}
|
|
12
41
|
|
|
13
42
|
function matchWords(value) {
|
|
@@ -39,48 +68,25 @@ const replacers = {
|
|
|
39
68
|
hash: (src) => hash({ src })
|
|
40
69
|
};
|
|
41
70
|
|
|
42
|
-
const name = "content-assets";
|
|
43
|
-
const defaults = {
|
|
44
|
-
assetsDir: "assets/content",
|
|
45
|
-
assetsPattern: "[name]-[hash].[ext]"
|
|
46
|
-
};
|
|
47
|
-
const imageExtensions = matchWords("png jpg jpeg gif svg webp ico");
|
|
48
|
-
const mediaExtensions = matchWords("mp3 m4a wav mp4 mov webm ogg avi flv avchd");
|
|
49
|
-
const fileExtensions = matchWords("pdf doc docx xls xlsx ppt pptx odp key");
|
|
50
|
-
const extensions = [
|
|
51
|
-
...imageExtensions,
|
|
52
|
-
...mediaExtensions,
|
|
53
|
-
...fileExtensions
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
function getSources(sources) {
|
|
57
|
-
return Object.keys(sources).reduce((output, key) => {
|
|
58
|
-
const source = sources[key];
|
|
59
|
-
if (source) {
|
|
60
|
-
const { driver, base } = source;
|
|
61
|
-
if (driver === "fs") {
|
|
62
|
-
output[key] = base;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return output;
|
|
66
|
-
}, {});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
71
|
const resolve = createResolver(import.meta.url).resolve;
|
|
70
72
|
const module = defineNuxtModule({
|
|
71
73
|
meta: {
|
|
72
|
-
name
|
|
74
|
+
name: moduleName,
|
|
75
|
+
configKey: moduleKey,
|
|
76
|
+
compatibility: {
|
|
77
|
+
nuxt: "^3.0.0"
|
|
78
|
+
}
|
|
73
79
|
},
|
|
74
80
|
defaults: {
|
|
75
81
|
output: `${defaults.assetsDir}/${defaults.assetsPattern}`,
|
|
76
82
|
extensions: "",
|
|
77
83
|
additionalExtensions: "",
|
|
78
|
-
|
|
84
|
+
imageSize: "",
|
|
79
85
|
debug: false
|
|
80
86
|
},
|
|
81
87
|
setup(options, nuxt) {
|
|
82
88
|
var _a;
|
|
83
|
-
const pluginPath = resolve("./runtime/
|
|
89
|
+
const pluginPath = resolve("./runtime/plugin");
|
|
84
90
|
const buildPath = nuxt.options.buildDir;
|
|
85
91
|
const cachePath = Path.resolve(buildPath, "content-assets");
|
|
86
92
|
if (options.debug) {
|
|
@@ -116,16 +122,22 @@ const module = defineNuxtModule({
|
|
|
116
122
|
function getAssetConfig(pattern, src, dir) {
|
|
117
123
|
let width = void 0;
|
|
118
124
|
let height = void 0;
|
|
119
|
-
|
|
125
|
+
let ratio = "";
|
|
126
|
+
if (options.imageSize && isImage(src)) {
|
|
120
127
|
const size = getImageSize(src);
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
if (options.imageSize.includes("style")) {
|
|
129
|
+
ratio = `${size.width}/${size.height}`;
|
|
130
|
+
}
|
|
131
|
+
if (options.imageSize.includes("attrs")) {
|
|
132
|
+
width = size.width;
|
|
133
|
+
height = size.height;
|
|
134
|
+
}
|
|
123
135
|
}
|
|
124
136
|
const id = Path.join(Path.basename(dir), Path.relative(dir, src)).replaceAll("/", ":");
|
|
125
137
|
const file = interpolatePattern(pattern, src, dir);
|
|
126
138
|
const trg = Path.join(cachePath, assetsDir, file);
|
|
127
139
|
const rel = Path.join("/", assetsDir, file);
|
|
128
|
-
return { id, file, trg, rel, width, height };
|
|
140
|
+
return { id, file, trg, rel, width, height, ratio };
|
|
129
141
|
}
|
|
130
142
|
const publicFolder = Path.join(cachePath, assetsDir);
|
|
131
143
|
const sourceFolders = Object.values(sources);
|
|
@@ -159,15 +171,15 @@ ${paths.join("\n")}
|
|
|
159
171
|
`export const assets = ${JSON.stringify(assets)}`,
|
|
160
172
|
`export const sources = ${JSON.stringify(sources)}`
|
|
161
173
|
].join("\n");
|
|
162
|
-
nuxt.options.alias[`#${
|
|
163
|
-
filename: `${
|
|
174
|
+
nuxt.options.alias[`#${moduleName}`] = addTemplate({
|
|
175
|
+
filename: `${moduleName}.mjs`,
|
|
164
176
|
getContents: () => virtualConfig
|
|
165
177
|
}).dst;
|
|
166
178
|
nuxt.hook("nitro:config", async (config) => {
|
|
167
179
|
config.plugins || (config.plugins = []);
|
|
168
180
|
config.plugins.push(pluginPath);
|
|
169
181
|
config.virtual || (config.virtual = {});
|
|
170
|
-
config.virtual[`#${
|
|
182
|
+
config.virtual[`#${moduleName}`] = virtualConfig;
|
|
171
183
|
config.publicAssets || (config.publicAssets = []);
|
|
172
184
|
config.publicAssets.push({
|
|
173
185
|
dir: cachePath
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const defaults: {
|
|
2
|
+
assetsDir: string;
|
|
3
|
+
assetsPattern: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const imageExtensions: RegExpMatchArray | [];
|
|
6
|
+
export declare const mediaExtensions: RegExpMatchArray | [];
|
|
7
|
+
export declare const fileExtensions: RegExpMatchArray | [];
|
|
8
|
+
export declare const extensions: string[];
|
|
9
|
+
export declare const tags: string[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { matchWords } from "./utils/assets.mjs";
|
|
2
|
+
export const defaults = {
|
|
3
|
+
assetsDir: "assets/content",
|
|
4
|
+
assetsPattern: "[folder]/[file]"
|
|
5
|
+
};
|
|
6
|
+
export const imageExtensions = matchWords("png jpg jpeg gif svg webp ico");
|
|
7
|
+
export const mediaExtensions = matchWords("mp3 m4a wav mp4 mov webm ogg avi flv avchd");
|
|
8
|
+
export const fileExtensions = matchWords("pdf doc docx xls xlsx ppt pptx odp key");
|
|
9
|
+
export const extensions = [
|
|
10
|
+
...imageExtensions,
|
|
11
|
+
...mediaExtensions,
|
|
12
|
+
...fileExtensions
|
|
13
|
+
];
|
|
14
|
+
export const tags = ["img", "video", "audio", "source", "embed", "iframe", "a"];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Path from "path";
|
|
2
2
|
import { visit } from "unist-util-visit";
|
|
3
|
-
import {
|
|
4
|
-
import { tags } from "
|
|
5
|
-
import {
|
|
3
|
+
import { isValidAsset, walk } from "./utils/index.mjs";
|
|
4
|
+
import { tags } from "./options.mjs";
|
|
5
|
+
import { assets, sources } from "#nuxt-content-assets";
|
|
6
6
|
function getDocPath(id) {
|
|
7
7
|
const parts = id.split(":");
|
|
8
8
|
const key = parts.shift();
|
|
@@ -29,7 +29,7 @@ export default defineNitroPlugin(async (nitroApp) => {
|
|
|
29
29
|
}, filter);
|
|
30
30
|
visit(file.body, (n) => tags.includes(n.tag), (node) => {
|
|
31
31
|
if (node.props.src) {
|
|
32
|
-
const { rel, width, height } = getAsset(absDoc, node.props.src);
|
|
32
|
+
const { rel, width, height, ratio } = getAsset(absDoc, node.props.src);
|
|
33
33
|
if (rel) {
|
|
34
34
|
node.props.src = rel;
|
|
35
35
|
}
|
|
@@ -37,6 +37,9 @@ export default defineNitroPlugin(async (nitroApp) => {
|
|
|
37
37
|
node.props.width = width;
|
|
38
38
|
node.props.height = height;
|
|
39
39
|
}
|
|
40
|
+
if (ratio) {
|
|
41
|
+
node.props.style = `aspect-ratio:${ratio}`;
|
|
42
|
+
}
|
|
40
43
|
} else if (node.tag === "a") {
|
|
41
44
|
if (node.props.href) {
|
|
42
45
|
const { rel } = getAsset(absDoc, node.props.href);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get matched words from a string
|
|
3
|
+
*/
|
|
4
|
+
export declare function matchWords(value: string): RegExpMatchArray | [];
|
|
5
|
+
/**
|
|
6
|
+
* Test path to be relative
|
|
7
|
+
*/
|
|
8
|
+
export declare function isRelative(path: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Test path for image extension
|
|
11
|
+
*/
|
|
12
|
+
export declare function isImage(path: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Test path for asset extension
|
|
15
|
+
*/
|
|
16
|
+
export declare function isAsset(path: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Test if value is a valid asset
|
|
19
|
+
*/
|
|
20
|
+
export declare function isValidAsset(value?: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Interpolate assets path pattern
|
|
23
|
+
*
|
|
24
|
+
* @param pattern A path pattern with tokens
|
|
25
|
+
* @param src The absolute path to a src asset
|
|
26
|
+
* @param dir The absolute path to its containing folder
|
|
27
|
+
* @param warn An optional flag to warn for unknown tokens
|
|
28
|
+
*/
|
|
29
|
+
export declare function interpolatePattern(pattern: string, src: string, dir: string, warn?: boolean): any;
|
|
30
|
+
/**
|
|
31
|
+
* Hash of replacer functions
|
|
32
|
+
*/
|
|
33
|
+
export declare const replacers: Record<string, Function>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import Path from "path";
|
|
2
|
+
import { hash as ohash } from "ohash";
|
|
3
|
+
import { extensions, imageExtensions } from "../options.mjs";
|
|
4
|
+
import { log } from "./debug.mjs";
|
|
5
|
+
export function matchWords(value) {
|
|
6
|
+
return value.match(/\w+/g) || [];
|
|
7
|
+
}
|
|
8
|
+
export function isRelative(path) {
|
|
9
|
+
return !(path.startsWith("http") || Path.isAbsolute(path));
|
|
10
|
+
}
|
|
11
|
+
export function isImage(path) {
|
|
12
|
+
const ext = Path.extname(path).substring(1);
|
|
13
|
+
return imageExtensions.includes(ext);
|
|
14
|
+
}
|
|
15
|
+
export function isAsset(path) {
|
|
16
|
+
const ext = Path.extname(path).substring(1);
|
|
17
|
+
return extensions.includes(ext);
|
|
18
|
+
}
|
|
19
|
+
export function isValidAsset(value) {
|
|
20
|
+
return typeof value === "string" && isAsset(value) && isRelative(value);
|
|
21
|
+
}
|
|
22
|
+
export function interpolatePattern(pattern, src, dir, warn = false) {
|
|
23
|
+
return Path.join(pattern.replace(/\[\w+]/g, (match) => {
|
|
24
|
+
const name = match.substring(1, match.length - 1);
|
|
25
|
+
const fn = replacers[name];
|
|
26
|
+
if (fn) {
|
|
27
|
+
return fn(src, dir);
|
|
28
|
+
}
|
|
29
|
+
if (warn) {
|
|
30
|
+
log(`Unknown output token ${match}`, true);
|
|
31
|
+
}
|
|
32
|
+
return match;
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
export const replacers = {
|
|
36
|
+
folder: (src, dir) => Path.dirname(src.replace(dir, "")),
|
|
37
|
+
file: (src) => Path.basename(src),
|
|
38
|
+
name: (src) => Path.basename(src, Path.extname(src)),
|
|
39
|
+
extname: (src) => Path.extname(src),
|
|
40
|
+
ext: (src) => Path.extname(src).substring(1),
|
|
41
|
+
hash: (src) => ohash({ src })
|
|
42
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function getSources(sources) {
|
|
2
|
+
return Object.keys(sources).reduce((output, key) => {
|
|
3
|
+
const source = sources[key];
|
|
4
|
+
if (source) {
|
|
5
|
+
const { driver, base } = source;
|
|
6
|
+
if (driver === "fs") {
|
|
7
|
+
output[key] = base;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return output;
|
|
11
|
+
}, {});
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Callback = (value: any, parent?: any, key?: string | number) => void;
|
|
2
|
+
export type Filter = (value: any, key?: string | number) => boolean | void;
|
|
3
|
+
/**
|
|
4
|
+
* Walk an object structure
|
|
5
|
+
*
|
|
6
|
+
* @param node
|
|
7
|
+
* @param callback
|
|
8
|
+
* @param filter
|
|
9
|
+
*/
|
|
10
|
+
export declare function walk(node: any, callback: Callback, filter?: Filter): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function walk(node, callback, filter) {
|
|
2
|
+
function visit(node2, callback2, parent, key) {
|
|
3
|
+
if (filter) {
|
|
4
|
+
const result = filter(node2, key);
|
|
5
|
+
if (result === false) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
if (Array.isArray(node2)) {
|
|
10
|
+
node2.forEach((value, index) => {
|
|
11
|
+
visit(value, callback2, node2, index);
|
|
12
|
+
});
|
|
13
|
+
} else if (typeof node2 === "object" && node2 !== null) {
|
|
14
|
+
Object.keys(node2).forEach((key2) => {
|
|
15
|
+
visit(node2[key2], callback2, node2, key2);
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
callback2(node2, parent, key);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
visit(node, callback);
|
|
22
|
+
}
|
package/package.json
CHANGED
|
File without changes
|