mirror of
https://github.com/ajnart/homarr.git
synced 2026-02-26 16:30:57 +01:00
feat: add trpc websocket (#205)
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
"name": "@homarr/nextjs",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "pnpm with-env next build",
|
||||
"clean": "git clean -xdf .next .turbo node_modules",
|
||||
@@ -38,7 +39,7 @@
|
||||
"@tiptap/extension-link": "^2.2.4",
|
||||
"@tiptap/react": "^2.2.4",
|
||||
"@tiptap/starter-kit": "^2.2.4",
|
||||
"@trpc/client": "next",
|
||||
"@trpc/client": "11.0.0-next-beta.316",
|
||||
"@trpc/next": "next",
|
||||
"@trpc/react-query": "next",
|
||||
"@trpc/server": "next",
|
||||
@@ -63,8 +64,10 @@
|
||||
"@types/react-dom": "^18.2.22",
|
||||
"@types/chroma-js": "2.4.4",
|
||||
"dotenv-cli": "^7.4.1",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^8.57.0",
|
||||
"prettier": "^3.2.5",
|
||||
"tsx": "^4.7.1",
|
||||
"typescript": "^5.4.2"
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
||||
@@ -5,11 +5,21 @@ import { useState } from "react";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||
import { ReactQueryStreamedHydration } from "@tanstack/react-query-next-experimental";
|
||||
import { loggerLink, unstable_httpBatchStreamLink } from "@trpc/client";
|
||||
import {
|
||||
createWSClient,
|
||||
loggerLink,
|
||||
unstable_httpBatchStreamLink,
|
||||
wsLink,
|
||||
} from "@trpc/client";
|
||||
import superjson from "superjson";
|
||||
|
||||
import type { AppRouter } from "@homarr/api";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
|
||||
const wsClient = createWSClient({
|
||||
url: "ws://localhost:3001",
|
||||
});
|
||||
|
||||
export function TRPCReactProvider(props: PropsWithChildren) {
|
||||
const [queryClient] = useState(
|
||||
() =>
|
||||
@@ -22,26 +32,39 @@ export function TRPCReactProvider(props: PropsWithChildren) {
|
||||
}),
|
||||
);
|
||||
|
||||
const [trpcClient] = useState(() =>
|
||||
clientApi.createClient({
|
||||
const [trpcClient] = useState(() => {
|
||||
return clientApi.createClient({
|
||||
links: [
|
||||
loggerLink({
|
||||
enabled: (opts) =>
|
||||
process.env.NODE_ENV === "development" ||
|
||||
(opts.direction === "down" && opts.result instanceof Error),
|
||||
}),
|
||||
unstable_httpBatchStreamLink({
|
||||
transformer: superjson,
|
||||
url: getBaseUrl() + "/api/trpc",
|
||||
headers() {
|
||||
const headers = new Headers();
|
||||
headers.set("x-trpc-source", "nextjs-react");
|
||||
return headers;
|
||||
},
|
||||
}),
|
||||
(args) => {
|
||||
return ({ op, next }) => {
|
||||
console.log("op", op.type, op.input, op.path, op.id);
|
||||
if (op.type === "subscription") {
|
||||
const link = wsLink<AppRouter>({
|
||||
client: wsClient,
|
||||
transformer: superjson,
|
||||
});
|
||||
return link(args)({ op, next });
|
||||
}
|
||||
|
||||
return unstable_httpBatchStreamLink({
|
||||
transformer: superjson,
|
||||
url: `${getBaseUrl()}/api/trpc`,
|
||||
headers() {
|
||||
const headers = new Headers();
|
||||
headers.set("x-trpc-source", "nextjs-react");
|
||||
return headers;
|
||||
},
|
||||
})(args)({ op, next });
|
||||
};
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<clientApi.Provider client={trpcClient} queryClient={queryClient}>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { getScopedI18n } from "@homarr/translation/server";
|
||||
import { Title } from "@homarr/ui";
|
||||
|
||||
import { Test } from "./test";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getScopedI18n("management");
|
||||
const metaTitle = `${t("metaTitle")} • Homarr`;
|
||||
@@ -24,6 +26,7 @@ export default async function ManagementPage() {
|
||||
return (
|
||||
<>
|
||||
<Title>{t(timeOfDay, { username: "admin" })}</Title>
|
||||
<Test />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
23
apps/nextjs/src/app/[locale]/manage/test.tsx
Normal file
23
apps/nextjs/src/app/[locale]/manage/test.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { Stack, Text } from "@homarr/ui";
|
||||
|
||||
export const Test = () => {
|
||||
const [value, setValue] = useState<number>(0);
|
||||
clientApi.user.test.useSubscription(undefined, {
|
||||
onData(data) {
|
||||
setValue(data);
|
||||
},
|
||||
onError(err) {
|
||||
alert(err);
|
||||
},
|
||||
});
|
||||
return (
|
||||
<Stack>
|
||||
<Text>This will change after one second: {value}</Text>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
|
||||
|
||||
import { appRouter, createTRPCContext } from "@homarr/api";
|
||||
import { auth } from "@homarr/auth";
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
/**
|
||||
* Configure basic CORS headers
|
||||
@@ -29,8 +30,10 @@ const handler = auth(async (req) => {
|
||||
req,
|
||||
createContext: () =>
|
||||
createTRPCContext({ session: req.auth, headers: req.headers }),
|
||||
onError({ error, path }) {
|
||||
console.error(`>>> tRPC Error on '${path}'`, error);
|
||||
onError({ error, path, type }) {
|
||||
logger.error(
|
||||
`tRPC Error with ${type} on '${path}': (${error.code}) - ${error.message}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"main": "./index.ts",
|
||||
"types": "./index.ts",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "pnpm tsx ./src/wssDevServer.ts",
|
||||
"clean": "rm -rf .turbo node_modules",
|
||||
"lint": "eslint .",
|
||||
"format": "prettier --check . --ignore-path ../../.gitignore",
|
||||
@@ -18,17 +20,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@homarr/auth": "workspace:^0.1.0",
|
||||
"@homarr/definitions": "workspace:^0.1.0",
|
||||
"@homarr/db": "workspace:^0.1.0",
|
||||
"@homarr/definitions": "workspace:^0.1.0",
|
||||
"@homarr/log": "workspace:^",
|
||||
"@homarr/validation": "workspace:^0.1.0",
|
||||
"@trpc/client": "next",
|
||||
"@trpc/server": "next",
|
||||
"superjson": "2.2.1"
|
||||
"superjson": "2.2.1",
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||
"@types/ws": "^8.5.10",
|
||||
"eslint": "^8.57.0",
|
||||
"prettier": "^3.2.5",
|
||||
"typescript": "^5.4.2"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import "server-only";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { observable } from "@trpc/server/observable";
|
||||
|
||||
import { createSalt, hashPassword } from "@homarr/auth";
|
||||
import type { Database } from "@homarr/db";
|
||||
@@ -99,6 +98,15 @@ export const userRouter = createTRPCRouter({
|
||||
})
|
||||
.where(eq(users.id, input.userId));
|
||||
}),
|
||||
test: publicProcedure.subscription(() => {
|
||||
return observable<number>((emit) => {
|
||||
let counter = 0;
|
||||
setInterval(() => {
|
||||
counter = counter + 1;
|
||||
emit.next(counter);
|
||||
}, 1000);
|
||||
});
|
||||
}),
|
||||
});
|
||||
|
||||
const createUser = async (
|
||||
|
||||
@@ -12,6 +12,7 @@ import superjson from "superjson";
|
||||
import type { Session } from "@homarr/auth";
|
||||
import { auth } from "@homarr/auth";
|
||||
import { db } from "@homarr/db";
|
||||
import { logger } from "@homarr/log";
|
||||
import { ZodError } from "@homarr/validation";
|
||||
|
||||
/**
|
||||
@@ -33,7 +34,10 @@ export const createTRPCContext = async (opts: {
|
||||
const session = opts.session ?? (await auth());
|
||||
const source = opts.headers.get("x-trpc-source") ?? "unknown";
|
||||
|
||||
console.log(">>> tRPC Request from", source, "by", session?.user);
|
||||
logger.info(
|
||||
`tRPC request from ${source} by user '${session?.user.id}'`,
|
||||
session?.user,
|
||||
);
|
||||
|
||||
return {
|
||||
session,
|
||||
|
||||
53
packages/api/src/wssDevServer.ts
Normal file
53
packages/api/src/wssDevServer.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { applyWSSHandler } from "@trpc/server/adapters/ws";
|
||||
import { WebSocketServer } from "ws";
|
||||
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
import { appRouter } from "./root";
|
||||
import { createTRPCContext } from "./trpc";
|
||||
|
||||
const wss = new WebSocketServer({
|
||||
port: 3001,
|
||||
});
|
||||
const handler = applyWSSHandler({
|
||||
wss,
|
||||
router: appRouter,
|
||||
createContext: ({ req }) => {
|
||||
return createTRPCContext({
|
||||
headers: {
|
||||
...req.headers,
|
||||
get(key: string) {
|
||||
const item = req.headers[key];
|
||||
return typeof item === "string" ? item ?? null : item?.at(0) ?? null;
|
||||
},
|
||||
} as Headers,
|
||||
session: {
|
||||
// TODO: replace with actual session
|
||||
user: {
|
||||
id: "1",
|
||||
name: "Test User",
|
||||
email: "",
|
||||
},
|
||||
expires: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
wss.on("connection", (ws, incomingMessage) => {
|
||||
logger.info(
|
||||
`➕ Connection (${wss.clients.size}) ${incomingMessage.method} ${incomingMessage.url}`,
|
||||
);
|
||||
ws.once("close", (code, reason) => {
|
||||
logger.info(
|
||||
`➖ Connection (${wss.clients.size}) ${code} ${reason.toString()}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
logger.info("✅ WebSocket Server listening on ws://localhost:3001");
|
||||
|
||||
process.on("SIGTERM", () => {
|
||||
logger.info("SIGTERM");
|
||||
handler.broadcastReconnectNotification();
|
||||
wss.close();
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@homarr/auth",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.ts",
|
||||
"./security": "./security.ts",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"name": "@homarr/common",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.ts"
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"name": "@homarr/definitions",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.ts"
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"name": "@homarr/validation",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./index.ts"
|
||||
},
|
||||
|
||||
127
pnpm-lock.yaml
generated
127
pnpm-lock.yaml
generated
@@ -211,14 +211,14 @@ importers:
|
||||
specifier: ^2.2.4
|
||||
version: 2.2.4(@tiptap/pm@2.2.4)
|
||||
'@trpc/client':
|
||||
specifier: next
|
||||
version: 11.0.0-next-beta.289(@trpc/server@11.0.0-next-beta.289)
|
||||
specifier: 11.0.0-next-beta.316
|
||||
version: 11.0.0-next-beta.316(@trpc/server@11.0.0-next-beta.289)
|
||||
'@trpc/next':
|
||||
specifier: next
|
||||
version: 11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.289)(@trpc/react-query@11.0.0-next-beta.289)(@trpc/server@11.0.0-next-beta.289)(next@14.1.3)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.316)(@trpc/react-query@11.0.0-next-beta.289)(@trpc/server@11.0.0-next-beta.289)(next@14.1.3)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/react-query':
|
||||
specifier: next
|
||||
version: 11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.289)(@trpc/server@11.0.0-next-beta.289)(react-dom@18.2.0)(react@18.2.0)
|
||||
version: 11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.316)(@trpc/server@11.0.0-next-beta.289)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/server':
|
||||
specifier: next
|
||||
version: 11.0.0-next-beta.289
|
||||
@@ -277,6 +277,9 @@ importers:
|
||||
'@types/react-dom':
|
||||
specifier: ^18.2.22
|
||||
version: 18.2.22
|
||||
concurrently:
|
||||
specifier: ^8.2.2
|
||||
version: 8.2.2
|
||||
dotenv-cli:
|
||||
specifier: ^7.4.1
|
||||
version: 7.4.1
|
||||
@@ -286,6 +289,9 @@ importers:
|
||||
prettier:
|
||||
specifier: ^3.2.5
|
||||
version: 3.2.5
|
||||
tsx:
|
||||
specifier: ^4.7.1
|
||||
version: 4.7.1
|
||||
typescript:
|
||||
specifier: ^5.4.2
|
||||
version: 5.4.2
|
||||
@@ -301,6 +307,9 @@ importers:
|
||||
'@homarr/definitions':
|
||||
specifier: workspace:^0.1.0
|
||||
version: link:../definitions
|
||||
'@homarr/log':
|
||||
specifier: workspace:^
|
||||
version: link:../log
|
||||
'@homarr/validation':
|
||||
specifier: workspace:^0.1.0
|
||||
version: link:../validation
|
||||
@@ -313,6 +322,9 @@ importers:
|
||||
superjson:
|
||||
specifier: 2.2.1
|
||||
version: 2.2.1
|
||||
ws:
|
||||
specifier: ^8.16.0
|
||||
version: 8.16.0
|
||||
devDependencies:
|
||||
'@homarr/eslint-config':
|
||||
specifier: workspace:^0.2.0
|
||||
@@ -323,6 +335,9 @@ importers:
|
||||
'@homarr/tsconfig':
|
||||
specifier: workspace:^0.1.0
|
||||
version: link:../../tooling/typescript
|
||||
'@types/ws':
|
||||
specifier: ^8.5.10
|
||||
version: 8.5.10
|
||||
eslint:
|
||||
specifier: ^8.57.0
|
||||
version: 8.57.0
|
||||
@@ -2964,7 +2979,15 @@ packages:
|
||||
'@trpc/server': 11.0.0-next-beta.289
|
||||
dev: false
|
||||
|
||||
/@trpc/next@11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.289)(@trpc/react-query@11.0.0-next-beta.289)(@trpc/server@11.0.0-next-beta.289)(next@14.1.3)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@trpc/client@11.0.0-next-beta.316(@trpc/server@11.0.0-next-beta.289):
|
||||
resolution: {integrity: sha512-SR5Z+LtvQ/IzY2ymSnbGYl4kB7GnqBktTH9o3YhGN2MrwgEJ9qNotVQ7wcAmhumpY26hJnXqG3hD5SZPZdeJlg==}
|
||||
peerDependencies:
|
||||
'@trpc/server': 11.0.0-next-beta.316+dcae8bd89
|
||||
dependencies:
|
||||
'@trpc/server': 11.0.0-next-beta.289
|
||||
dev: false
|
||||
|
||||
/@trpc/next@11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.316)(@trpc/react-query@11.0.0-next-beta.289)(@trpc/server@11.0.0-next-beta.289)(next@14.1.3)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-AKCrcbtHh/zFrld6lMG0RC37d/aac4ZisLDjJcViMnEmJXCo0J5nhoZa6f+G9N683NdMWZVmY2rmJidw9IX3QQ==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^5.0.0
|
||||
@@ -2981,15 +3004,15 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@tanstack/react-query': 5.28.0(react@18.2.0)
|
||||
'@trpc/client': 11.0.0-next-beta.289(@trpc/server@11.0.0-next-beta.289)
|
||||
'@trpc/react-query': 11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.289)(@trpc/server@11.0.0-next-beta.289)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/client': 11.0.0-next-beta.316(@trpc/server@11.0.0-next-beta.289)
|
||||
'@trpc/react-query': 11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.316)(@trpc/server@11.0.0-next-beta.289)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@trpc/server': 11.0.0-next-beta.289
|
||||
next: 14.1.3(@babel/core@7.23.9)(react-dom@18.2.0)(react@18.2.0)(sass@1.71.1)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@trpc/react-query@11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.289)(@trpc/server@11.0.0-next-beta.289)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@trpc/react-query@11.0.0-next-beta.289(@tanstack/react-query@5.28.0)(@trpc/client@11.0.0-next-beta.316)(@trpc/server@11.0.0-next-beta.289)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-SAn09DmZ4eFYLS0cCHOVNvRHJhHZ2ssUj4LUTj56wym0MieaCSrcxTqiolnaMfF+mWc1SJlLOzebrxaTHPwJSw==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^5.0.0
|
||||
@@ -2999,7 +3022,7 @@ packages:
|
||||
react-dom: '>=18.2.0'
|
||||
dependencies:
|
||||
'@tanstack/react-query': 5.28.0(react@18.2.0)
|
||||
'@trpc/client': 11.0.0-next-beta.289(@trpc/server@11.0.0-next-beta.289)
|
||||
'@trpc/client': 11.0.0-next-beta.316(@trpc/server@11.0.0-next-beta.289)
|
||||
'@trpc/server': 11.0.0-next-beta.289
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
@@ -3321,6 +3344,12 @@ packages:
|
||||
resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==}
|
||||
dev: false
|
||||
|
||||
/@types/ws@8.5.10:
|
||||
resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
|
||||
dependencies:
|
||||
'@types/node': 20.11.27
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/eslint-plugin@7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2):
|
||||
resolution: {integrity: sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
@@ -4341,6 +4370,15 @@ packages:
|
||||
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
|
||||
dev: false
|
||||
|
||||
/cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
dev: true
|
||||
|
||||
/clone@1.0.4:
|
||||
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
|
||||
engines: {node: '>=0.8'}
|
||||
@@ -4447,6 +4485,22 @@ packages:
|
||||
readable-stream: 2.3.8
|
||||
typedarray: 0.0.6
|
||||
|
||||
/concurrently@8.2.2:
|
||||
resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==}
|
||||
engines: {node: ^14.13.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
date-fns: 2.30.0
|
||||
lodash: 4.17.21
|
||||
rxjs: 7.8.1
|
||||
shell-quote: 1.8.1
|
||||
spawn-command: 0.0.2
|
||||
supports-color: 8.1.1
|
||||
tree-kill: 1.2.2
|
||||
yargs: 17.7.2
|
||||
dev: true
|
||||
|
||||
/consola@2.15.3:
|
||||
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
|
||||
|
||||
@@ -4603,6 +4657,13 @@ packages:
|
||||
whatwg-url: 14.0.0
|
||||
dev: true
|
||||
|
||||
/date-fns@2.30.0:
|
||||
resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
|
||||
engines: {node: '>=0.11'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.9
|
||||
dev: true
|
||||
|
||||
/dayjs@1.11.10:
|
||||
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
|
||||
dev: false
|
||||
@@ -5868,6 +5929,11 @@ packages:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
/get-caller-file@2.0.5:
|
||||
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
|
||||
engines: {node: 6.* || 8.* || >= 10.*}
|
||||
dev: true
|
||||
|
||||
/get-func-name@2.0.2:
|
||||
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
||||
dev: true
|
||||
@@ -8439,6 +8505,11 @@ packages:
|
||||
engines: {node: '>=0.10'}
|
||||
dev: true
|
||||
|
||||
/require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/require-from-string@2.0.2:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -8730,6 +8801,10 @@ packages:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
/shell-quote@1.8.1:
|
||||
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
|
||||
dev: true
|
||||
|
||||
/shelljs@0.8.5:
|
||||
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -8847,6 +8922,10 @@ packages:
|
||||
engines: {node: '>= 8'}
|
||||
dev: true
|
||||
|
||||
/spawn-command@0.0.2:
|
||||
resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==}
|
||||
dev: true
|
||||
|
||||
/sprintf-js@1.1.3:
|
||||
resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
|
||||
dev: true
|
||||
@@ -9377,6 +9456,17 @@ packages:
|
||||
engines: {node: '>=0.6.x'}
|
||||
dev: false
|
||||
|
||||
/tsx@4.7.1:
|
||||
resolution: {integrity: sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
esbuild: 0.19.12
|
||||
get-tsconfig: 4.7.2
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/tunnel-agent@0.6.0:
|
||||
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
|
||||
dependencies:
|
||||
@@ -10133,7 +10223,6 @@ packages:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
dev: true
|
||||
|
||||
/xml-name-validator@5.0.0:
|
||||
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
|
||||
@@ -10148,6 +10237,11 @@ packages:
|
||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
||||
/y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/yallist@3.1.1:
|
||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||
|
||||
@@ -10159,6 +10253,19 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.1.2
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
dev: true
|
||||
|
||||
/yn@3.1.1:
|
||||
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
Reference in New Issue
Block a user