nuxt-content-assets 1.1.1 → 1.2.1
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 +2 -0
- package/dist/module.d.ts +21 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +349 -168
- package/dist/runtime/assets/public.d.ts +41 -0
- package/dist/runtime/assets/public.mjs +111 -0
- package/dist/runtime/{services/sources.d.ts → assets/source.d.ts} +4 -4
- package/dist/runtime/{services/sources.mjs → assets/source.mjs} +4 -14
- package/dist/runtime/content/parsed.d.ts +5 -0
- package/dist/runtime/content/parsed.mjs +32 -0
- package/dist/runtime/content/plugin.mjs +65 -0
- package/dist/runtime/sockets/factory.d.ts +5 -1
- package/dist/runtime/sockets/factory.mjs +3 -10
- package/dist/runtime/sockets/plugin.d.ts +3 -0
- package/dist/runtime/sockets/plugin.mjs +31 -8
- package/dist/runtime/sockets/setup.d.ts +1 -1
- package/dist/runtime/sockets/setup.mjs +15 -2
- package/dist/runtime/utils/config.d.ts +11 -0
- package/dist/runtime/utils/config.mjs +12 -0
- package/dist/runtime/utils/content.d.ts +16 -0
- package/dist/runtime/utils/content.mjs +43 -0
- package/dist/runtime/utils/index.d.ts +2 -0
- package/dist/runtime/utils/index.mjs +2 -0
- package/dist/runtime/utils/object.d.ts +7 -3
- package/dist/runtime/utils/object.mjs +5 -2
- package/dist/runtime/utils/path.mjs +1 -1
- package/dist/types.d.ts +2 -6
- package/package.json +2 -4
- package/dist/runtime/config.d.ts +0 -2
- package/dist/runtime/config.mjs +0 -2
- package/dist/runtime/options.d.ts +0 -10
- package/dist/runtime/options.mjs +0 -18
- package/dist/runtime/plugin.mjs +0 -121
- package/dist/runtime/services/assets.d.ts +0 -25
- package/dist/runtime/services/assets.mjs +0 -23
- package/dist/runtime/services/index.d.ts +0 -3
- package/dist/runtime/services/index.mjs +0 -3
- package/dist/runtime/services/paths.d.ts +0 -8
- package/dist/runtime/services/paths.mjs +0 -26
- package/dist/runtime/sockets/composable.d.ts +0 -2
- package/dist/runtime/sockets/composable.mjs +0 -12
- /package/dist/runtime/{plugin.d.ts → content/plugin.d.ts} +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ParsedContent, AssetConfig } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Manages the public assets
|
|
4
|
+
*/
|
|
5
|
+
export declare function makeAssetsManager(publicPath: string): {
|
|
6
|
+
setAsset: (path: string) => AssetConfig;
|
|
7
|
+
getAsset: (path: string) => AssetConfig | undefined;
|
|
8
|
+
removeAsset: (path: string) => AssetConfig | undefined;
|
|
9
|
+
resolveAsset: (content: ParsedContent, relAsset: string, registerContent?: boolean) => AssetConfig;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Hash of replacer functions
|
|
13
|
+
*/
|
|
14
|
+
export declare const replacers: Record<string, (src: string) => string>;
|
|
15
|
+
/**
|
|
16
|
+
* Interpolate assets path pattern
|
|
17
|
+
*
|
|
18
|
+
* @param pattern A path pattern with tokens
|
|
19
|
+
* @param src The relative path to a src asset
|
|
20
|
+
* @param warn An optional flag to warn for unknown tokens
|
|
21
|
+
*/
|
|
22
|
+
export declare function interpolatePattern(pattern: string, src: string, warn?: boolean): string;
|
|
23
|
+
/**
|
|
24
|
+
* Parse asset paths from absolute path
|
|
25
|
+
*
|
|
26
|
+
* @param srcDir The absolute path to the asset's source folder
|
|
27
|
+
* @param srcAbs The absolute path to the asset itself
|
|
28
|
+
*/
|
|
29
|
+
export declare function getAssetPaths(srcDir: string, srcAbs: string): {
|
|
30
|
+
srcRel: string;
|
|
31
|
+
srcAttr: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Get asset image sizes
|
|
35
|
+
*
|
|
36
|
+
* @param srcAbs The absolute path to the asset itself
|
|
37
|
+
*/
|
|
38
|
+
export declare function getAssetSize(srcAbs: string): {
|
|
39
|
+
width?: number;
|
|
40
|
+
height?: number;
|
|
41
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as Path from "path";
|
|
2
|
+
import getImageSize from "image-size";
|
|
3
|
+
import debounce from "debounce";
|
|
4
|
+
import { hash } from "ohash";
|
|
5
|
+
import { makeSourceStorage } from "./source.mjs";
|
|
6
|
+
import { isImage, warn, log } from "../utils/index.mjs";
|
|
7
|
+
export function makeAssetsManager(publicPath) {
|
|
8
|
+
const indexKey = "assets.json";
|
|
9
|
+
const storage = makeSourceStorage(Path.join(publicPath, ".."));
|
|
10
|
+
storage.watch(async (event, key) => {
|
|
11
|
+
if (event === "update" && key === indexKey) {
|
|
12
|
+
await load();
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const assets = {};
|
|
16
|
+
async function load() {
|
|
17
|
+
const data = await storage.getItem(indexKey);
|
|
18
|
+
Object.assign(assets, data || {});
|
|
19
|
+
}
|
|
20
|
+
const save = debounce(function() {
|
|
21
|
+
storage.setItem(indexKey, assets);
|
|
22
|
+
}, 50);
|
|
23
|
+
function resolveAsset(content, relAsset, registerContent = false) {
|
|
24
|
+
const srcDir = Path.dirname(content._file);
|
|
25
|
+
const srcAsset = Path.join(srcDir, relAsset);
|
|
26
|
+
const asset = assets[srcAsset];
|
|
27
|
+
if (asset && registerContent) {
|
|
28
|
+
const { _id } = content;
|
|
29
|
+
if (!asset.content.includes(_id)) {
|
|
30
|
+
asset.content.push(_id);
|
|
31
|
+
save();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return asset || {};
|
|
35
|
+
}
|
|
36
|
+
function setAsset(path) {
|
|
37
|
+
const { srcRel, srcAttr } = getAssetPaths(publicPath, path);
|
|
38
|
+
const { width, height } = getAssetSize(path);
|
|
39
|
+
const oldAsset = assets[srcRel];
|
|
40
|
+
const newAsset = {
|
|
41
|
+
srcAttr,
|
|
42
|
+
content: oldAsset?.content || [],
|
|
43
|
+
width,
|
|
44
|
+
height
|
|
45
|
+
};
|
|
46
|
+
assets[srcRel] = newAsset;
|
|
47
|
+
save();
|
|
48
|
+
return newAsset;
|
|
49
|
+
}
|
|
50
|
+
function getAsset(path) {
|
|
51
|
+
const { srcRel } = getAssetPaths(publicPath, path);
|
|
52
|
+
return srcRel ? { ...assets[srcRel] } : void 0;
|
|
53
|
+
}
|
|
54
|
+
function removeAsset(path) {
|
|
55
|
+
const { srcRel } = getAssetPaths(publicPath, path);
|
|
56
|
+
const asset = assets[srcRel];
|
|
57
|
+
if (asset) {
|
|
58
|
+
delete assets[srcRel];
|
|
59
|
+
save();
|
|
60
|
+
}
|
|
61
|
+
return asset;
|
|
62
|
+
}
|
|
63
|
+
void load();
|
|
64
|
+
return {
|
|
65
|
+
setAsset,
|
|
66
|
+
getAsset,
|
|
67
|
+
removeAsset,
|
|
68
|
+
resolveAsset
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export const replacers = {
|
|
72
|
+
key: (src) => Path.dirname(src).split("/").filter((e) => e).shift() || "",
|
|
73
|
+
path: (src) => Path.dirname(src),
|
|
74
|
+
folder: (src) => Path.dirname(src).replace(/[^/]+\//, ""),
|
|
75
|
+
file: (src) => Path.basename(src),
|
|
76
|
+
name: (src) => Path.basename(src, Path.extname(src)),
|
|
77
|
+
extname: (src) => Path.extname(src),
|
|
78
|
+
ext: (src) => Path.extname(src).substring(1),
|
|
79
|
+
hash: (src) => hash({ src })
|
|
80
|
+
};
|
|
81
|
+
export function interpolatePattern(pattern, src, warn2 = false) {
|
|
82
|
+
return Path.join(pattern.replace(/\[\w+]/g, (match) => {
|
|
83
|
+
const name = match.substring(1, match.length - 1);
|
|
84
|
+
const fn = replacers[name];
|
|
85
|
+
if (fn) {
|
|
86
|
+
return fn(src);
|
|
87
|
+
}
|
|
88
|
+
if (warn2) {
|
|
89
|
+
log(`Unknown output token ${match}`, true);
|
|
90
|
+
}
|
|
91
|
+
return match;
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
export function getAssetPaths(srcDir, srcAbs) {
|
|
95
|
+
const srcRel = Path.relative(srcDir, srcAbs);
|
|
96
|
+
const srcAttr = "/" + srcRel;
|
|
97
|
+
return {
|
|
98
|
+
srcRel,
|
|
99
|
+
srcAttr
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function getAssetSize(srcAbs) {
|
|
103
|
+
if (isImage(srcAbs)) {
|
|
104
|
+
try {
|
|
105
|
+
return getImageSize(srcAbs);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
warn(`could not read image "${srcAbs}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {};
|
|
111
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { WatchEvent, Storage } from 'unstorage';
|
|
2
1
|
import { MountOptions } from '@nuxt/content';
|
|
2
|
+
import { WatchEvent, Storage } from 'unstorage';
|
|
3
3
|
/**
|
|
4
|
-
* Make a Storage instance
|
|
4
|
+
* Make a Storage instance that monitors assets from a single source
|
|
5
5
|
*/
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function makeSourceStorage(source: MountOptions | string, key?: string): Storage;
|
|
7
7
|
export interface SourceManager {
|
|
8
8
|
storage: Storage;
|
|
9
9
|
init: () => Promise<string[]>;
|
|
@@ -12,7 +12,7 @@ export interface SourceManager {
|
|
|
12
12
|
/**
|
|
13
13
|
* Make a SourceManager instance
|
|
14
14
|
*
|
|
15
|
-
* Each Source Manager is responsible for mirroring source
|
|
15
|
+
* Each Source Manager is responsible for watching and mirroring source assets to the public assets folder
|
|
16
16
|
*
|
|
17
17
|
* @param key
|
|
18
18
|
* @param source
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
import * as Path from "path";
|
|
2
|
-
import { createStorage } from "unstorage";
|
|
3
2
|
import githubDriver from "unstorage/drivers/github";
|
|
4
3
|
import fsDriver from "unstorage/drivers/fs";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
isAsset,
|
|
8
|
-
toPath,
|
|
9
|
-
removeFile,
|
|
10
|
-
copyFile,
|
|
11
|
-
writeBlob,
|
|
12
|
-
writeFile,
|
|
13
|
-
deKey,
|
|
14
|
-
isExcluded
|
|
15
|
-
} from "../utils/index.mjs";
|
|
4
|
+
import { createStorage } from "unstorage";
|
|
5
|
+
import { warn, isAsset, toPath, removeFile, copyFile, writeBlob, writeFile, deKey, isExcluded } from "../utils/index.mjs";
|
|
16
6
|
function isAssetId(id) {
|
|
17
7
|
const path = toPath(id);
|
|
18
8
|
return !isExcluded(path) && isAsset(path);
|
|
19
9
|
}
|
|
20
|
-
export function
|
|
10
|
+
export function makeSourceStorage(source, key = "") {
|
|
21
11
|
const storage = createStorage();
|
|
22
12
|
const options = typeof source === "string" ? { driver: "fs", base: source } : source;
|
|
23
13
|
switch (options.driver) {
|
|
@@ -99,7 +89,7 @@ export function makeSourceManager(key, source, publicPath, callback) {
|
|
|
99
89
|
}
|
|
100
90
|
return paths;
|
|
101
91
|
}
|
|
102
|
-
const storage =
|
|
92
|
+
const storage = makeSourceStorage(source, key);
|
|
103
93
|
storage.watch(onWatch);
|
|
104
94
|
return {
|
|
105
95
|
storage,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { walkBody, walkMeta, buildQuery, readFile, writeFile } from "../utils/index.mjs";
|
|
2
|
+
export function rewriteContent(path, asset) {
|
|
3
|
+
const { parsed } = readFile(path, true);
|
|
4
|
+
const { srcAttr, width, height } = asset;
|
|
5
|
+
walkMeta(parsed, (value, parent, key) => {
|
|
6
|
+
if (value.startsWith(srcAttr)) {
|
|
7
|
+
parent[key] = parent[key].replace(/width=\d+&height=\d+/, `width=${width}&height=${height}`);
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
walkBody(parsed, function(node) {
|
|
11
|
+
const { tag, props } = node;
|
|
12
|
+
if (tag === "img" && props?.src?.startsWith(srcAttr)) {
|
|
13
|
+
props.src = buildQuery(srcAttr, `time=${Date.now()}`);
|
|
14
|
+
if (props.width) {
|
|
15
|
+
props.width = width;
|
|
16
|
+
}
|
|
17
|
+
if (props.height) {
|
|
18
|
+
props.height = height;
|
|
19
|
+
}
|
|
20
|
+
if (props.style) {
|
|
21
|
+
const ratio = `${width}/${height}`;
|
|
22
|
+
if (typeof props.style === "string") {
|
|
23
|
+
props.style = props.style.replace(/aspect-ratio: \d+\/\d+/, `aspect-ratio: ${ratio}`);
|
|
24
|
+
} else if (props.style.aspectRatio) {
|
|
25
|
+
props.style.aspectRatio = ratio;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
writeFile(path, { module: true, parsed });
|
|
31
|
+
return parsed;
|
|
32
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { buildQuery, buildStyle, isValidAsset, list, parseQuery, removeQuery, walkBody, walkMeta } from "../utils/index.mjs";
|
|
2
|
+
import { makeAssetsManager } from "../assets/public.mjs";
|
|
3
|
+
import { debug, imageFlags, publicPath } from "#nuxt-content-assets";
|
|
4
|
+
function processMeta(content, imageFlags2 = [], updated = []) {
|
|
5
|
+
walkMeta(content, (value, parent, key) => {
|
|
6
|
+
if (isValidAsset(value)) {
|
|
7
|
+
const { srcAttr, width, height } = resolveAsset(content, removeQuery(value), true);
|
|
8
|
+
if (srcAttr) {
|
|
9
|
+
const query = width && height && (imageFlags2.includes("src") || imageFlags2.includes("url")) ? `width=${width}&height=${height}` : "";
|
|
10
|
+
const srcUrl = query ? buildQuery(srcAttr, parseQuery(value), query) : srcAttr;
|
|
11
|
+
parent[key] = srcUrl;
|
|
12
|
+
updated.push(`meta: ${key} to "${srcUrl}"`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function processBody(content, imageFlags2 = [], updated = []) {
|
|
18
|
+
walkBody(content, function(node) {
|
|
19
|
+
const { tag, props } = node;
|
|
20
|
+
for (const [prop, value] of Object.entries(props)) {
|
|
21
|
+
if (typeof value !== "string") {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const { srcAttr, width, height } = resolveAsset(content, value, true);
|
|
25
|
+
if (srcAttr) {
|
|
26
|
+
node.props[prop] = srcAttr;
|
|
27
|
+
if (node.tag === "img") {
|
|
28
|
+
if (width && height) {
|
|
29
|
+
if (imageFlags2.includes("attrs")) {
|
|
30
|
+
node.props.width ||= width;
|
|
31
|
+
node.props.height ||= height;
|
|
32
|
+
}
|
|
33
|
+
if (imageFlags2.includes("style")) {
|
|
34
|
+
const ratio = `${width}/${height}`;
|
|
35
|
+
if (typeof node.props.style === "string") {
|
|
36
|
+
node.props.style = buildStyle(node.props.style, `aspect-ratio: ${ratio}`);
|
|
37
|
+
} else {
|
|
38
|
+
node.props.style ||= {};
|
|
39
|
+
node.props.style.aspectRatio = ratio;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} else if (node.tag === "a") {
|
|
44
|
+
node.props.target ||= "_blank";
|
|
45
|
+
}
|
|
46
|
+
updated.push(`page: ${tag}[${prop}] to "${srcAttr}"`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const { resolveAsset } = makeAssetsManager(publicPath);
|
|
52
|
+
const plugin = async (nitro) => {
|
|
53
|
+
nitro.hooks.hook("content:file:afterParse", function(content) {
|
|
54
|
+
if (content._extension === "md") {
|
|
55
|
+
const updated = [];
|
|
56
|
+
processMeta(content, imageFlags, updated);
|
|
57
|
+
processBody(content, imageFlags, updated);
|
|
58
|
+
if (debug && updated.length) {
|
|
59
|
+
list(`Processed "/${content._file}"`, updated);
|
|
60
|
+
console.log();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
export default plugin;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { Callback } from '../../types';
|
|
2
|
-
export
|
|
2
|
+
export interface Logger {
|
|
3
|
+
log: (...args: any[]) => void;
|
|
4
|
+
warn: (...args: any[]) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function createWebSocket(url: string, logger?: Logger): {
|
|
3
7
|
connect: (retry?: boolean) => void;
|
|
4
8
|
send: (data: any) => void;
|
|
5
9
|
addHandler(callback: Callback): void;
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import { useRuntimeConfig } from "#app";
|
|
2
|
-
const plugin = "[Content Assets]";
|
|
3
|
-
const logger = {
|
|
4
|
-
// eslint-disable-next-line no-console
|
|
5
|
-
log: (...args) => console.log(plugin, ...args),
|
|
6
|
-
// eslint-disable-next-line no-console
|
|
7
|
-
warn: (...args) => console.warn(plugin, ...args)
|
|
8
|
-
};
|
|
9
1
|
let ws;
|
|
10
|
-
|
|
2
|
+
function log(...args) {
|
|
3
|
+
}
|
|
4
|
+
export function createWebSocket(url, logger = { log, warn: log }) {
|
|
11
5
|
if (!window.WebSocket) {
|
|
12
6
|
logger.warn("Your browser does not support WebSocket");
|
|
13
7
|
return null;
|
|
@@ -47,7 +41,6 @@ export function createWebSocket() {
|
|
|
47
41
|
}
|
|
48
42
|
};
|
|
49
43
|
let retries = 0;
|
|
50
|
-
const url = useRuntimeConfig().public.sockets?.wsUrl;
|
|
51
44
|
const connect = (retry = false) => {
|
|
52
45
|
if (retry) {
|
|
53
46
|
retries++;
|
|
@@ -1,17 +1,40 @@
|
|
|
1
|
-
import { defineNuxtPlugin } from "#imports";
|
|
2
|
-
import { useSockets } from "./composable.mjs";
|
|
1
|
+
import { defineNuxtPlugin, refreshNuxtData, useRuntimeConfig } from "#imports";
|
|
3
2
|
export default defineNuxtPlugin(async () => {
|
|
4
3
|
if (process.client) {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
const url = useRuntimeConfig().public.sockets?.wsUrl;
|
|
5
|
+
const socket = await import("./setup").then(({ setupSocketClient }) => {
|
|
6
|
+
return setupSocketClient(url, "content-assets");
|
|
7
|
+
});
|
|
8
|
+
if (socket) {
|
|
9
|
+
socket.addHandler(({ data }) => {
|
|
10
|
+
const { event, src, width, height } = data;
|
|
11
|
+
if (event === "refresh") {
|
|
12
|
+
refreshNuxtData();
|
|
13
|
+
} else if (src) {
|
|
10
14
|
const isUpdate = event === "update";
|
|
11
15
|
document.querySelectorAll(`:is(img, video, source, embed, iframe):where([src^="${src}"])`).forEach((el) => {
|
|
12
16
|
el.style.opacity = isUpdate ? "1" : "0.2";
|
|
13
17
|
if (isUpdate) {
|
|
14
|
-
el.
|
|
18
|
+
const query = el.getAttribute("src").split("?")[1];
|
|
19
|
+
const params = new URLSearchParams(query);
|
|
20
|
+
params.set("time", String(Date.now()));
|
|
21
|
+
if (width && height) {
|
|
22
|
+
el.addEventListener("load", function onLoad() {
|
|
23
|
+
if (el.width && el.height) {
|
|
24
|
+
el.setAttribute("width", width);
|
|
25
|
+
el.setAttribute("height", height);
|
|
26
|
+
}
|
|
27
|
+
if (el.style.aspectRatio) {
|
|
28
|
+
el.style.aspectRatio = `${width} / ${height}`;
|
|
29
|
+
}
|
|
30
|
+
if (params.get("width")) {
|
|
31
|
+
params.set("width", width);
|
|
32
|
+
params.set("height", height);
|
|
33
|
+
}
|
|
34
|
+
el.removeEventListener("load", onLoad);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
el.setAttribute("src", `${src}?${params.toString()}`);
|
|
15
38
|
}
|
|
16
39
|
});
|
|
17
40
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Callback, SocketInstance } from '../../types';
|
|
2
|
-
export declare function setupSocketClient(channel: string, callback?: Callback): SocketInstance | null;
|
|
2
|
+
export declare function setupSocketClient(url: string, channel: string, callback?: Callback): SocketInstance | null;
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { createWebSocket } from "./factory.mjs";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
let client;
|
|
3
|
+
const plugin = "[Content Assets]";
|
|
4
|
+
const logger = {
|
|
5
|
+
// eslint-disable-next-line no-console
|
|
6
|
+
log: (...args) => console.log(plugin, ...args),
|
|
7
|
+
// eslint-disable-next-line no-console
|
|
8
|
+
warn: (...args) => console.warn(plugin, ...args)
|
|
9
|
+
};
|
|
10
|
+
export function setupSocketClient(url, channel, callback) {
|
|
11
|
+
if (!client) {
|
|
12
|
+
client = createWebSocket(url, logger);
|
|
13
|
+
if (client === null) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
4
17
|
const instance = {
|
|
5
18
|
addHandler(callback2) {
|
|
6
19
|
if (client && typeof callback2 === "function") {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { matchTokens } from "./string.mjs";
|
|
2
|
+
export const extensions = {
|
|
3
|
+
// used to get image size
|
|
4
|
+
image: matchTokens("png jpg jpeg gif svg webp ico"),
|
|
5
|
+
// unused for now
|
|
6
|
+
media: matchTokens("mp3 m4a wav mp4 mov webm ogg avi flv avchd")
|
|
7
|
+
};
|
|
8
|
+
export function makeIgnores(extensions2) {
|
|
9
|
+
const matched = matchTokens(extensions2);
|
|
10
|
+
const ignored = matched.join("|");
|
|
11
|
+
return `[^:]+\\.(?!(${ignored})$)`;
|
|
12
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ParsedContent } from '../../types';
|
|
2
|
+
import { WalkCallback } from './object';
|
|
3
|
+
/**
|
|
4
|
+
* Walk parsed content meta, only processing relevant properties
|
|
5
|
+
*
|
|
6
|
+
* @param content
|
|
7
|
+
* @param callback
|
|
8
|
+
*/
|
|
9
|
+
export declare function walkMeta(content: ParsedContent, callback: WalkCallback): void;
|
|
10
|
+
/**
|
|
11
|
+
* Walk parsed content body, only visiting relevant tags
|
|
12
|
+
*
|
|
13
|
+
* @param content
|
|
14
|
+
* @param callback
|
|
15
|
+
*/
|
|
16
|
+
export declare function walkBody(content: ParsedContent, callback: (node: any) => void): void;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { CONTINUE, SKIP, visit } from "unist-util-visit";
|
|
2
|
+
import { walk } from "./object.mjs";
|
|
3
|
+
import { matchTokens } from "./string.mjs";
|
|
4
|
+
export function walkMeta(content, callback) {
|
|
5
|
+
walk(content, callback, (value, key) => !(String(key).startsWith("_") || key === "body"));
|
|
6
|
+
}
|
|
7
|
+
export function walkBody(content, callback) {
|
|
8
|
+
visit(content.body, (node) => node.type === "element", (node) => {
|
|
9
|
+
const { tag, props } = node;
|
|
10
|
+
const excluded = tags.exclude.includes(tag);
|
|
11
|
+
if (excluded) {
|
|
12
|
+
return SKIP;
|
|
13
|
+
}
|
|
14
|
+
const included = tags.include.includes(tag);
|
|
15
|
+
if (included || !props) {
|
|
16
|
+
return CONTINUE;
|
|
17
|
+
}
|
|
18
|
+
callback(node);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const tags = {
|
|
22
|
+
// unlikely to contain assets
|
|
23
|
+
exclude: matchTokens({
|
|
24
|
+
container: "pre code code-inline",
|
|
25
|
+
formatting: "acronym abbr address bdi bdo big center cite del dfn font ins kbd mark meter progress q rp rt ruby s samp small strike sub sup time tt u var wbr",
|
|
26
|
+
headers: "h1 h2 h3 h4 h5 h6",
|
|
27
|
+
controls: "input textarea button select optgroup option label legend datalist output",
|
|
28
|
+
media: "map area canvas svg",
|
|
29
|
+
other: "style script noscript template",
|
|
30
|
+
empty: "hr br"
|
|
31
|
+
}),
|
|
32
|
+
// may contain assets
|
|
33
|
+
include: matchTokens({
|
|
34
|
+
content: "main header footer section article aside details dialog summary data object nav blockquote div span p",
|
|
35
|
+
table: "table caption th tr td thead tbody tfoot col colgroup",
|
|
36
|
+
media: "figcaption figure picture",
|
|
37
|
+
form: "form fieldset",
|
|
38
|
+
list: "ul ol li dir dl dt dd",
|
|
39
|
+
formatting: "strong b em i"
|
|
40
|
+
}),
|
|
41
|
+
// assets
|
|
42
|
+
assets: "a img audio source track video embed"
|
|
43
|
+
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
export type
|
|
2
|
-
|
|
1
|
+
export type Walkable = {
|
|
2
|
+
[key: string | number]: any;
|
|
3
|
+
};
|
|
4
|
+
export type WalkFilter = (value: any, key?: string | number) => boolean | void;
|
|
5
|
+
export type WalkCallback = (value: any, parent: Walkable, key: string | number) => void;
|
|
3
6
|
/**
|
|
4
7
|
* Walk an object structure
|
|
5
8
|
*
|
|
@@ -7,4 +10,5 @@ export type Filter = (value: any, key?: string | number) => boolean | void;
|
|
|
7
10
|
* @param callback
|
|
8
11
|
* @param filter
|
|
9
12
|
*/
|
|
10
|
-
export declare function walk(node: any, callback:
|
|
13
|
+
export declare function walk(node: any, callback: WalkCallback, filter?: WalkFilter): void;
|
|
14
|
+
export declare function isObject(data: any): any;
|
|
@@ -10,7 +10,7 @@ export function walk(node, callback, filter) {
|
|
|
10
10
|
node2.forEach((value, index) => {
|
|
11
11
|
visit(value, callback2, node2, index);
|
|
12
12
|
});
|
|
13
|
-
} else if (
|
|
13
|
+
} else if (isObject(node2)) {
|
|
14
14
|
Object.keys(node2).forEach((key2) => {
|
|
15
15
|
visit(node2[key2], callback2, node2, key2);
|
|
16
16
|
});
|
|
@@ -18,5 +18,8 @@ export function walk(node, callback, filter) {
|
|
|
18
18
|
callback2(node2, parent, key);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
visit(node, callback);
|
|
21
|
+
visit(node, callback, { node }, "node");
|
|
22
|
+
}
|
|
23
|
+
export function isObject(data) {
|
|
24
|
+
return data && typeof data === "object" && !Array.isArray(data);
|
|
22
25
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import { } from './module'
|
|
3
3
|
|
|
4
|
-
declare module '@nuxt/schema' {
|
|
5
|
-
interface NuxtConfig { ['contentAssets']?: Partial<ModuleOptions> }
|
|
6
|
-
interface NuxtOptions { ['contentAssets']?: ModuleOptions }
|
|
7
|
-
}
|
|
8
4
|
|
|
9
5
|
|
|
10
|
-
export {
|
|
6
|
+
export { default } from './module'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-content-assets",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Enable locally-located assets in Nuxt Content",
|
|
5
5
|
"repository": "davestewart/nuxt-content-assets",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,17 +41,15 @@
|
|
|
41
41
|
"ws": "^8.13.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@nuxt/content": "
|
|
44
|
+
"@nuxt/content": ">=2.6 || <3.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@nuxt/content": "latest",
|
|
48
47
|
"@nuxt/eslint-config": "^0.1.1",
|
|
49
48
|
"@nuxt/module-builder": "^0.2.1",
|
|
50
49
|
"@nuxt/schema": "^3.3.2",
|
|
51
50
|
"@nuxt/test-utils": "^3.3.2",
|
|
52
51
|
"@types/debounce": "^1.2.1",
|
|
53
52
|
"@types/ws": "^8.5.4",
|
|
54
|
-
"changelogen": "^0.5.1",
|
|
55
53
|
"eslint": "^8.36.0",
|
|
56
54
|
"nuxt": "^3.3.2",
|
|
57
55
|
"vitest": "^0.29.7"
|
package/dist/runtime/config.d.ts
DELETED
package/dist/runtime/config.mjs
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare const defaults: {
|
|
2
|
-
imageSize: string;
|
|
3
|
-
contentExtensions: string;
|
|
4
|
-
debug: boolean;
|
|
5
|
-
};
|
|
6
|
-
export declare const extensions: {
|
|
7
|
-
image: string[];
|
|
8
|
-
media: string[];
|
|
9
|
-
};
|
|
10
|
-
export declare function getIgnores(extensions: string | string[]): string;
|