nuxt-content-assets 0.7.0 → 0.9.0-alpha
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 +45 -141
- package/dist/module.d.ts +0 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +275 -163
- package/dist/runtime/options.d.ts +4 -4
- package/dist/runtime/options.mjs +4 -8
- package/dist/runtime/plugin.mjs +15 -3
- package/dist/runtime/services/assets.d.ts +1 -1
- package/dist/runtime/services/assets.mjs +2 -3
- package/dist/runtime/services/sockets/client.d.ts +2 -0
- package/dist/runtime/services/sockets/client.mjs +9 -0
- package/dist/runtime/services/sockets/composable.d.ts +4 -0
- package/dist/runtime/services/sockets/composable.mjs +77 -0
- package/dist/runtime/services/sockets/server.d.ts +23 -0
- package/dist/runtime/services/sockets/server.mjs +78 -0
- package/dist/runtime/services/sources.d.ts +22 -10
- package/dist/runtime/services/sources.mjs +85 -32
- package/dist/runtime/utils/assert.d.ts +7 -3
- package/dist/runtime/utils/assert.mjs +7 -4
- package/dist/runtime/utils/fs.d.ts +3 -0
- package/dist/runtime/utils/fs.mjs +12 -0
- package/dist/runtime/utils/string.d.ts +3 -0
- package/dist/runtime/utils/string.mjs +9 -0
- package/dist/runtime/watcher.d.ts +2 -0
- package/dist/runtime/watcher.mjs +18 -0
- package/package.json +8 -2
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
let ws;
|
|
10
|
+
export function useSocket(channel, callback) {
|
|
11
|
+
if (!window.WebSocket) {
|
|
12
|
+
logger.warn("Unable to hot-reload images, your browser does not support WebSocket");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const onOpen = () => logger.log("WS connected!");
|
|
16
|
+
const onError = (e) => {
|
|
17
|
+
switch (e.code) {
|
|
18
|
+
case "ECONNREFUSED":
|
|
19
|
+
connect(true);
|
|
20
|
+
break;
|
|
21
|
+
default:
|
|
22
|
+
logger.warn("WS Error:", e);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const onClose = (e) => {
|
|
27
|
+
if (e.code === 1e3 || e.code === 1005) {
|
|
28
|
+
logger.log("WS closed!");
|
|
29
|
+
} else {
|
|
30
|
+
connect(true);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const onMessage = (message) => {
|
|
34
|
+
try {
|
|
35
|
+
const data = JSON.parse(message.data);
|
|
36
|
+
if (channel === data.channel) {
|
|
37
|
+
return callback(data);
|
|
38
|
+
}
|
|
39
|
+
} catch (err) {
|
|
40
|
+
logger.warn("Error parsing message:", message.data);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const send = (data) => {
|
|
44
|
+
if (ws) {
|
|
45
|
+
ws.send(JSON.stringify({ channel, data }));
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const connect = (retry = false) => {
|
|
49
|
+
if (retry) {
|
|
50
|
+
logger.log("WS reconnecting..");
|
|
51
|
+
setTimeout(connect, 1e3);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (ws) {
|
|
55
|
+
try {
|
|
56
|
+
ws.close();
|
|
57
|
+
} catch (err) {
|
|
58
|
+
}
|
|
59
|
+
ws = void 0;
|
|
60
|
+
}
|
|
61
|
+
const url = useRuntimeConfig().public.sockets?.wsUrl;
|
|
62
|
+
if (url) {
|
|
63
|
+
const wsUrl = `${url}ws`;
|
|
64
|
+
logger.log(`watching for image updates on ${wsUrl}`);
|
|
65
|
+
ws = new WebSocket(wsUrl);
|
|
66
|
+
ws.onopen = onOpen;
|
|
67
|
+
ws.onmessage = onMessage;
|
|
68
|
+
ws.onerror = onError;
|
|
69
|
+
ws.onclose = onClose;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
connect();
|
|
73
|
+
return {
|
|
74
|
+
connect,
|
|
75
|
+
send
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="ws" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import type { IncomingMessage } from 'http';
|
|
4
|
+
import { Nuxt } from '@nuxt/schema';
|
|
5
|
+
export type Callback = (data: any) => void;
|
|
6
|
+
export type Handler = {
|
|
7
|
+
channel: string;
|
|
8
|
+
callback: Callback;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* WebSocket server useful for live content reload.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createWebSocket(): {
|
|
14
|
+
wss: import("ws").Server<import("ws").WebSocket>;
|
|
15
|
+
serve: (req: IncomingMessage, socket?: import("net").Socket, head?: any) => void;
|
|
16
|
+
broadcast: (data: any, channel?: string) => void;
|
|
17
|
+
onMessage: (channel: string, callback: Callback) => void;
|
|
18
|
+
close: () => Promise<unknown>;
|
|
19
|
+
};
|
|
20
|
+
export declare function useSocketServer(nuxt: Nuxt, channel: string, onMessage?: Callback): {
|
|
21
|
+
send(data: any): any;
|
|
22
|
+
onMessage(callback: Callback): any;
|
|
23
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { WebSocketServer } from "ws";
|
|
2
|
+
import { listen } from "listhen";
|
|
3
|
+
export function createWebSocket() {
|
|
4
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
5
|
+
const serve = (req, socket = req.socket, head = "") => wss.handleUpgrade(req, socket, head, (client) => wss.emit("connection", client, req));
|
|
6
|
+
const broadcast = (data, channel = "*") => {
|
|
7
|
+
data = JSON.stringify({ channel, data });
|
|
8
|
+
for (const client of wss.clients) {
|
|
9
|
+
try {
|
|
10
|
+
client.send(data);
|
|
11
|
+
} catch (err) {
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const handlers = [];
|
|
16
|
+
const onMessage = (channel, callback) => {
|
|
17
|
+
handlers.push({ channel, callback });
|
|
18
|
+
};
|
|
19
|
+
wss.on("connection", (client) => {
|
|
20
|
+
client.addEventListener("message", (event) => {
|
|
21
|
+
try {
|
|
22
|
+
const { channel, data } = JSON.parse(event.data || "{}");
|
|
23
|
+
handlers.filter((handler) => handler.channel === channel || handler.channel === "*").forEach((handler) => handler.callback(data));
|
|
24
|
+
} catch (err) {
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
wss,
|
|
30
|
+
serve,
|
|
31
|
+
broadcast,
|
|
32
|
+
onMessage,
|
|
33
|
+
close: () => {
|
|
34
|
+
wss.clients.forEach((client) => client.close());
|
|
35
|
+
return new Promise((resolve) => wss.close(resolve));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const ws = createWebSocket();
|
|
40
|
+
let initialized = false;
|
|
41
|
+
const defaults = {
|
|
42
|
+
port: {
|
|
43
|
+
port: 4001,
|
|
44
|
+
portRange: [4001, 4040]
|
|
45
|
+
},
|
|
46
|
+
hostname: "localhost",
|
|
47
|
+
showURL: false
|
|
48
|
+
};
|
|
49
|
+
export function useSocketServer(nuxt, channel, onMessage) {
|
|
50
|
+
nuxt.hook("nitro:init", async (nitro) => {
|
|
51
|
+
if (!initialized) {
|
|
52
|
+
initialized = true;
|
|
53
|
+
const { server, url } = await listen(() => "Nuxt Sockets", defaults);
|
|
54
|
+
server.on("upgrade", ws.serve);
|
|
55
|
+
nitro.options.runtimeConfig.public.sockets = {
|
|
56
|
+
wsUrl: url.replace("http", "ws")
|
|
57
|
+
};
|
|
58
|
+
nitro.hooks.hook("close", async () => {
|
|
59
|
+
await ws.close();
|
|
60
|
+
await server.close();
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const instance = {
|
|
65
|
+
send(data) {
|
|
66
|
+
ws.broadcast(data, channel);
|
|
67
|
+
return this;
|
|
68
|
+
},
|
|
69
|
+
onMessage(callback) {
|
|
70
|
+
ws.onMessage(channel, callback);
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
if (onMessage) {
|
|
75
|
+
instance.onMessage(onMessage);
|
|
76
|
+
}
|
|
77
|
+
return instance;
|
|
78
|
+
}
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { WatchEvent, Storage } from 'unstorage';
|
|
2
|
+
import { MountOptions } from '@nuxt/content';
|
|
3
|
+
/**
|
|
4
|
+
* Make a Storage instance
|
|
5
|
+
*/
|
|
6
|
+
export declare function makeStorage(source: MountOptions | string, key?: string): Storage;
|
|
7
|
+
export interface SourceManager {
|
|
8
|
+
storage: Storage;
|
|
9
|
+
init: () => Promise<string[]>;
|
|
10
|
+
keys: () => Promise<string[]>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Make a SourceManager instance
|
|
14
|
+
*
|
|
15
|
+
* Each Source Manager is responsible for mirroring source files to the public folder
|
|
16
|
+
*
|
|
17
|
+
* @param key
|
|
18
|
+
* @param source
|
|
19
|
+
* @param publicPath
|
|
20
|
+
* @param callback
|
|
21
|
+
*/
|
|
22
|
+
export declare function makeSourceManager(key: string, source: MountOptions, publicPath: string, callback?: (event: WatchEvent, path: string) => void): SourceManager;
|
|
@@ -1,39 +1,92 @@
|
|
|
1
|
-
import * as Fs from "fs";
|
|
2
1
|
import * as Path from "path";
|
|
3
|
-
import glob from "glob";
|
|
4
2
|
import { createStorage } from "unstorage";
|
|
5
3
|
import githubDriver from "unstorage/drivers/github";
|
|
6
|
-
|
|
4
|
+
import fsDriver from "unstorage/drivers/fs";
|
|
5
|
+
import { warn, isAsset, toPath, removeFile, copyFile, writeBlob, writeFile, deKey } from "../utils/index.mjs";
|
|
6
|
+
export function makeStorage(source, key = "") {
|
|
7
7
|
const storage = createStorage();
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
for (const { id, data } of assetItems) {
|
|
24
|
-
if (data) {
|
|
25
|
-
const path = id.replaceAll(":", "/");
|
|
26
|
-
const absPath = Path.join(tempPath, path.replace(key, `${key}/${prefix}`));
|
|
27
|
-
const absFolder = Path.dirname(absPath);
|
|
28
|
-
const buffer = data.constructor.name === "Blob" ? Buffer.from(await data.arrayBuffer()) : typeof data === "object" ? JSON.stringify(data, null, " ") : String(data);
|
|
29
|
-
Fs.mkdirSync(absFolder, { recursive: true });
|
|
30
|
-
Fs.writeFileSync(absPath, buffer);
|
|
31
|
-
paths.push(absPath);
|
|
32
|
-
}
|
|
8
|
+
const options = typeof source === "string" ? { driver: "fs", base: source } : source;
|
|
9
|
+
switch (options.driver) {
|
|
10
|
+
case "fs":
|
|
11
|
+
storage.mount(key, fsDriver({
|
|
12
|
+
...options,
|
|
13
|
+
ignore: ["[^:]+?\\.md"]
|
|
14
|
+
}));
|
|
15
|
+
break;
|
|
16
|
+
case "github":
|
|
17
|
+
storage.mount(key, githubDriver({
|
|
18
|
+
branch: "main",
|
|
19
|
+
dir: "/",
|
|
20
|
+
...options
|
|
21
|
+
}));
|
|
22
|
+
break;
|
|
33
23
|
}
|
|
34
|
-
return
|
|
24
|
+
return storage;
|
|
35
25
|
}
|
|
36
|
-
export function
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
export function makeSourceManager(key, source, publicPath, callback) {
|
|
27
|
+
async function onWatch(event, key2) {
|
|
28
|
+
if (isAsset(key2)) {
|
|
29
|
+
const path = event === "update" ? await copyItem(key2) : removeItem(key2);
|
|
30
|
+
if (callback) {
|
|
31
|
+
callback(event, path);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function getRelSrc(key2) {
|
|
36
|
+
return toPath(key2).replace(/\w+/, "").replace(source.prefix || "", "");
|
|
37
|
+
}
|
|
38
|
+
function getAbsSrc(key2) {
|
|
39
|
+
return Path.join(source.base, getRelSrc(key2));
|
|
40
|
+
}
|
|
41
|
+
function getRelTrg(key2) {
|
|
42
|
+
return Path.join(source.prefix || "", toPath(deKey(key2)));
|
|
43
|
+
}
|
|
44
|
+
function getAbsTrg(key2) {
|
|
45
|
+
return Path.join(publicPath, getRelTrg(key2));
|
|
46
|
+
}
|
|
47
|
+
function removeItem(key2) {
|
|
48
|
+
const absTrg = getAbsTrg(key2);
|
|
49
|
+
removeFile(absTrg);
|
|
50
|
+
return absTrg;
|
|
51
|
+
}
|
|
52
|
+
async function copyItem(key2) {
|
|
53
|
+
const absTrg = getAbsTrg(key2);
|
|
54
|
+
const driver = source.driver;
|
|
55
|
+
if (driver === "fs") {
|
|
56
|
+
const absSrc = getAbsSrc(key2);
|
|
57
|
+
copyFile(absSrc, absTrg);
|
|
58
|
+
} else if (driver === "github") {
|
|
59
|
+
try {
|
|
60
|
+
const data = await storage.getItem(key2);
|
|
61
|
+
if (data) {
|
|
62
|
+
data?.constructor.name === "Blob" ? await writeBlob(absTrg, data) : writeFile(absTrg, data);
|
|
63
|
+
} else {
|
|
64
|
+
warn(`No data for key "${key2}"`);
|
|
65
|
+
}
|
|
66
|
+
} catch (err) {
|
|
67
|
+
warn(err.message);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return absTrg;
|
|
71
|
+
}
|
|
72
|
+
async function getKeys() {
|
|
73
|
+
const keys = await storage.getKeys();
|
|
74
|
+
return keys.filter(isAsset);
|
|
75
|
+
}
|
|
76
|
+
async function init() {
|
|
77
|
+
const keys = await getKeys();
|
|
78
|
+
const paths = [];
|
|
79
|
+
for (const key2 of keys) {
|
|
80
|
+
const path = await copyItem(key2);
|
|
81
|
+
paths.push(path);
|
|
82
|
+
}
|
|
83
|
+
return paths;
|
|
84
|
+
}
|
|
85
|
+
const storage = makeStorage(source, key);
|
|
86
|
+
storage.watch(onWatch);
|
|
87
|
+
return {
|
|
88
|
+
storage,
|
|
89
|
+
init,
|
|
90
|
+
keys: getKeys
|
|
91
|
+
};
|
|
39
92
|
}
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare function isRelative(path: string): boolean;
|
|
5
5
|
/**
|
|
6
|
-
* Test path for image extension
|
|
6
|
+
* Test path or id for image extension
|
|
7
7
|
*/
|
|
8
8
|
export declare function isImage(path: string): boolean;
|
|
9
9
|
/**
|
|
10
|
-
* Test path
|
|
10
|
+
* Test path or id is markdown
|
|
11
|
+
*/
|
|
12
|
+
export declare function isArticle(path: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Test path or id is asset
|
|
11
15
|
*/
|
|
12
16
|
export declare function isAsset(path: string): boolean;
|
|
13
17
|
/**
|
|
14
|
-
* Test if value is a
|
|
18
|
+
* Test if value is a relative asset
|
|
15
19
|
*/
|
|
16
20
|
export declare function isValidAsset(value?: string): boolean;
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import Path from "path";
|
|
2
|
-
import { extensions
|
|
2
|
+
import { extensions } from "../options.mjs";
|
|
3
3
|
export function isRelative(path) {
|
|
4
4
|
return !(path.startsWith("http") || Path.isAbsolute(path));
|
|
5
5
|
}
|
|
6
6
|
export function isImage(path) {
|
|
7
7
|
const ext = Path.extname(path).substring(1);
|
|
8
|
-
return
|
|
8
|
+
return extensions.image.includes(ext);
|
|
9
|
+
}
|
|
10
|
+
export function isArticle(path) {
|
|
11
|
+
return /\.mdx?$/.test(path);
|
|
9
12
|
}
|
|
10
13
|
export function isAsset(path) {
|
|
11
|
-
const ext = Path.extname(path)
|
|
12
|
-
return
|
|
14
|
+
const ext = Path.extname(path);
|
|
15
|
+
return !!ext && ext !== ".DS_Store" && !isArticle(path);
|
|
13
16
|
}
|
|
14
17
|
export function isValidAsset(value) {
|
|
15
18
|
return typeof value === "string" && isAsset(value) && isRelative(value);
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
export declare function readFile(path: string, asJson?: boolean): any;
|
|
1
2
|
export declare function writeFile(path: string, data: null | string | number | boolean | object): void;
|
|
3
|
+
export declare function writeBlob(path: string, data: object): Promise<void>;
|
|
2
4
|
export declare function copyFile(src: string, trg: string): void;
|
|
5
|
+
export declare function removeFile(src: string): void;
|
|
3
6
|
export declare function createFolder(path: string): void;
|
|
4
7
|
export declare function removeFolder(path: string): void;
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
import * as Path from "path";
|
|
2
2
|
import * as Fs from "fs";
|
|
3
|
+
export function readFile(path, asJson = false) {
|
|
4
|
+
const text = Fs.readFileSync(path, { encoding: "utf8" });
|
|
5
|
+
return asJson ? JSON.parse(text) : text;
|
|
6
|
+
}
|
|
3
7
|
export function writeFile(path, data) {
|
|
4
8
|
const text = typeof data === "object" ? JSON.stringify(data, null, " ") : String(data);
|
|
5
9
|
createFolder(Path.dirname(path));
|
|
6
10
|
Fs.writeFileSync(path, text, { encoding: "utf8" });
|
|
7
11
|
}
|
|
12
|
+
export async function writeBlob(path, data) {
|
|
13
|
+
const buffer = Buffer.from(await data.arrayBuffer());
|
|
14
|
+
createFolder(Path.dirname(path));
|
|
15
|
+
Fs.writeFileSync(path, buffer);
|
|
16
|
+
}
|
|
8
17
|
export function copyFile(src, trg) {
|
|
9
18
|
createFolder(Path.dirname(trg));
|
|
10
19
|
Fs.copyFileSync(src, trg);
|
|
11
20
|
}
|
|
21
|
+
export function removeFile(src) {
|
|
22
|
+
Fs.rmSync(src);
|
|
23
|
+
}
|
|
12
24
|
export function createFolder(path) {
|
|
13
25
|
Fs.mkdirSync(path, { recursive: true });
|
|
14
26
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
export function matchWords(value) {
|
|
2
2
|
return typeof value === "string" ? value.match(/\w+/g) || [] : [];
|
|
3
3
|
}
|
|
4
|
+
export function toPath(key) {
|
|
5
|
+
return key.replaceAll(":", "/");
|
|
6
|
+
}
|
|
7
|
+
export function toKey(path) {
|
|
8
|
+
return path.replaceAll("/", ":");
|
|
9
|
+
}
|
|
10
|
+
export function deKey(path) {
|
|
11
|
+
return path.replace(/^[^:]+:/, "");
|
|
12
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineNuxtPlugin } from "#imports";
|
|
2
|
+
import { useSocketClient } from "./services/sockets/client.mjs";
|
|
3
|
+
export default defineNuxtPlugin(async () => {
|
|
4
|
+
if (process.client) {
|
|
5
|
+
void useSocketClient("content-assets", ({ data }) => {
|
|
6
|
+
const { event, src } = data;
|
|
7
|
+
if (src) {
|
|
8
|
+
const isUpdate = event === "update";
|
|
9
|
+
document.querySelectorAll(`img[src^="${src}"]`).forEach((img) => {
|
|
10
|
+
img.style.opacity = isUpdate ? "1" : "0.2";
|
|
11
|
+
if (isUpdate) {
|
|
12
|
+
img.setAttribute("src", src);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-content-assets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0-alpha",
|
|
4
4
|
"description": "Enable locally-located assets in Nuxt Content",
|
|
5
5
|
"repository": "davestewart/nuxt-content-assets",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,12 +31,16 @@
|
|
|
31
31
|
"release:dry": "npm run lint && npm run test && npm run build && npm publish --dry-run"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@davestewart/nuxt-sockets": "^0.1.0",
|
|
34
35
|
"@nuxt/kit": "^3.3.2",
|
|
36
|
+
"debounce": "^1.2.1",
|
|
35
37
|
"glob": "^9.3.2",
|
|
36
38
|
"image-size": "^1.0.2",
|
|
39
|
+
"listhen": "^1.0.4",
|
|
37
40
|
"ohash": "^1.0.0",
|
|
38
41
|
"unist-util-visit": "^4.1.2",
|
|
39
|
-
"unstorage": "^1.4.1"
|
|
42
|
+
"unstorage": "^1.4.1",
|
|
43
|
+
"ws": "^8.13.0"
|
|
40
44
|
},
|
|
41
45
|
"peerDependencies": {
|
|
42
46
|
"@nuxt/content": "latest"
|
|
@@ -47,6 +51,8 @@
|
|
|
47
51
|
"@nuxt/module-builder": "^0.2.1",
|
|
48
52
|
"@nuxt/schema": "^3.3.2",
|
|
49
53
|
"@nuxt/test-utils": "^3.3.2",
|
|
54
|
+
"@types/debounce": "^1.2.1",
|
|
55
|
+
"@types/ws": "^8.5.4",
|
|
50
56
|
"changelogen": "^0.5.1",
|
|
51
57
|
"eslint": "^8.36.0",
|
|
52
58
|
"nuxt": "^3.3.2",
|