From 6b261f4e3f37b5eee48f030746c7e79e7fb7c1e1 Mon Sep 17 00:00:00 2001
From: Rob Knight
Date: Fri, 13 Sep 2024 19:23:02 +0200
Subject: [PATCH] GPC proofs in test client
---
apps/client-web/.gitignore | 1 +
apps/client-web/index.html | 2 +-
apps/client-web/package.json | 5 +-
apps/client-web/src/App.tsx | 278 ++++++++++++++++--
apps/client-web/src/client/gpc.ts | 9 +-
apps/client-web/src/client/pod.ts | 21 +-
apps/client-web/src/client/pod_collection.ts | 6 +-
.../src/client/query_subscriptions.ts | 12 +-
apps/client-web/src/client/utils.ts | 20 --
apps/client-web/src/state.ts | 8 +
apps/client-web/vite.config.ts | 5 +-
examples/test-app/src/apis/GPC.tsx | 26 +-
.../client-helpers/src/connection/iframe.ts | 37 ++-
packages/podspec/src/gpc/proof_request.ts | 4 +-
packages/podspec/src/parse/pod.ts | 14 +-
pnpm-lock.yaml | 29 +-
16 files changed, 372 insertions(+), 105 deletions(-)
diff --git a/apps/client-web/.gitignore b/apps/client-web/.gitignore
index a547bf3..c6d388a 100644
--- a/apps/client-web/.gitignore
+++ b/apps/client-web/.gitignore
@@ -22,3 +22,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
+public/artifacts/*
diff --git a/apps/client-web/index.html b/apps/client-web/index.html
index 1975e38..1f85e1a 100644
--- a/apps/client-web/index.html
+++ b/apps/client-web/index.html
@@ -5,7 +5,7 @@
PARCNET Client
-
+
diff --git a/apps/client-web/package.json b/apps/client-web/package.json
index 72fc2c0..57c8ec4 100644
--- a/apps/client-web/package.json
+++ b/apps/client-web/package.json
@@ -19,8 +19,7 @@
"eventemitter3": "^5.0.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
- "vite-plugin-node-polyfills": "^0.22.0",
- "zod": "^3.23.8"
+ "vite-plugin-node-polyfills": "^0.22.0"
},
"devDependencies": {
"@parcnet/eslint-config": "workspace:*",
@@ -33,6 +32,6 @@
"postcss": "^8.4.41",
"tailwindcss": "^3.4.10",
"typescript": "^5.5",
- "vite": "^5.4.1"
+ "vite": "^5.4.4"
}
}
diff --git a/apps/client-web/src/App.tsx b/apps/client-web/src/App.tsx
index c428e2a..b92d619 100644
--- a/apps/client-web/src/App.tsx
+++ b/apps/client-web/src/App.tsx
@@ -1,6 +1,16 @@
import { listen } from "@parcnet/client-helpers/connection/iframe";
import { Zapp } from "@parcnet/client-rpc";
-import { Dispatch, ReactNode, useEffect, useReducer } from "react";
+import { EntriesSchema, PODSchema, proofRequest } from "@parcnet/podspec";
+import { gpcProve } from "@pcd/gpc";
+import { POD, POD_INT_MAX, POD_INT_MIN } from "@pcd/pod";
+import {
+ Dispatch,
+ Fragment,
+ ReactNode,
+ useEffect,
+ useReducer,
+ useState
+} from "react";
import { ParcnetClientProcessor } from "./client/client";
import { PODCollection } from "./client/pod_collection";
import { loadPODsFromStorage, savePODsToStorage } from "./client/utils";
@@ -67,18 +77,173 @@ function App() {
state.authorized &&
state.zapp &&
state.proofInProgress && (
-
+
)}
);
}
+function Reveal({ children }: { children: ReactNode }) {
+ const [isRevealed, setIsRevealed] = useState(false);
+ return (
+ <>
+ setIsRevealed(!isRevealed)}>
+ {isRevealed ? "Hide" : "Reveal"}
+
+ {isRevealed && {children}
}
+ >
+ );
+}
+
+function ProvePODInfo({
+ name,
+ schema,
+ pods,
+ selectedPOD,
+ onChange
+}: {
+ name: string;
+ schema: PODSchema;
+ pods: POD[];
+ selectedPOD: POD | undefined;
+ onChange: (pod: POD | undefined) => void;
+}): ReactNode {
+ const revealedEntries = Object.entries(schema.entries)
+ .map(([name, entry]) => {
+ if (entry.type === "optional") {
+ entry = entry.innerType;
+ }
+ return [name, entry] as const;
+ })
+ .filter(([_, entry]) => entry.isRevealed);
+
+ const selectedPODEntries = selectedPOD?.content.asEntries();
+
+ const entriesWithConstraints = Object.entries(schema.entries)
+ .map(([name, entry]) => {
+ if (entry.type === "optional") {
+ entry = entry.innerType;
+ }
+ return [name, entry] as const;
+ })
+ .filter(
+ ([_, entry]) =>
+ !!entry.isMemberOf ||
+ !!entry.isNotMemberOf ||
+ !!(entry.type === "int" && entry.inRange)
+ );
+
+ return (
+
+
+
{name}
+
{
+ onChange(pods.find((pod) => pod.signature === ev.target.value));
+ }}
+ >
+
+ -- None selected --
+
+ {pods.map((pod) => {
+ return (
+
+ {pod.signature.substring(0, 16)}
+
+ );
+ })}
+
+
+
+ {revealedEntries.length > 0 && "Revealed entries:"}
+
+
+ {revealedEntries.map(([entryName, _]) => {
+ return (
+
+ {entryName}
+
+ {selectedPODEntries?.[entryName].value.toString() ?? "-"}
+
+
+ );
+ })}
+
+ {entriesWithConstraints.length > 0 && (
+
+
Proven constraints:
+ {entriesWithConstraints.map(([entryName, entry]) => {
+ return (
+
+ {entry.isMemberOf && (
+
+
{entryName} is member
+ of list:{" "}
+
+
+ {entry.isMemberOf
+ .map((v) => v.value.toString())
+ .join(", ")}
+
+
+
+ )}
+ {entry.isNotMemberOf && (
+
+
{entryName} is not
+ member of list:{" "}
+
+
+ {entry.isNotMemberOf
+ .map((v) => v.value.toString())
+ .join(", ")}
+
+
+
+ )}
+ {entry.type === "int" && entry.inRange && (
+
+
{entryName} is
+
+ {entry.inRange.min === POD_INT_MIN &&
+ entry.inRange.max === POD_INT_MAX &&
+ "any number"}
+ {entry.inRange.min !== POD_INT_MIN &&
+ entry.inRange.max === POD_INT_MAX &&
+ `greater than ${entry.inRange.min}`}
+ {entry.inRange.min === POD_INT_MIN &&
+ entry.inRange.max !== POD_INT_MAX &&
+ `less than ${entry.inRange.max}`}
+ {entry.inRange.min !== POD_INT_MIN &&
+ entry.inRange.max !== POD_INT_MAX &&
+ `between ${entry.inRange.min} and ${entry.inRange.max}`}
+
+
+ )}
+
+ );
+ })}
+
+ )}
+
+ );
+}
+
function Prove({
- proveOperation
+ proveOperation,
+ dispatch
}: {
proveOperation: NonNullable;
+ dispatch: Dispatch;
}): ReactNode {
+ const canProve =
+ Object.keys(proveOperation.selectedPods).length ===
+ Object.keys(proveOperation.proofRequest.pods).length &&
+ Object.values(proveOperation.selectedPods).every((maybePod) => !!maybePod);
+
/**
* show exactly which fields are revealed and which are not, literally show
* the whole POD and which entries are revealed
@@ -86,25 +251,94 @@ function Prove({
*/
return (
-
- {Object.entries(proveOperation.pods).map(([key, pods]) => {
- return (
-
-
{key}
-
- {pods.map((pod) => {
- return (
-
- {pod.contentID.toString()}
- {pod.serialize()}
-
- );
- })}
-
-
- );
- })}
-
+
+
This proof will reveal the following data from your PODs:
+ {Object.entries(proveOperation.proofRequest.pods).map(
+ ([name, schema]) => {
+ return (
+
{
+ dispatch({
+ type: "set-proof-in-progress",
+ ...proveOperation,
+ selectedPods: {
+ ...proveOperation.selectedPods,
+ ...{ [name]: pod }
+ }
+ });
+ }}
+ />
+ );
+ }
+ )}
+
+
{
+ dispatch({
+ type: "set-proof-in-progress",
+ ...proveOperation,
+ proving: true
+ });
+ const prs = proofRequest(
+ proveOperation.proofRequest
+ ).getProofRequest();
+ gpcProve(
+ prs.proofConfig,
+ {
+ pods: proveOperation.selectedPods as Record,
+ membershipLists: prs.membershipLists,
+ watermark: prs.watermark
+ },
+ new URL("/artifacts", window.location.origin).toString()
+ )
+ .then((proof) => {
+ proveOperation.resolve?.({
+ success: true,
+ proof: proof.proof,
+ boundConfig: proof.boundConfig,
+ revealedClaims: proof.revealedClaims
+ });
+ dispatch({
+ type: "clear-proof-in-progress"
+ });
+ })
+ .catch((error) => console.error(error));
+ }}
+ >
+ {proveOperation.proving ? (
+
+
+
+
+ ) : (
+ "Prove"
+ )}
+
+
+
);
}
diff --git a/apps/client-web/src/client/gpc.ts b/apps/client-web/src/client/gpc.ts
index 2c940e8..50344dc 100644
--- a/apps/client-web/src/client/gpc.ts
+++ b/apps/client-web/src/client/gpc.ts
@@ -1,14 +1,9 @@
import { ConnectorAdvice } from "@parcnet/client-helpers";
-import {
- ParcnetGPCRPC,
- ParcnetRPCSchema,
- ProveResult
-} from "@parcnet/client-rpc";
+import { ParcnetGPCRPC, ProveResult } from "@parcnet/client-rpc";
import { PodspecProofRequest, proofRequest } from "@parcnet/podspec";
import { Dispatch } from "react";
import { ClientAction } from "../state";
import { PODCollection } from "./pod_collection";
-import { validateInput } from "./utils";
export class ParcnetGPCProcessor implements ParcnetGPCRPC {
public constructor(
@@ -17,7 +12,6 @@ export class ParcnetGPCProcessor implements ParcnetGPCRPC {
private readonly advice: ConnectorAdvice
) {}
- @validateInput(ParcnetRPCSchema.shape.gpc.shape.canProve)
public async canProve(request: PodspecProofRequest): Promise {
const prs = proofRequest(request);
@@ -31,7 +25,6 @@ export class ParcnetGPCProcessor implements ParcnetGPCRPC {
return true;
}
- @validateInput(ParcnetRPCSchema.shape.gpc.shape.prove)
public async prove(request: PodspecProofRequest): Promise {
const prs = proofRequest(request);
diff --git a/apps/client-web/src/client/pod.ts b/apps/client-web/src/client/pod.ts
index f8b25d1..5d4e338 100644
--- a/apps/client-web/src/client/pod.ts
+++ b/apps/client-web/src/client/pod.ts
@@ -1,10 +1,8 @@
-import { ParcnetPODRPC, ParcnetRPCSchema } from "@parcnet/client-rpc";
-import * as p from "@parcnet/podspec";
+import { ParcnetPODRPC } from "@parcnet/client-rpc";
import { EntriesSchema, PODSchema } from "@parcnet/podspec";
import { POD } from "@pcd/pod";
import { PODCollection } from "./pod_collection.js";
import { QuerySubscriptions } from "./query_subscriptions.js";
-import { validateInput } from "./utils.js";
export class ParcnetPODProcessor implements ParcnetPODRPC {
public constructor(
@@ -12,28 +10,27 @@ export class ParcnetPODProcessor implements ParcnetPODRPC {
private readonly subscriptions: QuerySubscriptions
) {}
- @validateInput(ParcnetRPCSchema.shape.pod.shape.query)
- public async query(query: PODSchema): Promise {
- return this.pods.query(p.pod(query)).map((pod) => pod.serialize());
+ public async query(
+ query: PODSchema
+ ): Promise {
+ return this.pods.query(query).map((pod) => pod.serialize());
}
- @validateInput(ParcnetRPCSchema.shape.pod.shape.insert)
public async insert(serializedPod: string): Promise {
const pod = POD.deserialize(serializedPod);
this.pods.insert(pod);
}
- @validateInput(ParcnetRPCSchema.shape.pod.shape.delete)
public async delete(signature: string): Promise {
this.pods.delete(signature);
}
- @validateInput(ParcnetRPCSchema.shape.pod.shape.subscribe)
- public async subscribe(query: PODSchema): Promise {
- return this.subscriptions.subscribe(p.pod(query));
+ public async subscribe(
+ query: PODSchema
+ ): Promise {
+ return this.subscriptions.subscribe(query);
}
- @validateInput(ParcnetRPCSchema.shape.pod.shape.unsubscribe)
public async unsubscribe(subscriptionId: string): Promise {
this.subscriptions.unsubscribe(subscriptionId);
}
diff --git a/apps/client-web/src/client/pod_collection.ts b/apps/client-web/src/client/pod_collection.ts
index 37c112d..3fa4adf 100644
--- a/apps/client-web/src/client/pod_collection.ts
+++ b/apps/client-web/src/client/pod_collection.ts
@@ -2,8 +2,6 @@ import * as p from "@parcnet/podspec";
import { POD } from "@pcd/pod";
import { EventEmitter } from "eventemitter3";
-type PODQuery = ReturnType;
-
export interface PODCollectionUpdate {
type: "insert" | "delete";
affectedPOD: POD;
@@ -38,9 +36,9 @@ export class PODCollection {
}
}
- public query(query: PODQuery): POD[] {
+ public query(query: p.PODSchema): POD[] {
console.log(query);
- return query.query(this.pods).matches;
+ return p.pod(query).query(this.pods).matches;
}
public onUpdate(listener: (update: PODCollectionUpdate) => void): void {
diff --git a/apps/client-web/src/client/query_subscriptions.ts b/apps/client-web/src/client/query_subscriptions.ts
index a8d1728..88690e3 100644
--- a/apps/client-web/src/client/query_subscriptions.ts
+++ b/apps/client-web/src/client/query_subscriptions.ts
@@ -1,5 +1,6 @@
import { SubscriptionUpdateResult } from "@parcnet/client-rpc";
-import { EntriesSchema, PodSpec } from "@parcnet/podspec";
+import * as p from "@parcnet/podspec";
+import { EntriesSchema, PODSchema, PodSpec } from "@parcnet/podspec";
import { EventEmitter } from "eventemitter3";
import { PODCollection } from "./pod_collection.js";
@@ -57,9 +58,14 @@ export class QuerySubscriptions {
});
}
- public async subscribe(query: PodSpec): Promise {
+ public async subscribe(
+ query: PODSchema
+ ): Promise {
const subscriptionId = (this.nextSubscriptionId++).toString();
- this.subscriptions.set(subscriptionId, { query, serial: 0 });
+ this.subscriptions.set(subscriptionId, {
+ query: p.pod(query) as PodSpec,
+ serial: 0
+ });
return subscriptionId;
}
diff --git a/apps/client-web/src/client/utils.ts b/apps/client-web/src/client/utils.ts
index abaacc4..00e5729 100644
--- a/apps/client-web/src/client/utils.ts
+++ b/apps/client-web/src/client/utils.ts
@@ -1,24 +1,4 @@
import { POD } from "@pcd/pod";
-import { z } from "zod";
-
-export function validateInput(
- parser: z.ZodSchema
-) {
- return function actualDecorator(
- originalMethod: (this: This, ...args: Args) => Return,
- context: ClassMethodDecoratorContext
- ): (this: This, ...args: Args) => Return {
- function replacementMethod(this: This, ...args: Args): Return {
- const input = parser.safeParse(args);
- if (!input.success) {
- throw new Error(`Invalid arguments for ${context.name.toString()}`);
- }
- return originalMethod.call(this, ...input.data);
- }
-
- return replacementMethod;
- };
-}
export function loadPODsFromStorage(): POD[] {
let pods: POD[] = [];
diff --git a/apps/client-web/src/state.ts b/apps/client-web/src/state.ts
index 9e7169c..0e2daaa 100644
--- a/apps/client-web/src/state.ts
+++ b/apps/client-web/src/state.ts
@@ -43,6 +43,9 @@ export type ClientAction =
proofRequest: PodspecProofRequest;
proving: boolean;
resolve?: (result: ProveResult) => void;
+ }
+ | {
+ type: "clear-proof-in-progress";
};
export function clientReducer(state: ClientState, action: ClientAction) {
@@ -66,5 +69,10 @@ export function clientReducer(state: ClientState, action: ClientAction) {
resolve: action.resolve
}
};
+ case "clear-proof-in-progress":
+ return {
+ ...state,
+ proofInProgress: undefined
+ };
}
}
diff --git a/apps/client-web/vite.config.ts b/apps/client-web/vite.config.ts
index 87c0b82..88235f0 100644
--- a/apps/client-web/vite.config.ts
+++ b/apps/client-web/vite.config.ts
@@ -9,5 +9,8 @@ export default defineConfig({
nodePolyfills({
include: ["assert", "buffer"]
})
- ]
+ ],
+ esbuild: {
+ target: "es2020"
+ }
});
diff --git a/examples/test-app/src/apis/GPC.tsx b/examples/test-app/src/apis/GPC.tsx
index 8db1d95..4dc655e 100644
--- a/examples/test-app/src/apis/GPC.tsx
+++ b/examples/test-app/src/apis/GPC.tsx
@@ -1,4 +1,5 @@
import { PodspecProofRequest } from "@parcnet/podspec";
+import JSONBig from "json-bigint";
import { ReactNode, useState } from "react";
import { ProveResult } from "../../../../packages/client-rpc/src";
import { TryIt } from "../components/TryIt";
@@ -8,7 +9,11 @@ const request: PodspecProofRequest = {
pods: {
pod1: {
entries: {
- wis: { type: "int", inRange: { min: BigInt(5), max: BigInt(1000) } },
+ wis: {
+ type: "int",
+ inRange: { min: BigInt(5), max: BigInt(1000) },
+ isRevealed: true
+ },
str: { type: "int", inRange: { min: BigInt(5), max: BigInt(1000) } }
}
},
@@ -16,7 +21,8 @@ const request: PodspecProofRequest = {
entries: {
test: {
type: "string",
- isMemberOf: [{ type: "string", value: "secret" }]
+ isMemberOf: [{ type: "string", value: "secret" }],
+ isRevealed: true
}
}
}
@@ -41,7 +47,11 @@ const request: PodspecProofRequest = {
pods: {
pod1: {
entries: {
- wis: { type: "int", inRange: { min: BigInt(5), max: BigInt(1000) } },
+ wis: {
+ type: "int",
+ inRange: { min: BigInt(5), max: BigInt(1000) },
+ isRevealed: true
+ },
str: { type: "int", inRange: { min: BigInt(5), max: BigInt(1000) } }
}
},
@@ -49,15 +59,17 @@ const request: PodspecProofRequest = {
entries: {
test: {
type: "string",
- isMemberOf: [{ type: "string", value: "secret" }]
+ isMemberOf: [{ type: "string", value: "secret" }],
+ isRevealed: true
}
}
}
}
};
-
+
+const gpcProof = await z.gpc.prove(request);
+
`}
- const gpcProof = await z.gpc.prove(request);
{proof && (
- {JSON.stringify(proof, null, 2)}
+ {JSONBig.stringify(proof, null, 2)}
)}
diff --git a/packages/client-helpers/src/connection/iframe.ts b/packages/client-helpers/src/connection/iframe.ts
index f55b07c..f711f7f 100644
--- a/packages/client-helpers/src/connection/iframe.ts
+++ b/packages/client-helpers/src/connection/iframe.ts
@@ -3,6 +3,8 @@ import {
InitializationMessageSchema,
InitializationMessageType,
ParcnetRPC,
+ ParcnetRPCMethodName,
+ ParcnetRPCSchema,
RPCMessage,
RPCMessageSchema,
RPCMessageType,
@@ -58,6 +60,32 @@ export class AdviceChannel implements ConnectorAdvice {
}
}
+function getSchema(method: ParcnetRPCMethodName) {
+ switch (method) {
+ case "gpc.canProve":
+ return ParcnetRPCSchema.shape.gpc.shape.canProve;
+ case "gpc.prove":
+ return ParcnetRPCSchema.shape.gpc.shape.prove;
+ case "gpc.verify":
+ return ParcnetRPCSchema.shape.gpc.shape.verify;
+ case "identity.getSemaphoreV3Commitment":
+ return ParcnetRPCSchema.shape.identity.shape.getSemaphoreV3Commitment;
+ case "pod.query":
+ return ParcnetRPCSchema.shape.pod.shape.query;
+ case "pod.insert":
+ return ParcnetRPCSchema.shape.pod.shape.insert;
+ case "pod.delete":
+ return ParcnetRPCSchema.shape.pod.shape.delete;
+ case "pod.subscribe":
+ return ParcnetRPCSchema.shape.pod.shape.subscribe;
+ case "pod.unsubscribe":
+ return ParcnetRPCSchema.shape.pod.shape.unsubscribe;
+ default:
+ const unknownMethod: never = method;
+ throw new Error(`Unknown method: ${unknownMethod as string}`);
+ }
+}
+
async function handleMessage(
rpc: ParcnetRPC,
port: MessagePort,
@@ -71,11 +99,16 @@ async function handleMessage(
}
const object = deepGet(rpc, path);
const functionToInvoke = (object as Record)[functionName];
+
try {
if (functionToInvoke && typeof functionToInvoke === "function") {
+ const schema = getSchema(message.fn);
+ const parsedArgs = schema.parameters().parse(message.args);
try {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- const result = await functionToInvoke.apply(object, message.args);
+ const result = await schema
+ .returnType()
+ .parse(functionToInvoke.apply(object, parsedArgs));
+
port.postMessage({
type: RPCMessageType.PARCNET_CLIENT_INVOKE_RESULT,
result,
diff --git a/packages/podspec/src/gpc/proof_request.ts b/packages/podspec/src/gpc/proof_request.ts
index b85008c..2975e21 100644
--- a/packages/podspec/src/gpc/proof_request.ts
+++ b/packages/podspec/src/gpc/proof_request.ts
@@ -28,7 +28,9 @@ export type ProofRequest = {
* A PodspecProofRequest allows us to generate a {@link ProofRequest} from a
* set of Podspecs defining the allowable PODs.
*/
-export interface PodspecProofRequest> {
+export interface PodspecProofRequest<
+ P extends Record = Record>
+> {
pods: Readonly<{
[K in keyof P]: P[K] extends PODSchema
? P[K] & PODSchema
diff --git a/packages/podspec/src/parse/pod.ts b/packages/podspec/src/parse/pod.ts
index e906d1d..04dd958 100644
--- a/packages/podspec/src/parse/pod.ts
+++ b/packages/podspec/src/parse/pod.ts
@@ -54,7 +54,7 @@ export class PodSpec {
*
* @param schema The schema for the POD.
*/
- private constructor(schema: PODSchema>) {
+ private constructor(schema: PODSchema) {
this.schema = Object.freeze(schema);
}
@@ -108,9 +108,14 @@ export class PodSpec {
public query(input: POD[]): { matches: POD[]; matchingIndexes: number[] } {
const matchingIndexes: number[] = [];
const matches: POD[] = [];
+ const signatures = new Set();
for (const [index, pod] of input.entries()) {
const result = this.safeParse(pod, { exitEarly: true });
if (result.isValid) {
+ if (signatures.has(pod.signature)) {
+ continue;
+ }
+ signatures.add(pod.signature);
matchingIndexes.push(index);
matches.push(pod);
}
@@ -142,7 +147,7 @@ export class PodSpec {
* @returns A new PodSpec instance.
*/
public static create(
- schema: PODSchema>
+ schema: PODSchema
): PodSpec {
return new PodSpec(schema);
}
@@ -151,9 +156,8 @@ export class PodSpec {
/**
* Exported version of static create method, for convenience.
*/
-export const pod = (
- schema: PODSchema>
-) => PodSpec.create(schema);
+export const pod = (schema: PODSchema) =>
+ PodSpec.create(schema);
/**
* Parses the POD and its entries, returning a {@link ParseResult}.
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f9fdaec..3404ec0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -131,10 +131,7 @@ importers:
version: 18.3.1(react@18.3.1)
vite-plugin-node-polyfills:
specifier: ^0.22.0
- version: 0.22.0(rollup@4.21.2)(vite@5.4.2(@types/node@22.5.4))
- zod:
- specifier: ^3.23.8
- version: 3.23.8
+ version: 0.22.0(rollup@4.21.2)(vite@5.4.4(@types/node@22.5.4))
devDependencies:
'@parcnet/eslint-config':
specifier: workspace:*
@@ -147,7 +144,7 @@ importers:
version: 18.3.0
'@vitejs/plugin-react':
specifier: ^4.3.1
- version: 4.3.1(vite@5.4.2(@types/node@22.5.4))
+ version: 4.3.1(vite@5.4.4(@types/node@22.5.4))
autoprefixer:
specifier: ^10.4.20
version: 10.4.20(postcss@8.4.44)
@@ -167,8 +164,8 @@ importers:
specifier: ^5.5
version: 5.5.4
vite:
- specifier: ^5.4.1
- version: 5.4.2(@types/node@22.5.4)
+ specifier: ^5.4.4
+ version: 5.4.4(@types/node@22.5.4)
examples/test-app:
dependencies:
@@ -3639,8 +3636,8 @@ packages:
peerDependencies:
vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
- vite@5.4.2:
- resolution: {integrity: sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==}
+ vite@5.4.4:
+ resolution: {integrity: sha512-RHFCkULitycHVTtelJ6jQLd+KSAAzOgEYorV32R2q++M6COBjKJR6BxqClwp5sf0XaBDjVMuJ9wnNfyAJwjMkA==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@@ -4653,14 +4650,14 @@ snapshots:
'@typescript-eslint/types': 8.4.0
eslint-visitor-keys: 3.4.3
- '@vitejs/plugin-react@4.3.1(vite@5.4.2(@types/node@22.5.4))':
+ '@vitejs/plugin-react@4.3.1(vite@5.4.4(@types/node@22.5.4))':
dependencies:
'@babel/core': 7.25.2
'@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2)
'@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2)
'@types/babel__core': 7.20.5
react-refresh: 0.14.2
- vite: 5.4.2(@types/node@22.5.4)
+ vite: 5.4.4(@types/node@22.5.4)
transitivePeerDependencies:
- supports-color
@@ -7324,7 +7321,7 @@ snapshots:
debug: 4.3.6
pathe: 1.1.2
tinyrainbow: 1.2.0
- vite: 5.4.2(@types/node@22.5.4)
+ vite: 5.4.4(@types/node@22.5.4)
transitivePeerDependencies:
- '@types/node'
- less
@@ -7336,15 +7333,15 @@ snapshots:
- supports-color
- terser
- vite-plugin-node-polyfills@0.22.0(rollup@4.21.2)(vite@5.4.2(@types/node@22.5.4)):
+ vite-plugin-node-polyfills@0.22.0(rollup@4.21.2)(vite@5.4.4(@types/node@22.5.4)):
dependencies:
'@rollup/plugin-inject': 5.0.5(rollup@4.21.2)
node-stdlib-browser: 1.2.0
- vite: 5.4.2(@types/node@22.5.4)
+ vite: 5.4.4(@types/node@22.5.4)
transitivePeerDependencies:
- rollup
- vite@5.4.2(@types/node@22.5.4):
+ vite@5.4.4(@types/node@22.5.4):
dependencies:
esbuild: 0.21.5
postcss: 8.4.44
@@ -7371,7 +7368,7 @@ snapshots:
tinybench: 2.9.0
tinypool: 1.0.1
tinyrainbow: 1.2.0
- vite: 5.4.2(@types/node@22.5.4)
+ vite: 5.4.4(@types/node@22.5.4)
vite-node: 2.0.5(@types/node@22.5.4)
why-is-node-running: 2.3.0
optionalDependencies: