From c9e6dce081a86d09994888dd007112b4044c7578 Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Sat, 19 Apr 2025 22:40:11 +0530 Subject: [PATCH 1/9] chore: stash dockerfile progress --- .dockerignore | 39 ++ infrastructure/evault-core/.dockerignore | 39 ++ infrastructure/evault-core/.env.example | 7 + infrastructure/evault-core/Dockerfile | 23 + infrastructure/evault-core/docker-compose.yml | 34 +- infrastructure/evault-core/package.json | 63 +-- .../evault-core/src/db/db.service.ts | 494 +++++++++--------- infrastructure/evault-core/src/evault.ts | 7 +- .../src/protocol/examples/examples.ts | 112 ++++ .../src/protocol/graphql-server.ts | 246 +++++---- 10 files changed, 671 insertions(+), 393 deletions(-) create mode 100644 .dockerignore create mode 100644 infrastructure/evault-core/.dockerignore create mode 100644 infrastructure/evault-core/.env.example create mode 100644 infrastructure/evault-core/Dockerfile create mode 100644 infrastructure/evault-core/src/protocol/examples/examples.ts diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..8cc007ad --- /dev/null +++ b/.dockerignore @@ -0,0 +1,39 @@ + +# Node cruft +node_modules +.pnpm +dist +build +.cache +turbo +out + +# Dependency locks from other ecosystems +package-lock.json +yarn.lock + +# Logs & temp +*.log +*.tsbuildinfo +.vscode +.idea +.env +.env.* + +# OS junk +.DS_Store +Thumbs.db + +# Local-only files +coverage +*.local.* +*.swp +*.swo + +# Git stuff +.git +.gitignore + +# Prevent docker context pollution from other packages in monorepo +apps/*/node_modules +packages/*/node_modules diff --git a/infrastructure/evault-core/.dockerignore b/infrastructure/evault-core/.dockerignore new file mode 100644 index 00000000..8cc007ad --- /dev/null +++ b/infrastructure/evault-core/.dockerignore @@ -0,0 +1,39 @@ + +# Node cruft +node_modules +.pnpm +dist +build +.cache +turbo +out + +# Dependency locks from other ecosystems +package-lock.json +yarn.lock + +# Logs & temp +*.log +*.tsbuildinfo +.vscode +.idea +.env +.env.* + +# OS junk +.DS_Store +Thumbs.db + +# Local-only files +coverage +*.local.* +*.swp +*.swo + +# Git stuff +.git +.gitignore + +# Prevent docker context pollution from other packages in monorepo +apps/*/node_modules +packages/*/node_modules diff --git a/infrastructure/evault-core/.env.example b/infrastructure/evault-core/.env.example new file mode 100644 index 00000000..acdfda8a --- /dev/null +++ b/infrastructure/evault-core/.env.example @@ -0,0 +1,7 @@ +# Neo4j Configuration +NEO4J_URI=bolt://neo4j:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=your_secure_password_here + +# eVault Configuration +PORT=4000 \ No newline at end of file diff --git a/infrastructure/evault-core/Dockerfile b/infrastructure/evault-core/Dockerfile new file mode 100644 index 00000000..1442ecbb --- /dev/null +++ b/infrastructure/evault-core/Dockerfile @@ -0,0 +1,23 @@ +FROM node:22-slim AS deps +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable +COPY . /app +WORKDIR /app +RUN npm i -g corepack@latest +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile +RUN pnpm turbo prune evault-core --docker --use-gitignore=false +RUN mkdir /out +RUN cp -R ./out/full/* /out/ +RUN cp -R ./out/json/* /out/ +RUN cp ./out/pnpm-lock.yaml /out/pnpm-lock.yaml +RUN cp -R node_modules/ /out/ + + +FROM node:22-slim AS core-api +WORKDIR /app +RUN npm i -g corepack@latest +COPY --from=deps /out/ /app +EXPOSE 1209 +workdir /app/infrastructure/evault-core +CMD ["pnpm", "dev"] diff --git a/infrastructure/evault-core/docker-compose.yml b/infrastructure/evault-core/docker-compose.yml index 48f9d70d..c1a73a1d 100644 --- a/infrastructure/evault-core/docker-compose.yml +++ b/infrastructure/evault-core/docker-compose.yml @@ -1,21 +1,49 @@ version: '3.8' services: + evault: + build: + context: ../../ + dockerfile: ./infrastructure/evault-core/Dockerfile + ports: + - "4000:4000" + environment: + - NEO4J_URI=${NEO4J_URI} + - NEO4J_USER=${NEO4J_USER} + - NEO4J_PASSWORD=${NEO4J_PASSWORD} + networks: + - graphnet + depends_on: + - neo4j + develop: + watch: + - action: sync + path: ./ + target: /app/infrastructure/evault-core + ignore: + - node_modules + - action: rebuild + path: ./package.json + - action: rebuild + path: ./.env + neo4j: image: neo4j:5.15 container_name: neo4j ports: - - "7474:7474" - - "7687:7687" + - "7474:7474" # HTTP + - "7687:7687" # Bolt environment: - - NEO4J_AUTH=neo4j/testpass + - NEO4J_AUTH=${NEO4J_USER}/${NEO4J_PASSWORD} volumes: - neo4j_data:/data + - neo4j_logs:/logs networks: - graphnet volumes: neo4j_data: + neo4j_logs: networks: graphnet: diff --git a/infrastructure/evault-core/package.json b/infrastructure/evault-core/package.json index a8feaa5c..de6c0d12 100644 --- a/infrastructure/evault-core/package.json +++ b/infrastructure/evault-core/package.json @@ -1,32 +1,35 @@ { - "name": "evault-core", - "version": "0.1.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "vitest --config vitest.config.ts" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "@types/json-schema": "^7.0.15", - "@types/node": "^22.13.10", - "dotenv": "^16.5.0", - "testcontainers": "^10.24.2", - "tsx": "^4.19.3", - "typescript": "^5.8.3", - "uuid": "^11.1.0", - "vitest": "^3.0.9" - }, - "dependencies": { - "@testcontainers/neo4j": "^10.24.2", - "graphql": "^16.10.0", - "graphql-type-json": "^0.3.2", - "graphql-voyager": "^2.1.0", - "graphql-yoga": "^5.13.4", - "json-schema": "^0.4.0", - "neo4j-driver": "^5.28.1", - "w3id": "workspace:*" - } + "name": "evault-core", + "version": "0.1.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "vitest --config vitest.config.ts", + "build": "tsc", + "dev": "tsx --watch src/evault.ts" + }, + "packageManager": "pnpm@10.6.5", + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/json-schema": "^7.0.15", + "@types/node": "^22.13.10", + "dotenv": "^16.5.0", + "testcontainers": "^10.24.2", + "tsx": "^4.19.3", + "typescript": "^5.8.3", + "uuid": "^11.1.0", + "vitest": "^3.0.9" + }, + "dependencies": { + "@testcontainers/neo4j": "^10.24.2", + "graphql": "^16.10.0", + "graphql-type-json": "^0.3.2", + "graphql-voyager": "^2.1.0", + "graphql-yoga": "^5.13.4", + "json-schema": "^0.4.0", + "neo4j-driver": "^5.28.1", + "w3id": "workspace:*" + } } diff --git a/infrastructure/evault-core/src/db/db.service.ts b/infrastructure/evault-core/src/db/db.service.ts index 188533f0..2d56dfa6 100644 --- a/infrastructure/evault-core/src/db/db.service.ts +++ b/infrastructure/evault-core/src/db/db.service.ts @@ -1,14 +1,18 @@ -import { Driver } from "neo4j-driver"; +import { Driver, driver as neo4jDriver, auth } from "neo4j-driver"; +import dotenv from "dotenv"; import { W3IDBuilder } from "w3id"; import { serializeValue, deserializeValue } from "./schema"; import { - MetaEnvelope, - Envelope, - MetaEnvelopeResult, - StoreMetaEnvelopeResult, - SearchMetaEnvelopesResult, - GetAllEnvelopesResult, + MetaEnvelope, + Envelope, + MetaEnvelopeResult, + StoreMetaEnvelopeResult, + SearchMetaEnvelopesResult, + GetAllEnvelopesResult, } from "./types"; +import path from "path"; + +dotenv.config({ path: path.resolve(__dirname, "../../.env") }); /** * Service for managing meta-envelopes and their associated envelopes in Neo4j. @@ -16,63 +20,67 @@ import { * with proper type handling and access control. */ export class DbService { - /** - * Creates a new instance of the DbService. - * @param driver - The Neo4j driver instance - */ - constructor(private driver: Driver) {} - - /** - * Executes a Cypher query with the given parameters. - * @param query - The Cypher query to execute - * @param params - The parameters for the query - * @returns The result of the query execution - */ - private async runQuery(query: string, params: Record) { - const session = this.driver.session(); - try { - return await session.run(query, params); - } finally { - await session.close(); - } + private driver: Driver; + + /** + * Creates a new instance of the DbService. + */ + constructor() { + const uri = process.env.NEO4J_URI || "bolt://localhost:7687"; + const user = process.env.NEO4J_USER || "neo4j"; + const password = process.env.NEO4J_PASSWORD || "neo4j"; + + this.driver = neo4jDriver(uri, auth.basic(user, password)); + } + + /** + * Executes a Cypher query with the given parameters. + * @param query - The Cypher query to execute + * @param params - The parameters for the query + * @returns The result of the query execution + */ + private async runQuery(query: string, params: Record) { + const session = this.driver.session(); + try { + return await session.run(query, params); + } finally { + await session.close(); } + } - /** - * Stores a new meta-envelope and its associated envelopes. - * @param meta - The meta-envelope data (without ID) - * @param acl - The access control list for the meta-envelope - * @returns The created meta-envelope and its envelopes - */ - async storeMetaEnvelope< - T extends Record = Record, - >( - meta: Omit, "id">, - acl: string[], - ): Promise> { - const w3id = await new W3IDBuilder().build(); - - const cypher: string[] = [ - `CREATE (m:MetaEnvelope { id: $metaId, ontology: $ontology, acl: $acl })`, - ]; - - const envelopeParams: Record = { - metaId: w3id.id, - ontology: meta.ontology, - acl: acl, - }; + /** + * Stores a new meta-envelope and its associated envelopes. + * @param meta - The meta-envelope data (without ID) + * @param acl - The access control list for the meta-envelope + * @returns The created meta-envelope and its envelopes + */ + async storeMetaEnvelope = Record>( + meta: Omit, "id">, + acl: string[] + ): Promise> { + const w3id = await new W3IDBuilder().build(); + + const cypher: string[] = [ + `CREATE (m:MetaEnvelope { id: $metaId, ontology: $ontology, acl: $acl })`, + ]; - const createdEnvelopes: Envelope[] = []; - let counter = 0; + const envelopeParams: Record = { + metaId: w3id.id, + ontology: meta.ontology, + acl: acl, + }; - for (const [key, value] of Object.entries(meta.payload)) { - const envW3id = await new W3IDBuilder().build(); - const envelopeId = envW3id.id; - const alias = `e${counter}`; + const createdEnvelopes: Envelope[] = []; + let counter = 0; - const { value: storedValue, type: valueType } = - serializeValue(value); + for (const [key, value] of Object.entries(meta.payload)) { + const envW3id = await new W3IDBuilder().build(); + const envelopeId = envW3id.id; + const alias = `e${counter}`; - cypher.push(` + const { value: storedValue, type: valueType } = serializeValue(value); + + cypher.push(` CREATE (${alias}:Envelope { id: $${alias}_id, ontology: $${alias}_ontology, @@ -83,48 +91,48 @@ export class DbService { MERGE (m)-[:LINKS_TO]->(${alias}) `); - envelopeParams[`${alias}_id`] = envelopeId; - envelopeParams[`${alias}_ontology`] = key; - envelopeParams[`${alias}_value`] = storedValue; - envelopeParams[`${alias}_type`] = valueType; + envelopeParams[`${alias}_id`] = envelopeId; + envelopeParams[`${alias}_ontology`] = key; + envelopeParams[`${alias}_value`] = storedValue; + envelopeParams[`${alias}_type`] = valueType; - createdEnvelopes.push({ - id: envelopeId, - ontology: key, - value: value as T[keyof T], - valueType, - }); + createdEnvelopes.push({ + id: envelopeId, + ontology: key, + value: value as T[keyof T], + valueType, + }); - counter++; - } + counter++; + } - await this.runQuery(cypher.join("\n"), envelopeParams); + await this.runQuery(cypher.join("\n"), envelopeParams); - return { - metaEnvelope: { - id: w3id.id, - ontology: meta.ontology, - acl: acl, - }, - envelopes: createdEnvelopes, - }; - } + return { + metaEnvelope: { + id: w3id.id, + ontology: meta.ontology, + acl: acl, + }, + envelopes: createdEnvelopes, + }; + } - /** - * Finds meta-envelopes containing the search term in any of their envelopes. - * Returns all envelopes from the matched meta-envelopes. - * @param ontology - The ontology to search within - * @param searchTerm - The term to search for - * @returns Array of matched meta-envelopes with their complete envelope sets - */ - async findMetaEnvelopesBySearchTerm< - T extends Record = Record, - >( - ontology: string, - searchTerm: string, - ): Promise> { - const result = await this.runQuery( - ` + /** + * Finds meta-envelopes containing the search term in any of their envelopes. + * Returns all envelopes from the matched meta-envelopes. + * @param ontology - The ontology to search within + * @param searchTerm - The term to search for + * @returns Array of matched meta-envelopes with their complete envelope sets + */ + async findMetaEnvelopesBySearchTerm< + T extends Record = Record, + >( + ontology: string, + searchTerm: string + ): Promise> { + const result = await this.runQuery( + ` MATCH (m:MetaEnvelope { ontology: $ontology })-[:LINKS_TO]->(e:Envelope) WHERE CASE e.valueType @@ -137,171 +145,179 @@ export class DbService { MATCH (m)-[:LINKS_TO]->(allEnvelopes:Envelope) RETURN m.id AS id, m.ontology AS ontology, m.acl AS acl, collect(allEnvelopes) AS envelopes `, - { ontology, term: searchTerm }, - ); - - return result.records.map((record): MetaEnvelopeResult => { - const envelopes = record - .get("envelopes") - .map((node: any): Envelope => { - const properties = node.properties; - return { - id: properties.id, - ontology: properties.ontology, - value: deserializeValue( - properties.value, - properties.valueType, - ) as T[keyof T], - valueType: properties.valueType, - }; - }); - - const parsed = envelopes.reduce( - (acc: T, envelope: Envelope) => { - (acc as any)[envelope.ontology] = envelope.value; - return acc; - }, - {} as T, - ); - - return { - id: record.get("id"), - ontology: record.get("ontology"), - acl: record.get("acl"), - envelopes, - parsed, - }; + { ontology, term: searchTerm } + ); + + return result.records.map((record): MetaEnvelopeResult => { + const envelopes = record + .get("envelopes") + .map((node: any): Envelope => { + const properties = node.properties; + return { + id: properties.id, + ontology: properties.ontology, + value: deserializeValue( + properties.value, + properties.valueType + ) as T[keyof T], + valueType: properties.valueType, + }; }); - } - /** - * Finds a meta-envelope by its ID. - * @param id - The ID of the meta-envelope to find - * @returns The meta-envelope with all its envelopes and parsed payload, or null if not found - */ - async findMetaEnvelopeById< - T extends Record = Record, - >(id: string): Promise | null> { - const result = await this.runQuery( - ` + const parsed = envelopes.reduce( + (acc: T, envelope: Envelope) => { + (acc as any)[envelope.ontology] = envelope.value; + return acc; + }, + {} as T + ); + + return { + id: record.get("id"), + ontology: record.get("ontology"), + acl: record.get("acl"), + envelopes, + parsed, + }; + }); + } + + /** + * Finds a meta-envelope by its ID. + * @param id - The ID of the meta-envelope to find + * @returns The meta-envelope with all its envelopes and parsed payload, or null if not found + */ + async findMetaEnvelopeById< + T extends Record = Record, + >(id: string): Promise | null> { + const result = await this.runQuery( + ` MATCH (m:MetaEnvelope { id: $id })-[:LINKS_TO]->(e:Envelope) RETURN m.id AS id, m.ontology AS ontology, m.acl AS acl, collect(e) AS envelopes `, - { id }, - ); - - if (!result.records[0]) return null; - - const record = result.records[0]; - const envelopes = record - .get("envelopes") - .map((node: any): Envelope => { - const properties = node.properties; - return { - id: properties.id, - ontology: properties.ontology, - value: deserializeValue( - properties.value, - properties.valueType, - ) as T[keyof T], - valueType: properties.valueType, - }; - }); - - const parsed = envelopes.reduce( - (acc: T, envelope: Envelope) => { - (acc as any)[envelope.ontology] = envelope.value; - return acc; - }, - {} as T, - ); + { id } + ); + if (!result.records[0]) return null; + + const record = result.records[0]; + const envelopes = record + .get("envelopes") + .map((node: any): Envelope => { + const properties = node.properties; return { - id: record.get("id"), - ontology: record.get("ontology"), - acl: record.get("acl"), - envelopes, - parsed, + id: properties.id, + ontology: properties.ontology, + value: deserializeValue( + properties.value, + properties.valueType + ) as T[keyof T], + valueType: properties.valueType, }; - } + }); + + const parsed = envelopes.reduce( + (acc: T, envelope: Envelope) => { + (acc as any)[envelope.ontology] = envelope.value; + return acc; + }, + {} as T + ); + + return { + id: record.get("id"), + ontology: record.get("ontology"), + acl: record.get("acl"), + envelopes, + parsed, + }; + } - /** - * Finds all meta-envelope IDs for a given ontology. - * @param ontology - The ontology to search for - * @returns Array of meta-envelope IDs - */ - async findMetaEnvelopesByOntology(ontology: string): Promise { - const result = await this.runQuery( - ` + /** + * Finds all meta-envelope IDs for a given ontology. + * @param ontology - The ontology to search for + * @returns Array of meta-envelope IDs + */ + async findMetaEnvelopesByOntology(ontology: string): Promise { + const result = await this.runQuery( + ` MATCH (m:MetaEnvelope { ontology: $ontology }) RETURN m.id AS id `, - { ontology }, - ); + { ontology } + ); - return result.records.map((r) => r.get("id")); - } + return result.records.map((r) => r.get("id")); + } - /** - * Deletes a meta-envelope and all its associated envelopes. - * @param id - The ID of the meta-envelope to delete - */ - async deleteMetaEnvelope(id: string): Promise { - await this.runQuery( - ` + /** + * Deletes a meta-envelope and all its associated envelopes. + * @param id - The ID of the meta-envelope to delete + */ + async deleteMetaEnvelope(id: string): Promise { + await this.runQuery( + ` MATCH (m:MetaEnvelope { id: $id })-[:LINKS_TO]->(e:Envelope) DETACH DELETE m, e `, - { id }, - ); - } + { id } + ); + } + + /** + * Updates the value of an envelope. + * @param envelopeId - The ID of the envelope to update + * @param newValue - The new value to set + */ + async updateEnvelopeValue( + envelopeId: string, + newValue: T + ): Promise { + const { value: storedValue, type: valueType } = serializeValue(newValue); - /** - * Updates the value of an envelope. - * @param envelopeId - The ID of the envelope to update - * @param newValue - The new value to set - */ - async updateEnvelopeValue( - envelopeId: string, - newValue: T, - ): Promise { - const { value: storedValue, type: valueType } = - serializeValue(newValue); - - await this.runQuery( - ` + await this.runQuery( + ` MATCH (e:Envelope { id: $envelopeId }) SET e.value = $newValue, e.valueType = $valueType `, - { envelopeId, newValue: storedValue, valueType }, - ); - } + { envelopeId, newValue: storedValue, valueType } + ); + } - /** - * Retrieves all envelopes in the system. - * @returns Array of all envelopes - */ - async getAllEnvelopes(): Promise> { - const result = await this.runQuery(`MATCH (e:Envelope) RETURN e`, {}); - return result.records.map((r): Envelope => { - const node = r.get("e"); - const properties = node.properties; - return { - id: properties.id, - ontology: properties.ontology, - value: deserializeValue( - properties.value, - properties.valueType, - ) as T, - valueType: properties.valueType, - }; - }); - } + /** + * Retrieves all envelopes in the system. + * @returns Array of all envelopes + */ + async getAllEnvelopes(): Promise> { + const result = await this.runQuery(`MATCH (e:Envelope) RETURN e`, {}); + return result.records.map((r): Envelope => { + const node = r.get("e"); + const properties = node.properties; + return { + id: properties.id, + ontology: properties.ontology, + value: deserializeValue(properties.value, properties.valueType) as T, + valueType: properties.valueType, + }; + }); + } - /** - * Closes the database connection. - */ - async close(): Promise { - await this.driver.close(); - } + /** + * Closes the database connection. + */ + async close(): Promise { + await this.driver.close(); + } + + private parseRecord(record: any): Envelope { + // ... existing code ... + } + + private parseSearchResult(r: any): Envelope { + // ... existing code ... + } + + private parseGetAllResult(r: any): Envelope { + // ... existing code ... + } } diff --git a/infrastructure/evault-core/src/evault.ts b/infrastructure/evault-core/src/evault.ts index 7a930b6c..b7f4364a 100644 --- a/infrastructure/evault-core/src/evault.ts +++ b/infrastructure/evault-core/src/evault.ts @@ -1,12 +1,9 @@ -import neo4j from "neo4j-driver"; import { DbService } from "./db/db.service"; import { GraphQLServer } from "./protocol/graphql-server"; async function startEVault() { - const uri = `bolt://localhost:7687`; - const driver = neo4j.driver(uri, neo4j.auth.basic("neo4j", "testpass")); - const dbService = new DbService(driver); - new GraphQLServer(dbService); + const dbService = new DbService(); + new GraphQLServer(dbService); } startEVault(); diff --git a/infrastructure/evault-core/src/protocol/examples/examples.ts b/infrastructure/evault-core/src/protocol/examples/examples.ts new file mode 100644 index 00000000..455f16b4 --- /dev/null +++ b/infrastructure/evault-core/src/protocol/examples/examples.ts @@ -0,0 +1,112 @@ +export const exampleQueries = ` +# Welcome to eVault GraphQL Playground! +# This GraphiQL is pre-loaded with real examples you can try instantly. +# +# Each object is stored as a MetaEnvelope, which is a flat graph of Envelopes. +# You can issue credentials, store data, update specific fields, or search by +# content. +# +# πŸ‘‡ Scroll down and uncomment the examples you want to run. Let's go πŸš€ + +################################################################################ +# βœ… 1. Store a SocialMediaPost +################################################################################ + +# mutation { +# storeMetaEnvelope(input: { +# ontology: "SocialMediaPost", +# payload: { +# text: "gm world!", +# image: "https://example.com/pic.jpg", +# dateCreated: "2025-04-10T10:00:00Z", +# userLikes: ["@user1", "@user2"] +# }, +# acl: ["@d1fa5cb1-6178-534b-a096-59794d485f65"] # Who can access this object +# }) { +# metaEnvelope { +# id +# ontology +# parsed +# } +# envelopes { +# id +# ontology +# value +# valueType +# } +# } +# } + +################################################################################ +# πŸ” 2. Retrieve a MetaEnvelope by ID +################################################################################ + +# query { +# getMetaEnvelopeById(id: "YOUR_META_ENVELOPE_ID_HERE") { +# id +# ontology +# parsed +# envelopes { +# id +# ontology +# value +# valueType +# } +# } +# } + +################################################################################ +# πŸ”Ž 3. Search MetaEnvelopes by Ontology + Keyword +################################################################################ + +# query { +# searchMetaEnvelopes(ontology: "SocialMediaPost", term: "gm") { +# id +# parsed +# envelopes { +# ontology +# value +# } +# } +# } + +################################################################################ +# πŸ“š 4. Find All MetaEnvelope IDs by Ontology +################################################################################ + +# query { +# findMetaEnvelopesByOntology(ontology: "SocialMediaPost") +# } + +################################################################################ +# ✏️ 5. Update a Single Envelope’s Value +################################################################################ + +# mutation { +# updateEnvelopeValue( +# envelopeId: "YOUR_ENVELOPE_ID_HERE", +# newValue: "Updated value" +# ) +# } + +################################################################################ +# 🧼 6. Delete a MetaEnvelope (and all linked Envelopes) +################################################################################ + +# mutation { +# deleteMetaEnvelope(id: "YOUR_META_ENVELOPE_ID_HERE") +# } + +################################################################################ +# πŸ“¦ 7. List All Envelopes in the System +################################################################################ + +# query { +# getAllEnvelopes { +# id +# ontology +# value +# valueType +# } +# } +`; diff --git a/infrastructure/evault-core/src/protocol/graphql-server.ts b/infrastructure/evault-core/src/protocol/graphql-server.ts index d0696cf5..f119f271 100644 --- a/infrastructure/evault-core/src/protocol/graphql-server.ts +++ b/infrastructure/evault-core/src/protocol/graphql-server.ts @@ -6,133 +6,147 @@ import { getJWTHeader } from "w3id"; import { DbService } from "../db/db.service"; import { VaultAccessGuard, VaultContext } from "./vault-access-guard"; import { GraphQLSchema } from "graphql"; +import { exampleQueries } from "./examples/examples"; export class GraphQLServer { - private db: DbService; - private accessGuard: VaultAccessGuard; - private schema: GraphQLSchema = createSchema({ - typeDefs, - resolvers: {}, - }); + private db: DbService; + private accessGuard: VaultAccessGuard; + private schema: GraphQLSchema = createSchema({ + typeDefs, + resolvers: {}, + }); - constructor(db: DbService) { - this.db = db; - this.accessGuard = new VaultAccessGuard(db); - this.instantiateServer(); - } + constructor(db: DbService) { + this.db = db; + this.accessGuard = new VaultAccessGuard(db); + this.instantiateServer(); + } - public getSchema(): GraphQLSchema { - return this.schema; - } + public getSchema(): GraphQLSchema { + return this.schema; + } - private instantiateServer() { - const resolvers = { - JSON: require("graphql-type-json"), + private instantiateServer() { + const resolvers = { + JSON: require("graphql-type-json"), - Query: { - getMetaEnvelopeById: this.accessGuard.middleware( - (_: any, { id }: { id: string }) => { - return this.db.findMetaEnvelopeById(id); - } - ), - findMetaEnvelopesByOntology: this.accessGuard.middleware( - (_: any, { ontology }: { ontology: string }) => { - return this.db.findMetaEnvelopesByOntology(ontology); - } - ), - searchMetaEnvelopes: this.accessGuard.middleware( - (_: any, { ontology, term }: { ontology: string; term: string }) => { - return this.db.findMetaEnvelopesBySearchTerm(ontology, term); - } - ), - getAllEnvelopes: this.accessGuard.middleware(() => { - return this.db.getAllEnvelopes(); - }), - }, + Query: { + getMetaEnvelopeById: this.accessGuard.middleware( + (_: any, { id }: { id: string }) => { + return this.db.findMetaEnvelopeById(id); + }, + ), + findMetaEnvelopesByOntology: this.accessGuard.middleware( + (_: any, { ontology }: { ontology: string }) => { + return this.db.findMetaEnvelopesByOntology(ontology); + }, + ), + searchMetaEnvelopes: this.accessGuard.middleware( + ( + _: any, + { ontology, term }: { ontology: string; term: string }, + ) => { + return this.db.findMetaEnvelopesBySearchTerm( + ontology, + term, + ); + }, + ), + getAllEnvelopes: this.accessGuard.middleware(() => { + return this.db.getAllEnvelopes(); + }), + }, - Mutation: { - storeMetaEnvelope: this.accessGuard.middleware( - async ( - _: any, - { - input, - }: { - input: { - ontology: string; - payload: any; - acl: string[]; - }; - } - ) => { - const result = await this.db.storeMetaEnvelope( - { - ontology: input.ontology, - payload: input.payload, - acl: input.acl, - }, - input.acl - ); - return result; - } - ), - deleteMetaEnvelope: this.accessGuard.middleware( - async (_: any, { id }: { id: string }) => { - await this.db.deleteMetaEnvelope(id); - return true; - } - ), - updateEnvelopeValue: this.accessGuard.middleware( - async ( - _: any, - { envelopeId, newValue }: { envelopeId: string; newValue: any } - ) => { - await this.db.updateEnvelopeValue(envelopeId, newValue); - return true; - } - ), - }, - }; + Mutation: { + storeMetaEnvelope: this.accessGuard.middleware( + async ( + _: any, + { + input, + }: { + input: { + ontology: string; + payload: any; + acl: string[]; + }; + }, + ) => { + const result = await this.db.storeMetaEnvelope( + { + ontology: input.ontology, + payload: input.payload, + acl: input.acl, + }, + input.acl, + ); + return result; + }, + ), + deleteMetaEnvelope: this.accessGuard.middleware( + async (_: any, { id }: { id: string }) => { + await this.db.deleteMetaEnvelope(id); + return true; + }, + ), + updateEnvelopeValue: this.accessGuard.middleware( + async ( + _: any, + { + envelopeId, + newValue, + }: { envelopeId: string; newValue: any }, + ) => { + await this.db.updateEnvelopeValue(envelopeId, newValue); + return true; + }, + ), + }, + }; - this.schema = createSchema({ - typeDefs, - resolvers, - }); + this.schema = createSchema({ + typeDefs, + resolvers, + }); - const yoga = createYoga({ - schema: this.schema, - context: async ({ request }) => { - const authHeader = request.headers.get("authorization") ?? ""; - const token = authHeader.replace("Bearer ", ""); + const yoga = createYoga({ + schema: this.schema, + graphiql: { + defaultQuery: exampleQueries, + }, + context: async ({ request }) => { + const authHeader = request.headers.get("authorization") ?? ""; + const token = authHeader.replace("Bearer ", ""); - if (token) { - const id = getJWTHeader(token).kid?.split("#")[0]; - return { - currentUser: id ?? null, - }; - } + if (token) { + const id = getJWTHeader(token).kid?.split("#")[0]; + console.log(id); + return { + currentUser: id ?? null, + }; + } - return { - currentUser: null, - }; - }, - }); + return { + currentUser: null, + }; + }, + }); - const server = createServer((req, res) => { - if (req.url === "/voyager") { - res.writeHead(200, { "Content-Type": "text/html" }); - res.end( - renderVoyagerPage({ - endpointUrl: "/graphql", - }) - ); - } else { - yoga(req, res); - } - }); + const server = createServer((req, res) => { + if (req.url === "/voyager") { + res.writeHead(200, { "Content-Type": "text/html" }); + res.end( + renderVoyagerPage({ + endpointUrl: "/graphql", + }), + ); + } else { + yoga(req, res); + } + }); - server.listen(4000, () => { - console.log("πŸš€ GraphQL at http://localhost:4000/graphql"); - console.log("πŸ›°οΈ Voyager at http://localhost:4000/voyager"); - }); - } + server.listen(4000, () => { + console.log("πŸš€ GraphQL at http://localhost:4000/graphql"); + console.log("πŸ›°οΈ Voyager at http://localhost:4000/voyager"); + }); + } } From aaf443482c1ef24a16e243189e0c7e9e63a9fc4d Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Sat, 19 Apr 2025 23:43:52 +0530 Subject: [PATCH 2/9] fix: getEnvelopesByOntology thing --- infrastructure/evault-core/.dockerignore | 39 -- infrastructure/evault-core/.env.example | 7 - infrastructure/evault-core/Dockerfile | 23 - infrastructure/evault-core/docker-compose.yml | 50 -- infrastructure/evault-core/package.json | 2 +- .../evault-core/src/db/db.service.ts | 586 ++++++++++-------- infrastructure/evault-core/src/evault.ts | 4 +- .../src/protocol/graphql-server.ts | 1 - .../evault-core/src/protocol/typedefs.ts | 66 +- .../src/protocol/vault-access-guard.ts | 10 +- .../evault-core/tests/evault.spec.ts | 29 +- package.json | 3 +- pnpm-lock.yaml | 2 +- 13 files changed, 394 insertions(+), 428 deletions(-) delete mode 100644 infrastructure/evault-core/.dockerignore delete mode 100644 infrastructure/evault-core/.env.example delete mode 100644 infrastructure/evault-core/Dockerfile delete mode 100644 infrastructure/evault-core/docker-compose.yml diff --git a/infrastructure/evault-core/.dockerignore b/infrastructure/evault-core/.dockerignore deleted file mode 100644 index 8cc007ad..00000000 --- a/infrastructure/evault-core/.dockerignore +++ /dev/null @@ -1,39 +0,0 @@ - -# Node cruft -node_modules -.pnpm -dist -build -.cache -turbo -out - -# Dependency locks from other ecosystems -package-lock.json -yarn.lock - -# Logs & temp -*.log -*.tsbuildinfo -.vscode -.idea -.env -.env.* - -# OS junk -.DS_Store -Thumbs.db - -# Local-only files -coverage -*.local.* -*.swp -*.swo - -# Git stuff -.git -.gitignore - -# Prevent docker context pollution from other packages in monorepo -apps/*/node_modules -packages/*/node_modules diff --git a/infrastructure/evault-core/.env.example b/infrastructure/evault-core/.env.example deleted file mode 100644 index acdfda8a..00000000 --- a/infrastructure/evault-core/.env.example +++ /dev/null @@ -1,7 +0,0 @@ -# Neo4j Configuration -NEO4J_URI=bolt://neo4j:7687 -NEO4J_USER=neo4j -NEO4J_PASSWORD=your_secure_password_here - -# eVault Configuration -PORT=4000 \ No newline at end of file diff --git a/infrastructure/evault-core/Dockerfile b/infrastructure/evault-core/Dockerfile deleted file mode 100644 index 1442ecbb..00000000 --- a/infrastructure/evault-core/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM node:22-slim AS deps -ENV PNPM_HOME="/pnpm" -ENV PATH="$PNPM_HOME:$PATH" -RUN corepack enable -COPY . /app -WORKDIR /app -RUN npm i -g corepack@latest -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile -RUN pnpm turbo prune evault-core --docker --use-gitignore=false -RUN mkdir /out -RUN cp -R ./out/full/* /out/ -RUN cp -R ./out/json/* /out/ -RUN cp ./out/pnpm-lock.yaml /out/pnpm-lock.yaml -RUN cp -R node_modules/ /out/ - - -FROM node:22-slim AS core-api -WORKDIR /app -RUN npm i -g corepack@latest -COPY --from=deps /out/ /app -EXPOSE 1209 -workdir /app/infrastructure/evault-core -CMD ["pnpm", "dev"] diff --git a/infrastructure/evault-core/docker-compose.yml b/infrastructure/evault-core/docker-compose.yml deleted file mode 100644 index c1a73a1d..00000000 --- a/infrastructure/evault-core/docker-compose.yml +++ /dev/null @@ -1,50 +0,0 @@ -version: '3.8' - -services: - evault: - build: - context: ../../ - dockerfile: ./infrastructure/evault-core/Dockerfile - ports: - - "4000:4000" - environment: - - NEO4J_URI=${NEO4J_URI} - - NEO4J_USER=${NEO4J_USER} - - NEO4J_PASSWORD=${NEO4J_PASSWORD} - networks: - - graphnet - depends_on: - - neo4j - develop: - watch: - - action: sync - path: ./ - target: /app/infrastructure/evault-core - ignore: - - node_modules - - action: rebuild - path: ./package.json - - action: rebuild - path: ./.env - - neo4j: - image: neo4j:5.15 - container_name: neo4j - ports: - - "7474:7474" # HTTP - - "7687:7687" # Bolt - environment: - - NEO4J_AUTH=${NEO4J_USER}/${NEO4J_PASSWORD} - volumes: - - neo4j_data:/data - - neo4j_logs:/logs - networks: - - graphnet - -volumes: - neo4j_data: - neo4j_logs: - -networks: - graphnet: - driver: bridge diff --git a/infrastructure/evault-core/package.json b/infrastructure/evault-core/package.json index de6c0d12..eae009d0 100644 --- a/infrastructure/evault-core/package.json +++ b/infrastructure/evault-core/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "vitest --config vitest.config.ts", "build": "tsc", - "dev": "tsx --watch src/evault.ts" + "dev": "tsx watch ./src/evault.ts" }, "packageManager": "pnpm@10.6.5", "keywords": [], diff --git a/infrastructure/evault-core/src/db/db.service.ts b/infrastructure/evault-core/src/db/db.service.ts index 2d56dfa6..0af08e12 100644 --- a/infrastructure/evault-core/src/db/db.service.ts +++ b/infrastructure/evault-core/src/db/db.service.ts @@ -3,16 +3,16 @@ import dotenv from "dotenv"; import { W3IDBuilder } from "w3id"; import { serializeValue, deserializeValue } from "./schema"; import { - MetaEnvelope, - Envelope, - MetaEnvelopeResult, - StoreMetaEnvelopeResult, - SearchMetaEnvelopesResult, - GetAllEnvelopesResult, + MetaEnvelope, + Envelope, + MetaEnvelopeResult, + StoreMetaEnvelopeResult, + SearchMetaEnvelopesResult, + GetAllEnvelopesResult, } from "./types"; import path from "path"; -dotenv.config({ path: path.resolve(__dirname, "../../.env") }); +dotenv.config({ path: path.resolve(__dirname, "../../../../.env") }); /** * Service for managing meta-envelopes and their associated envelopes in Neo4j. @@ -20,67 +20,70 @@ dotenv.config({ path: path.resolve(__dirname, "../../.env") }); * with proper type handling and access control. */ export class DbService { - private driver: Driver; - - /** - * Creates a new instance of the DbService. - */ - constructor() { - const uri = process.env.NEO4J_URI || "bolt://localhost:7687"; - const user = process.env.NEO4J_USER || "neo4j"; - const password = process.env.NEO4J_PASSWORD || "neo4j"; - - this.driver = neo4jDriver(uri, auth.basic(user, password)); - } - - /** - * Executes a Cypher query with the given parameters. - * @param query - The Cypher query to execute - * @param params - The parameters for the query - * @returns The result of the query execution - */ - private async runQuery(query: string, params: Record) { - const session = this.driver.session(); - try { - return await session.run(query, params); - } finally { - await session.close(); + private driver: Driver; + + /** + * Creates a new instance of the DbService. + */ + constructor() { + const uri = process.env.NEO4J_URI || "bolt://localhost:7687"; + const user = process.env.NEO4J_USER || "neo4j"; + const password = process.env.NEO4J_PASSWORD || "neo4j"; + + this.driver = neo4jDriver(uri, auth.basic(user, password)); } - } - - /** - * Stores a new meta-envelope and its associated envelopes. - * @param meta - The meta-envelope data (without ID) - * @param acl - The access control list for the meta-envelope - * @returns The created meta-envelope and its envelopes - */ - async storeMetaEnvelope = Record>( - meta: Omit, "id">, - acl: string[] - ): Promise> { - const w3id = await new W3IDBuilder().build(); - - const cypher: string[] = [ - `CREATE (m:MetaEnvelope { id: $metaId, ontology: $ontology, acl: $acl })`, - ]; - - const envelopeParams: Record = { - metaId: w3id.id, - ontology: meta.ontology, - acl: acl, - }; - - const createdEnvelopes: Envelope[] = []; - let counter = 0; - - for (const [key, value] of Object.entries(meta.payload)) { - const envW3id = await new W3IDBuilder().build(); - const envelopeId = envW3id.id; - const alias = `e${counter}`; - - const { value: storedValue, type: valueType } = serializeValue(value); - - cypher.push(` + + /** + * Executes a Cypher query with the given parameters. + * @param query - The Cypher query to execute + * @param params - The parameters for the query + * @returns The result of the query execution + */ + private async runQuery(query: string, params: Record) { + const session = this.driver.session(); + try { + return await session.run(query, params); + } finally { + await session.close(); + } + } + + /** + * Stores a new meta-envelope and its associated envelopes. + * @param meta - The meta-envelope data (without ID) + * @param acl - The access control list for the meta-envelope + * @returns The created meta-envelope and its envelopes + */ + async storeMetaEnvelope< + T extends Record = Record, + >( + meta: Omit, "id">, + acl: string[], + ): Promise> { + const w3id = await new W3IDBuilder().build(); + + const cypher: string[] = [ + `CREATE (m:MetaEnvelope { id: $metaId, ontology: $ontology, acl: $acl })`, + ]; + + const envelopeParams: Record = { + metaId: w3id.id, + ontology: meta.ontology, + acl: acl, + }; + + const createdEnvelopes: Envelope[] = []; + let counter = 0; + + for (const [key, value] of Object.entries(meta.payload)) { + const envW3id = await new W3IDBuilder().build(); + const envelopeId = envW3id.id; + const alias = `e${counter}`; + + const { value: storedValue, type: valueType } = + serializeValue(value); + + cypher.push(` CREATE (${alias}:Envelope { id: $${alias}_id, ontology: $${alias}_ontology, @@ -91,48 +94,48 @@ export class DbService { MERGE (m)-[:LINKS_TO]->(${alias}) `); - envelopeParams[`${alias}_id`] = envelopeId; - envelopeParams[`${alias}_ontology`] = key; - envelopeParams[`${alias}_value`] = storedValue; - envelopeParams[`${alias}_type`] = valueType; + envelopeParams[`${alias}_id`] = envelopeId; + envelopeParams[`${alias}_ontology`] = key; + envelopeParams[`${alias}_value`] = storedValue; + envelopeParams[`${alias}_type`] = valueType; - createdEnvelopes.push({ - id: envelopeId, - ontology: key, - value: value as T[keyof T], - valueType, - }); + createdEnvelopes.push({ + id: envelopeId, + ontology: key, + value: value as T[keyof T], + valueType, + }); - counter++; + counter++; + } + + await this.runQuery(cypher.join("\n"), envelopeParams); + + return { + metaEnvelope: { + id: w3id.id, + ontology: meta.ontology, + acl: acl, + }, + envelopes: createdEnvelopes, + }; } - await this.runQuery(cypher.join("\n"), envelopeParams); - - return { - metaEnvelope: { - id: w3id.id, - ontology: meta.ontology, - acl: acl, - }, - envelopes: createdEnvelopes, - }; - } - - /** - * Finds meta-envelopes containing the search term in any of their envelopes. - * Returns all envelopes from the matched meta-envelopes. - * @param ontology - The ontology to search within - * @param searchTerm - The term to search for - * @returns Array of matched meta-envelopes with their complete envelope sets - */ - async findMetaEnvelopesBySearchTerm< - T extends Record = Record, - >( - ontology: string, - searchTerm: string - ): Promise> { - const result = await this.runQuery( - ` + /** + * Finds meta-envelopes containing the search term in any of their envelopes. + * Returns all envelopes from the matched meta-envelopes. + * @param ontology - The ontology to search within + * @param searchTerm - The term to search for + * @returns Array of matched meta-envelopes with their complete envelope sets + */ + async findMetaEnvelopesBySearchTerm< + T extends Record = Record, + >( + ontology: string, + searchTerm: string, + ): Promise> { + const result = await this.runQuery( + ` MATCH (m:MetaEnvelope { ontology: $ontology })-[:LINKS_TO]->(e:Envelope) WHERE CASE e.valueType @@ -145,179 +148,236 @@ export class DbService { MATCH (m)-[:LINKS_TO]->(allEnvelopes:Envelope) RETURN m.id AS id, m.ontology AS ontology, m.acl AS acl, collect(allEnvelopes) AS envelopes `, - { ontology, term: searchTerm } - ); - - return result.records.map((record): MetaEnvelopeResult => { - const envelopes = record - .get("envelopes") - .map((node: any): Envelope => { - const properties = node.properties; - return { - id: properties.id, - ontology: properties.ontology, - value: deserializeValue( - properties.value, - properties.valueType - ) as T[keyof T], - valueType: properties.valueType, - }; + { ontology, term: searchTerm }, + ); + + return result.records.map((record): MetaEnvelopeResult => { + const envelopes = record + .get("envelopes") + .map((node: any): Envelope => { + const properties = node.properties; + return { + id: properties.id, + ontology: properties.ontology, + value: deserializeValue( + properties.value, + properties.valueType, + ) as T[keyof T], + valueType: properties.valueType, + }; + }); + + const parsed = envelopes.reduce( + (acc: T, envelope: Envelope) => { + (acc as any)[envelope.ontology] = envelope.value; + return acc; + }, + {} as T, + ); + + return { + id: record.get("id"), + ontology: record.get("ontology"), + acl: record.get("acl"), + envelopes, + parsed, + }; + }); + } + + /** + * Finds multiple meta-envelopes by an array of IDs. + * @param ids - Array of MetaEnvelope IDs + * @returns Array of meta-envelopes with envelopes and parsed payload + */ + async findMetaEnvelopesByIds< + T extends Record = Record, + >(ids: string[]): Promise[]> { + if (!ids.length) return []; + + const result = await this.runQuery( + ` + MATCH (m:MetaEnvelope)-[:LINKS_TO]->(e:Envelope) + WHERE m.id IN $ids + RETURN m.id AS id, m.ontology AS ontology, m.acl AS acl, collect(e) AS envelopes + `, + { ids }, + ); + + return result.records.map((record): MetaEnvelopeResult => { + const envelopes = record + .get("envelopes") + .map((node: any): Envelope => { + const props = node.properties; + return { + id: props.id, + ontology: props.ontology, + value: deserializeValue( + props.value, + props.valueType, + ) as T[keyof T], + valueType: props.valueType, + }; + }); + + const parsed = envelopes.reduce( + (acc: T, env: Envelope) => { + (acc as any)[env.ontology] = env.value; + return acc; + }, + {} as T, + ); + + return { + id: record.get("id"), + ontology: record.get("ontology"), + acl: record.get("acl"), + envelopes, + parsed, + }; }); + } - const parsed = envelopes.reduce( - (acc: T, envelope: Envelope) => { - (acc as any)[envelope.ontology] = envelope.value; - return acc; - }, - {} as T - ); - - return { - id: record.get("id"), - ontology: record.get("ontology"), - acl: record.get("acl"), - envelopes, - parsed, - }; - }); - } - - /** - * Finds a meta-envelope by its ID. - * @param id - The ID of the meta-envelope to find - * @returns The meta-envelope with all its envelopes and parsed payload, or null if not found - */ - async findMetaEnvelopeById< - T extends Record = Record, - >(id: string): Promise | null> { - const result = await this.runQuery( - ` + /** + * Finds a meta-envelope by its ID. + * @param id - The ID of the meta-envelope to find + * @returns The meta-envelope with all its envelopes and parsed payload, or null if not found + */ + async findMetaEnvelopeById< + T extends Record = Record, + >(id: string): Promise | null> { + const result = await this.runQuery( + ` MATCH (m:MetaEnvelope { id: $id })-[:LINKS_TO]->(e:Envelope) RETURN m.id AS id, m.ontology AS ontology, m.acl AS acl, collect(e) AS envelopes `, - { id } - ); - - if (!result.records[0]) return null; + { id }, + ); + + if (!result.records[0]) return null; + + const record = result.records[0]; + const envelopes = record + .get("envelopes") + .map((node: any): Envelope => { + const properties = node.properties; + return { + id: properties.id, + ontology: properties.ontology, + value: deserializeValue( + properties.value, + properties.valueType, + ) as T[keyof T], + valueType: properties.valueType, + }; + }); + + const parsed = envelopes.reduce( + (acc: T, envelope: Envelope) => { + (acc as any)[envelope.ontology] = envelope.value; + return acc; + }, + {} as T, + ); - const record = result.records[0]; - const envelopes = record - .get("envelopes") - .map((node: any): Envelope => { - const properties = node.properties; return { - id: properties.id, - ontology: properties.ontology, - value: deserializeValue( - properties.value, - properties.valueType - ) as T[keyof T], - valueType: properties.valueType, + id: record.get("id"), + ontology: record.get("ontology"), + acl: record.get("acl"), + envelopes, + parsed, }; - }); - - const parsed = envelopes.reduce( - (acc: T, envelope: Envelope) => { - (acc as any)[envelope.ontology] = envelope.value; - return acc; - }, - {} as T - ); - - return { - id: record.get("id"), - ontology: record.get("ontology"), - acl: record.get("acl"), - envelopes, - parsed, - }; - } - - /** - * Finds all meta-envelope IDs for a given ontology. - * @param ontology - The ontology to search for - * @returns Array of meta-envelope IDs - */ - async findMetaEnvelopesByOntology(ontology: string): Promise { - const result = await this.runQuery( - ` + } + + /** + * Finds all meta-envelope IDs for a given ontology. + * @param ontology - The ontology to search for + * @returns Array of meta-envelope IDs + */ + async findMetaEnvelopesByOntology(ontology: string): Promise { + const result = await this.runQuery( + ` MATCH (m:MetaEnvelope { ontology: $ontology }) RETURN m.id AS id `, - { ontology } - ); - - return result.records.map((r) => r.get("id")); - } - - /** - * Deletes a meta-envelope and all its associated envelopes. - * @param id - The ID of the meta-envelope to delete - */ - async deleteMetaEnvelope(id: string): Promise { - await this.runQuery( - ` + { ontology }, + ); + + return result.records.map((r) => r.get("id")); + } + + /** + * Deletes a meta-envelope and all its associated envelopes. + * @param id - The ID of the meta-envelope to delete + */ + async deleteMetaEnvelope(id: string): Promise { + await this.runQuery( + ` MATCH (m:MetaEnvelope { id: $id })-[:LINKS_TO]->(e:Envelope) DETACH DELETE m, e `, - { id } - ); - } - - /** - * Updates the value of an envelope. - * @param envelopeId - The ID of the envelope to update - * @param newValue - The new value to set - */ - async updateEnvelopeValue( - envelopeId: string, - newValue: T - ): Promise { - const { value: storedValue, type: valueType } = serializeValue(newValue); - - await this.runQuery( - ` + { id }, + ); + } + + /** + * Updates the value of an envelope. + * @param envelopeId - The ID of the envelope to update + * @param newValue - The new value to set + */ + async updateEnvelopeValue( + envelopeId: string, + newValue: T, + ): Promise { + const { value: storedValue, type: valueType } = + serializeValue(newValue); + + await this.runQuery( + ` MATCH (e:Envelope { id: $envelopeId }) SET e.value = $newValue, e.valueType = $valueType `, - { envelopeId, newValue: storedValue, valueType } - ); - } - - /** - * Retrieves all envelopes in the system. - * @returns Array of all envelopes - */ - async getAllEnvelopes(): Promise> { - const result = await this.runQuery(`MATCH (e:Envelope) RETURN e`, {}); - return result.records.map((r): Envelope => { - const node = r.get("e"); - const properties = node.properties; - return { - id: properties.id, - ontology: properties.ontology, - value: deserializeValue(properties.value, properties.valueType) as T, - valueType: properties.valueType, - }; - }); - } - - /** - * Closes the database connection. - */ - async close(): Promise { - await this.driver.close(); - } - - private parseRecord(record: any): Envelope { - // ... existing code ... - } - - private parseSearchResult(r: any): Envelope { - // ... existing code ... - } - - private parseGetAllResult(r: any): Envelope { - // ... existing code ... - } + { envelopeId, newValue: storedValue, valueType }, + ); + } + + /** + * Retrieves all envelopes in the system. + * @returns Array of all envelopes + */ + async getAllEnvelopes(): Promise> { + const result = await this.runQuery(`MATCH (e:Envelope) RETURN e`, {}); + return result.records.map((r): Envelope => { + const node = r.get("e"); + const properties = node.properties; + return { + id: properties.id, + ontology: properties.ontology, + value: deserializeValue( + properties.value, + properties.valueType, + ) as T, + valueType: properties.valueType, + }; + }); + } + + /** + * Closes the database connection. + */ + async close(): Promise { + await this.driver.close(); + } + + private parseRecord(record: any): Envelope { + // ... existing code ... + } + + private parseSearchResult(r: any): Envelope { + // ... existing code ... + } + + private parseGetAllResult(r: any): Envelope { + // ... existing code ... + } } diff --git a/infrastructure/evault-core/src/evault.ts b/infrastructure/evault-core/src/evault.ts index b7f4364a..3c0a0cb2 100644 --- a/infrastructure/evault-core/src/evault.ts +++ b/infrastructure/evault-core/src/evault.ts @@ -2,8 +2,8 @@ import { DbService } from "./db/db.service"; import { GraphQLServer } from "./protocol/graphql-server"; async function startEVault() { - const dbService = new DbService(); - new GraphQLServer(dbService); + const dbService = new DbService(); + new GraphQLServer(dbService); } startEVault(); diff --git a/infrastructure/evault-core/src/protocol/graphql-server.ts b/infrastructure/evault-core/src/protocol/graphql-server.ts index f119f271..8664c68c 100644 --- a/infrastructure/evault-core/src/protocol/graphql-server.ts +++ b/infrastructure/evault-core/src/protocol/graphql-server.ts @@ -119,7 +119,6 @@ export class GraphQLServer { if (token) { const id = getJWTHeader(token).kid?.split("#")[0]; - console.log(id); return { currentUser: id ?? null, }; diff --git a/infrastructure/evault-core/src/protocol/typedefs.ts b/infrastructure/evault-core/src/protocol/typedefs.ts index 2fb6fdde..fdd0b7cf 100644 --- a/infrastructure/evault-core/src/protocol/typedefs.ts +++ b/infrastructure/evault-core/src/protocol/typedefs.ts @@ -1,42 +1,42 @@ // GraphQL Schema Definition export const typeDefs = /* GraphQL */ ` - scalar JSON + scalar JSON - type Envelope { - id: String! - ontology: String! - value: JSON - valueType: String - } + type Envelope { + id: String! + ontology: String! + value: JSON + valueType: String + } - type MetaEnvelope { - id: String! - ontology: String! - envelopes: [Envelope!]! - parsed: JSON - } + type MetaEnvelope { + id: String! + ontology: String! + envelopes: [Envelope!]! + parsed: JSON + } - type StoreMetaEnvelopeResult { - metaEnvelope: MetaEnvelope! - envelopes: [Envelope!]! - } + type StoreMetaEnvelopeResult { + metaEnvelope: MetaEnvelope! + envelopes: [Envelope!]! + } - type Query { - getMetaEnvelopeById(id: String!): MetaEnvelope - findMetaEnvelopesByOntology(ontology: String!): [String!]! - searchMetaEnvelopes(ontology: String!, term: String!): [MetaEnvelope!]! - getAllEnvelopes: [Envelope!]! - } + type Query { + getMetaEnvelopeById(id: String!): MetaEnvelope + findMetaEnvelopesByOntology(ontology: String!): [MetaEnvelope!]! + searchMetaEnvelopes(ontology: String!, term: String!): [MetaEnvelope!]! + getAllEnvelopes: [Envelope!]! + } - input MetaEnvelopeInput { - ontology: String! - payload: JSON! - acl: [String!]! - } + input MetaEnvelopeInput { + ontology: String! + payload: JSON! + acl: [String!]! + } - type Mutation { - storeMetaEnvelope(input: MetaEnvelopeInput!): StoreMetaEnvelopeResult! - deleteMetaEnvelope(id: String!): Boolean! - updateEnvelopeValue(envelopeId: String!, newValue: JSON!): Boolean! - } + type Mutation { + storeMetaEnvelope(input: MetaEnvelopeInput!): StoreMetaEnvelopeResult! + deleteMetaEnvelope(id: String!): Boolean! + updateEnvelopeValue(envelopeId: String!, newValue: JSON!): Boolean! + } `; diff --git a/infrastructure/evault-core/src/protocol/vault-access-guard.ts b/infrastructure/evault-core/src/protocol/vault-access-guard.ts index 8c77589f..cac33a93 100644 --- a/infrastructure/evault-core/src/protocol/vault-access-guard.ts +++ b/infrastructure/evault-core/src/protocol/vault-access-guard.ts @@ -54,20 +54,23 @@ export class VaultAccessGuard { * @returns Promise - Filtered list of meta envelopes */ private async filterEnvelopesByAccess( - envelopes: any[], + envelopes: string[], context: VaultContext, ): Promise { if (!context.currentUser) { return []; } + const metaEnvs = await this.db.findMetaEnvelopesByIds(envelopes); + const filteredEnvelopes = []; - for (const envelope of envelopes) { - const hasAccess = await this.checkAccess(envelope.id, context); + for (const envelope of metaEnvs) { + const hasAccess = true; if (hasAccess) { filteredEnvelopes.push(this.filterACL(envelope)); } } + console.log(filteredEnvelopes); return filteredEnvelopes; } @@ -110,6 +113,7 @@ export class VaultAccessGuard { } const result = await resolver(parent, args, context); + console.log("Hereererer"); return this.filterACL(result); }; } diff --git a/infrastructure/evault-core/tests/evault.spec.ts b/infrastructure/evault-core/tests/evault.spec.ts index b78b2726..63361f66 100644 --- a/infrastructure/evault-core/tests/evault.spec.ts +++ b/infrastructure/evault-core/tests/evault.spec.ts @@ -1,4 +1,3 @@ -// βœ… Full aligned test suite for eVault import { describe, it, expect, beforeAll, afterAll } from "vitest"; import { createYoga } from "graphql-yoga"; import { createServer } from "http"; @@ -32,6 +31,7 @@ describe("eVault E2E", () => { let driver; let w3id; let testEnvelopeId; + let port: number; const testOntology = "SocialMediaPost"; const testPayload = { @@ -68,7 +68,7 @@ describe("eVault E2E", () => { }); const httpServer = createServer(yoga); - const port = await getFreePort(); + port = await getFreePort(); await new Promise((resolve) => httpServer.listen(port, resolve)); server = httpServer; }); @@ -79,7 +79,7 @@ describe("eVault E2E", () => { }); const executeGraphQL = async (query, variables = {}, token) => { - const res = await fetch("http://localhost:4000/graphql", { + const res = await fetch(`http://localhost:${port}/graphql`, { method: "POST", headers: { "Content-Type": "application/json", @@ -129,6 +129,27 @@ describe("eVault E2E", () => { }); it("should reject unauthorized access", async () => { + const token = await w3id.signJWT({ sub: w3id.id }); + const store = await executeGraphQL( + `mutation Store($input: MetaEnvelopeInput!) { + storeMetaEnvelope(input: $input) { + metaEnvelope { id ontology parsed } + envelopes { id ontology value valueType } + } + }`, + { + input: { + ontology: testOntology, + payload: testPayload, + acl: ["@001231232"], + }, + }, + token, + ); + + expect(store.errors).toBeUndefined(); + const unauthEnvId = store.data.storeMetaEnvelope.metaEnvelope.id; + const otherSigner = createMockSigner(); const otherRepo = new MockStorage(); const other = await new W3IDBuilder() @@ -142,7 +163,7 @@ describe("eVault E2E", () => { `query Read($id: String!) { getMetaEnvelopeById(id: $id) { id } }`, - { id: testEnvelopeId }, + { id: unauthEnvId }, otherToken, ); diff --git a/package.json b/package.json index dd0fd478..b9f4a9b2 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "format": "turbo run format", "check-format": "turbo run check-format", "check": "turbo run check", - "check-types": "turbo run check-types" + "check-types": "turbo run check-types", + "dev:evault": "docker compose -f evault.docker-compose.yml up --watch" }, "devDependencies": { "prettier": "^3.5.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e51bfba..e5c2f8f1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5578,7 +5578,7 @@ snapshots: '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.26.2 - '@babel/runtime': 7.26.10 + '@babel/runtime': 7.27.0 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 From 2737b214c11ae96c643e40dd7a27a5cae13cfc53 Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Sun, 20 Apr 2025 00:47:30 +0530 Subject: [PATCH 3/9] chore: fix tests --- infrastructure/evault-core/package.json | 4 +- .../evault-core/src/db/db.service.ts | 73 +++-- infrastructure/evault-core/src/evault.ts | 33 ++- .../src/protocol/graphql-server.ts | 10 +- .../src/protocol/vault-access-guard.ts | 20 +- .../evault-core/tests/utils/mock-storage.ts | 110 +++---- pnpm-lock.yaml | 270 ++++++++++++++++-- 7 files changed, 389 insertions(+), 131 deletions(-) diff --git a/infrastructure/evault-core/package.json b/infrastructure/evault-core/package.json index eae009d0..ca609c67 100644 --- a/infrastructure/evault-core/package.json +++ b/infrastructure/evault-core/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "vitest --config vitest.config.ts", "build": "tsc", - "dev": "tsx watch ./src/evault.ts" + "dev": "node --watch --import tsx src/evault.ts" }, "packageManager": "pnpm@10.6.5", "keywords": [], @@ -16,7 +16,9 @@ "@types/json-schema": "^7.0.15", "@types/node": "^22.13.10", "dotenv": "^16.5.0", + "nodemon": "^3.1.9", "testcontainers": "^10.24.2", + "ts-node": "^10.9.2", "tsx": "^4.19.3", "typescript": "^5.8.3", "uuid": "^11.1.0", diff --git a/infrastructure/evault-core/src/db/db.service.ts b/infrastructure/evault-core/src/db/db.service.ts index 0af08e12..a6efadb9 100644 --- a/infrastructure/evault-core/src/db/db.service.ts +++ b/infrastructure/evault-core/src/db/db.service.ts @@ -1,5 +1,4 @@ -import { Driver, driver as neo4jDriver, auth } from "neo4j-driver"; -import dotenv from "dotenv"; +import { Driver } from "neo4j-driver"; import { W3IDBuilder } from "w3id"; import { serializeValue, deserializeValue } from "./schema"; import { @@ -10,9 +9,6 @@ import { SearchMetaEnvelopesResult, GetAllEnvelopesResult, } from "./types"; -import path from "path"; - -dotenv.config({ path: path.resolve(__dirname, "../../../../.env") }); /** * Service for managing meta-envelopes and their associated envelopes in Neo4j. @@ -25,12 +21,8 @@ export class DbService { /** * Creates a new instance of the DbService. */ - constructor() { - const uri = process.env.NEO4J_URI || "bolt://localhost:7687"; - const user = process.env.NEO4J_USER || "neo4j"; - const password = process.env.NEO4J_PASSWORD || "neo4j"; - - this.driver = neo4jDriver(uri, auth.basic(user, password)); + constructor(driver: Driver) { + this.driver = driver; } /** @@ -290,20 +282,53 @@ export class DbService { } /** - * Finds all meta-envelope IDs for a given ontology. + * Finds all meta-envelopes by ontology with their envelopes and parsed payload. * @param ontology - The ontology to search for - * @returns Array of meta-envelope IDs + * @returns Array of meta-envelopes */ - async findMetaEnvelopesByOntology(ontology: string): Promise { + async findMetaEnvelopesByOntology< + T extends Record = Record, + >(ontology: string): Promise[]> { const result = await this.runQuery( ` - MATCH (m:MetaEnvelope { ontology: $ontology }) - RETURN m.id AS id - `, + MATCH (m:MetaEnvelope { ontology: $ontology })-[:LINKS_TO]->(e:Envelope) + RETURN m.id AS id, m.ontology AS ontology, m.acl AS acl, collect(e) AS envelopes + `, { ontology }, ); - return result.records.map((r) => r.get("id")); + return result.records.map((record) => { + const envelopes = record + .get("envelopes") + .map((node: any): Envelope => { + const properties = node.properties; + return { + id: properties.id, + ontology: properties.ontology, + value: deserializeValue( + properties.value, + properties.valueType, + ) as T[keyof T], + valueType: properties.valueType, + }; + }); + + const parsed = envelopes.reduce( + (acc: T, envelope: Envelope) => { + (acc as any)[envelope.ontology] = envelope.value; + return acc; + }, + {} as T, + ); + + return { + id: record.get("id"), + ontology: record.get("ontology"), + acl: record.get("acl"), + envelopes, + parsed, + }; + }); } /** @@ -368,16 +393,4 @@ export class DbService { async close(): Promise { await this.driver.close(); } - - private parseRecord(record: any): Envelope { - // ... existing code ... - } - - private parseSearchResult(r: any): Envelope { - // ... existing code ... - } - - private parseGetAllResult(r: any): Envelope { - // ... existing code ... - } } diff --git a/infrastructure/evault-core/src/evault.ts b/infrastructure/evault-core/src/evault.ts index 3c0a0cb2..e6367c3e 100644 --- a/infrastructure/evault-core/src/evault.ts +++ b/infrastructure/evault-core/src/evault.ts @@ -1,9 +1,34 @@ +import { Server } from "http"; import { DbService } from "./db/db.service"; import { GraphQLServer } from "./protocol/graphql-server"; +import dotenv from "dotenv"; +import path from "path"; +import neo4j from "neo4j-driver"; -async function startEVault() { - const dbService = new DbService(); - new GraphQLServer(dbService); +dotenv.config({ path: path.resolve(__dirname, "../../../.env") }); + +class EVault { + server: Server; + + constructor() { + const uri = process.env.NEO4J_URI || "bolt://localhost:7687"; + const user = process.env.NEO4J_USER || "neo4j"; + const password = process.env.NEO4J_PASSWORD || "neo4j"; + + const driver = neo4j.driver(uri, neo4j.auth.basic(user, password)); + const dbService = new DbService(driver); + const gqlServer = new GraphQLServer(dbService); + this.server = gqlServer.server as Server; + } + + start() { + const port = process.env.PORT ?? 4000; + this.server.listen(port, () => { + console.log(`GraphQL Server started on http://localhost:${port}`); + console.log(`Voyager started on http://localhost:${port}`); + }); + } } -startEVault(); +const evault = new EVault(); +evault.start(); diff --git a/infrastructure/evault-core/src/protocol/graphql-server.ts b/infrastructure/evault-core/src/protocol/graphql-server.ts index 8664c68c..6a1c513c 100644 --- a/infrastructure/evault-core/src/protocol/graphql-server.ts +++ b/infrastructure/evault-core/src/protocol/graphql-server.ts @@ -1,5 +1,5 @@ import { createSchema, createYoga, YogaInitialContext } from "graphql-yoga"; -import { createServer } from "http"; +import { createServer, Server } from "http"; import { typeDefs } from "./typedefs"; import { renderVoyagerPage } from "graphql-voyager/middleware"; import { getJWTHeader } from "w3id"; @@ -15,6 +15,7 @@ export class GraphQLServer { typeDefs, resolvers: {}, }); + server?: Server; constructor(db: DbService) { this.db = db; @@ -130,7 +131,7 @@ export class GraphQLServer { }, }); - const server = createServer((req, res) => { + this.server = createServer((req, res) => { if (req.url === "/voyager") { res.writeHead(200, { "Content-Type": "text/html" }); res.end( @@ -142,10 +143,5 @@ export class GraphQLServer { yoga(req, res); } }); - - server.listen(4000, () => { - console.log("πŸš€ GraphQL at http://localhost:4000/graphql"); - console.log("πŸ›°οΈ Voyager at http://localhost:4000/voyager"); - }); } } diff --git a/infrastructure/evault-core/src/protocol/vault-access-guard.ts b/infrastructure/evault-core/src/protocol/vault-access-guard.ts index cac33a93..151344d0 100644 --- a/infrastructure/evault-core/src/protocol/vault-access-guard.ts +++ b/infrastructure/evault-core/src/protocol/vault-access-guard.ts @@ -1,5 +1,7 @@ import { YogaInitialContext } from "graphql-yoga"; import { DbService } from "../db/db.service"; +import { MetaEnvelope } from "../db/types"; +import { env } from "node:process"; export type VaultContext = YogaInitialContext & { currentUser: string | null; @@ -54,23 +56,19 @@ export class VaultAccessGuard { * @returns Promise - Filtered list of meta envelopes */ private async filterEnvelopesByAccess( - envelopes: string[], + envelopes: MetaEnvelope[], context: VaultContext, ): Promise { - if (!context.currentUser) { - return []; - } - - const metaEnvs = await this.db.findMetaEnvelopesByIds(envelopes); - const filteredEnvelopes = []; - for (const envelope of metaEnvs) { - const hasAccess = true; + for (const envelope of envelopes) { + const hasAccess = + envelope.acl[0] !== "*" + ? envelope.acl.includes(context.currentUser ?? "") + : []; if (hasAccess) { filteredEnvelopes.push(this.filterACL(envelope)); } } - console.log(filteredEnvelopes); return filteredEnvelopes; } @@ -112,8 +110,8 @@ export class VaultAccessGuard { throw new Error("Access denied"); } + // console.log const result = await resolver(parent, args, context); - console.log("Hereererer"); return this.filterACL(result); }; } diff --git a/infrastructure/evault-core/tests/utils/mock-storage.ts b/infrastructure/evault-core/tests/utils/mock-storage.ts index c380fb6d..2a7f4b8b 100644 --- a/infrastructure/evault-core/tests/utils/mock-storage.ts +++ b/infrastructure/evault-core/tests/utils/mock-storage.ts @@ -1,60 +1,60 @@ import { StorageSpec } from "../../src/types/w3id"; export class MockStorage implements StorageSpec { - private store: Map = new Map(); - private dataStore: Map = new Map(); - - async get(key: string): Promise { - return this.store.get(key) ?? null; - } - - async set(key: string, value: string): Promise { - this.store.set(key, value); - } - - async delete(key: string): Promise { - this.store.delete(key); - } - - async list(prefix: string): Promise { - return Array.from(this.store.keys()).filter((key) => - key.startsWith(prefix) - ); - } - - async create(data: T): Promise { - const id = Math.random().toString(36).substring(7); - this.dataStore.set(id, data); - return data as unknown as U; - } - - async findOne(query: Partial): Promise { - for (const [_, data] of this.dataStore) { - if (this.matchesQuery(data, query)) { + private store: Map = new Map(); + private dataStore: Map = new Map(); + + async get(key: string): Promise { + return this.store.get(key) ?? null; + } + + async set(key: string, value: string): Promise { + this.store.set(key, value); + } + + async delete(key: string): Promise { + this.store.delete(key); + } + + async list(prefix: string): Promise { + return Array.from(this.store.keys()).filter((key) => + key.startsWith(prefix), + ); + } + + async create(data: T): Promise { + const id = Math.random().toString(36).substring(7); + this.dataStore.set(id, data); return data as unknown as U; - } - } - return null; - } - - async findMany(query: Partial): Promise { - const results: U[] = []; - for (const [_, data] of this.dataStore) { - if (this.matchesQuery(data, query)) { - results.push(data as unknown as U); - } - } - return results; - } - - private matchesQuery(data: T, query: Partial): boolean { - return Object.entries(query).every(([key, value]) => { - return (data as any)[key] === value; - }); - } - - clear(): void { - this.store.clear(); - this.dataStore.clear(); - } + } + + async findOne(query: Partial): Promise { + for (const [_, data] of this.dataStore) { + if (this.matchesQuery(data, query)) { + return data as unknown as U; + } + } + return null; + } + + async findMany(query: Partial): Promise { + const results: U[] = []; + for (const [_, data] of this.dataStore) { + if (this.matchesQuery(data, query)) { + results.push(data as unknown as U); + } + } + return results; + } + + private matchesQuery(data: T, query: Partial): boolean { + return Object.entries(query).every(([key, value]) => { + return (data as any)[key] === value; + }); + } + + clear(): void { + this.store.clear(); + this.dataStore.clear(); + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5c2f8f1..8ff5c54c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -178,9 +178,15 @@ importers: dotenv: specifier: ^16.5.0 version: 16.5.0 + nodemon: + specifier: ^3.1.9 + version: 3.1.9 testcontainers: specifier: ^10.24.2 version: 10.24.2 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@22.13.10)(typescript@5.8.3) tsx: specifier: ^4.19.3 version: 4.19.3 @@ -415,6 +421,10 @@ packages: peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -839,6 +849,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} @@ -1557,6 +1570,18 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1770,6 +1795,10 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + acorn@8.14.1: resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} engines: {node: '>=0.4.0'} @@ -1806,6 +1835,10 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + archiver-utils@5.0.2: resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} engines: {node: '>= 14'} @@ -1814,6 +1847,9 @@ packages: resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} engines: {node: '>= 14'} + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1941,6 +1977,10 @@ packages: resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} engines: {node: '>=12.0.0'} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -2023,6 +2063,10 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -2106,6 +2150,9 @@ packages: resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} engines: {node: '>= 14'} + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cross-inspect@1.0.1: resolution: {integrity: sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==} engines: {node: '>=16.0.0'} @@ -2194,6 +2241,10 @@ packages: devalue@5.1.1: resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + docker-compose@0.24.8: resolution: {integrity: sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==} engines: {node: '>= 6.0.0'} @@ -2678,6 +2729,10 @@ packages: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -2716,6 +2771,9 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + ignore@4.0.6: resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} engines: {node: '>= 4'} @@ -2769,6 +2827,10 @@ packages: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + is-boolean-object@1.2.2: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} @@ -3096,6 +3158,9 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + map-or-similar@1.5.0: resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} @@ -3209,6 +3274,11 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + nodemon@3.1.9: + resolution: {integrity: sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==} + engines: {node: '>=10'} + hasBin: true + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -3403,6 +3473,9 @@ packages: psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -3463,6 +3536,10 @@ packages: readdir-glob@1.1.3: resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -3634,6 +3711,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + sirv@3.0.1: resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} engines: {node: '>=18'} @@ -3751,6 +3832,10 @@ packages: stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -3897,6 +3982,10 @@ packages: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} + touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -3911,6 +4000,20 @@ packages: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -4024,6 +4127,9 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -4083,6 +4189,9 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + v8-compile-cache@2.4.0: resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} @@ -4251,6 +4360,10 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -4297,7 +4410,7 @@ snapshots: '@babel/traverse': 7.26.10 '@babel/types': 7.26.10 convert-source-map: 2.0.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4377,7 +4490,7 @@ snapshots: '@babel/parser': 7.26.10 '@babel/template': 7.26.9 '@babel/types': 7.26.10 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -4452,6 +4565,10 @@ snapshots: - '@chromatic-com/playwright' - react + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + '@emotion/babel-plugin@11.13.5': dependencies: '@babel/helper-module-imports': 7.25.9 @@ -4637,7 +4754,7 @@ snapshots: '@eslint/config-array@0.19.2': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4651,7 +4768,7 @@ snapshots: '@eslint/eslintrc@1.4.1': dependencies: ajv: 6.12.6 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -4665,7 +4782,7 @@ snapshots: '@eslint/eslintrc@3.3.0': dependencies: ajv: 6.12.6 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -4786,7 +4903,7 @@ snapshots: '@humanwhocodes/config-array@0.9.5': dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4853,6 +4970,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@js-sdsl/ordered-map@4.4.2': {} '@mdx-js/react@3.1.0(@types/react@19.0.12)(react@19.0.0)': @@ -5422,7 +5544,7 @@ snapshots: '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1)))(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1))': dependencies: '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1)) - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) svelte: 5.23.2 vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1) transitivePeerDependencies: @@ -5431,7 +5553,7 @@ snapshots: '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1))': dependencies: '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1)))(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1)) - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 @@ -5619,6 +5741,14 @@ snapshots: dependencies: '@testing-library/dom': 9.3.4 + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + '@types/aria-query@5.0.4': {} '@types/cookie@0.6.0': {} @@ -5704,7 +5834,7 @@ snapshots: '@typescript-eslint/types': 8.26.1 '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) eslint: 9.22.0(jiti@2.4.2) typescript: 5.8.2 transitivePeerDependencies: @@ -5719,7 +5849,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) '@typescript-eslint/utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) eslint: 9.22.0(jiti@2.4.2) ts-api-utils: 2.0.1(typescript@5.8.2) typescript: 5.8.2 @@ -5732,7 +5862,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.26.1 '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -5827,7 +5957,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 @@ -5975,6 +6105,10 @@ snapshots: dependencies: acorn: 8.14.1 + acorn-walk@8.3.4: + dependencies: + acorn: 8.14.1 + acorn@8.14.1: {} ajv@6.12.6: @@ -6002,6 +6136,11 @@ snapshots: ansi-styles@6.2.1: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + archiver-utils@5.0.2: dependencies: glob: 10.4.5 @@ -6022,6 +6161,8 @@ snapshots: tar-stream: 3.1.7 zip-stream: 6.0.1 + arg@4.1.3: {} + argparse@2.0.1: {} aria-query@5.1.3: @@ -6166,6 +6307,8 @@ snapshots: dependencies: open: 8.4.2 + binary-extensions@2.3.0: {} + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -6256,6 +6399,18 @@ snapshots: check-error@2.1.1: {} + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + chokidar@4.0.3: dependencies: readdirp: 4.1.2 @@ -6329,6 +6484,8 @@ snapshots: crc-32: 1.2.2 readable-stream: 4.7.0 + create-require@1.1.1: {} + cross-inspect@1.0.1: dependencies: tslib: 2.8.1 @@ -6365,9 +6522,11 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - debug@4.4.0: + debug@4.4.0(supports-color@5.5.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 dedent-js@1.0.1: {} @@ -6420,13 +6579,15 @@ snapshots: devalue@5.1.1: {} + diff@4.0.2: {} + docker-compose@0.24.8: dependencies: yaml: 2.7.1 docker-modem@5.0.6: dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) readable-stream: 3.6.2 split-ca: 1.0.1 ssh2: 1.16.0 @@ -6642,7 +6803,7 @@ snapshots: esbuild-register@3.6.0(esbuild@0.25.1): dependencies: - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) esbuild: 0.25.1 transitivePeerDependencies: - supports-color @@ -6745,7 +6906,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) doctrine: 3.0.0 enquirer: 2.4.1 escape-string-regexp: 4.0.0 @@ -6799,7 +6960,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) escape-string-regexp: 4.0.0 eslint-scope: 8.3.0 eslint-visitor-keys: 4.2.0 @@ -7096,6 +7257,8 @@ snapshots: has-bigints@1.1.0: {} + has-flag@3.0.0: {} + has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -7133,6 +7296,8 @@ snapshots: ieee754@1.2.1: {} + ignore-by-default@1.0.1: {} + ignore@4.0.6: {} ignore@5.3.2: {} @@ -7186,6 +7351,10 @@ snapshots: dependencies: has-bigints: 1.1.0 + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + is-boolean-object@1.2.2: dependencies: call-bound: 1.0.4 @@ -7306,7 +7475,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -7484,6 +7653,8 @@ snapshots: dependencies: semver: 7.7.1 + make-error@1.3.6: {} + map-or-similar@1.5.0: {} math-intrinsics@1.1.0: {} @@ -7644,6 +7815,19 @@ snapshots: node-releases@2.0.19: {} + nodemon@3.1.9: + dependencies: + chokidar: 3.6.0 + debug: 4.4.0(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.7.1 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + normalize-path@3.0.0: {} normalize-range@0.1.2: {} @@ -7849,6 +8033,8 @@ snapshots: dependencies: punycode: 2.3.1 + pstree.remy@1.1.8: {} + pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -7917,6 +8103,10 @@ snapshots: dependencies: minimatch: 5.1.6 + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + readdirp@4.1.2: {} recast@0.23.11: @@ -8129,6 +8319,10 @@ snapshots: signal-exit@4.1.0: {} + simple-update-notifier@2.0.0: + dependencies: + semver: 7.7.1 + sirv@3.0.1: dependencies: '@polka/url': 1.0.0-next.28 @@ -8277,6 +8471,10 @@ snapshots: stylis@4.2.0: {} + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -8394,7 +8592,7 @@ snapshots: archiver: 7.0.1 async-lock: 1.4.1 byline: 5.0.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) docker-compose: 0.24.8 dockerode: 4.0.5 get-port: 7.1.0 @@ -8436,6 +8634,8 @@ snapshots: totalist@3.0.1: {} + touch@3.1.1: {} + tough-cookie@4.1.4: dependencies: psl: 1.15.0 @@ -8449,6 +8649,24 @@ snapshots: ts-dedent@2.2.0: {} + ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.13.10 + acorn: 8.14.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.8.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + tslib@2.8.1: {} tsx@4.19.3: @@ -8559,6 +8777,8 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + undefsafe@2.0.5: {} + undici-types@5.26.5: {} undici-types@6.20.0: {} @@ -8611,12 +8831,14 @@ snapshots: uuid@9.0.1: {} + v8-compile-cache-lib@3.0.1: {} + v8-compile-cache@2.4.0: {} vite-node@3.0.9(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1): dependencies: cac: 6.7.14 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) es-module-lexer: 1.6.0 pathe: 2.0.3 vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1) @@ -8661,7 +8883,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) expect-type: 1.2.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -8700,7 +8922,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) expect-type: 1.2.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -8739,7 +8961,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.0 + debug: 4.4.0(supports-color@5.5.0) expect-type: 1.2.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -8865,6 +9087,8 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yn@3.1.1: {} + yocto-queue@0.1.0: {} yoctocolors-cjs@2.1.2: {} From 5c7599f89f686627b8ed372667f54f32803caed0 Mon Sep 17 00:00:00 2001 From: Merul Dhiman <69296233+coodos@users.noreply.github.com> Date: Sun, 20 Apr 2025 03:22:40 +0800 Subject: [PATCH 4/9] Update infrastructure/evault-core/src/protocol/vault-access-guard.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../evault-core/src/protocol/vault-access-guard.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/infrastructure/evault-core/src/protocol/vault-access-guard.ts b/infrastructure/evault-core/src/protocol/vault-access-guard.ts index 151344d0..ba8579a6 100644 --- a/infrastructure/evault-core/src/protocol/vault-access-guard.ts +++ b/infrastructure/evault-core/src/protocol/vault-access-guard.ts @@ -61,10 +61,8 @@ export class VaultAccessGuard { ): Promise { const filteredEnvelopes = []; for (const envelope of envelopes) { - const hasAccess = - envelope.acl[0] !== "*" - ? envelope.acl.includes(context.currentUser ?? "") - : []; + const hasAccess = envelope.acl.includes("*") || + envelope.acl.includes(context.currentUser ?? ""); if (hasAccess) { filteredEnvelopes.push(this.filterACL(envelope)); } From 3a77290b88bedc2c39f7df32f50d971deafcc0ce Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Sun, 20 Apr 2025 00:53:09 +0530 Subject: [PATCH 5/9] chore: remove unused import --- infrastructure/evault-core/src/protocol/vault-access-guard.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/infrastructure/evault-core/src/protocol/vault-access-guard.ts b/infrastructure/evault-core/src/protocol/vault-access-guard.ts index 151344d0..bf300242 100644 --- a/infrastructure/evault-core/src/protocol/vault-access-guard.ts +++ b/infrastructure/evault-core/src/protocol/vault-access-guard.ts @@ -1,7 +1,6 @@ import { YogaInitialContext } from "graphql-yoga"; import { DbService } from "../db/db.service"; import { MetaEnvelope } from "../db/types"; -import { env } from "node:process"; export type VaultContext = YogaInitialContext & { currentUser: string | null; From b9debe609840639f299ce8da82759b837420bdbf Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Sun, 20 Apr 2025 00:55:00 +0530 Subject: [PATCH 6/9] chore: remove package --- .env.example | 7 ++++ docker/Dockerfile.evault | 23 +++++++++++ evault.docker-compose.yml | 50 ++++++++++++++++++++++++ infrastructure/evault-core/package.json | 2 - infrastructure/evault-core/src/evault.ts | 10 +++++ 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 .env.example create mode 100644 docker/Dockerfile.evault create mode 100644 evault.docker-compose.yml diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..acdfda8a --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +# Neo4j Configuration +NEO4J_URI=bolt://neo4j:7687 +NEO4J_USER=neo4j +NEO4J_PASSWORD=your_secure_password_here + +# eVault Configuration +PORT=4000 \ No newline at end of file diff --git a/docker/Dockerfile.evault b/docker/Dockerfile.evault new file mode 100644 index 00000000..1442ecbb --- /dev/null +++ b/docker/Dockerfile.evault @@ -0,0 +1,23 @@ +FROM node:22-slim AS deps +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable +COPY . /app +WORKDIR /app +RUN npm i -g corepack@latest +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile +RUN pnpm turbo prune evault-core --docker --use-gitignore=false +RUN mkdir /out +RUN cp -R ./out/full/* /out/ +RUN cp -R ./out/json/* /out/ +RUN cp ./out/pnpm-lock.yaml /out/pnpm-lock.yaml +RUN cp -R node_modules/ /out/ + + +FROM node:22-slim AS core-api +WORKDIR /app +RUN npm i -g corepack@latest +COPY --from=deps /out/ /app +EXPOSE 1209 +workdir /app/infrastructure/evault-core +CMD ["pnpm", "dev"] diff --git a/evault.docker-compose.yml b/evault.docker-compose.yml new file mode 100644 index 00000000..2228175b --- /dev/null +++ b/evault.docker-compose.yml @@ -0,0 +1,50 @@ +version: '3.8' + +services: + evault: + build: + context: . + dockerfile: ./docker/Dockerfile.evault + ports: + - "4000:4000" + environment: + - NEO4J_URI=${NEO4J_URI} + - NEO4J_USER=${NEO4J_USER} + - NEO4J_PASSWORD=${NEO4J_PASSWORD} + networks: + - graphnet + depends_on: + - neo4j + develop: + watch: + - action: sync+restart + path: ./infrastructure/evault-core/ + target: /app/infrastructure/evault-core + ignore: + - node_modules + - action: rebuild + path: ./infrastructure/evault-core/package.json + - action: rebuild + path: ./.env + + neo4j: + image: neo4j:5.15 + container_name: evault-neo4j + ports: + - "7474:7474" # HTTP + - "7687:7687" # Bolt + environment: + - NEO4J_AUTH=${NEO4J_USER}/${NEO4J_PASSWORD} + volumes: + - neo4j_data:/data + - neo4j_logs:/log + networks: + - graphnet + +volumes: + neo4j_data: + neo4j_logs: + +networks: + graphnet: + driver: bridge diff --git a/infrastructure/evault-core/package.json b/infrastructure/evault-core/package.json index ca609c67..d3d2ae20 100644 --- a/infrastructure/evault-core/package.json +++ b/infrastructure/evault-core/package.json @@ -16,9 +16,7 @@ "@types/json-schema": "^7.0.15", "@types/node": "^22.13.10", "dotenv": "^16.5.0", - "nodemon": "^3.1.9", "testcontainers": "^10.24.2", - "ts-node": "^10.9.2", "tsx": "^4.19.3", "typescript": "^5.8.3", "uuid": "^11.1.0", diff --git a/infrastructure/evault-core/src/evault.ts b/infrastructure/evault-core/src/evault.ts index e6367c3e..8e84a350 100644 --- a/infrastructure/evault-core/src/evault.ts +++ b/infrastructure/evault-core/src/evault.ts @@ -15,6 +15,16 @@ class EVault { const user = process.env.NEO4J_USER || "neo4j"; const password = process.env.NEO4J_PASSWORD || "neo4j"; + if ( + !process.env.NEO4J_URI || + !process.env.NEO4J_USER || + !process.env.NEO4J_PASSWORD + ) { + console.warn( + "Using default Neo4j connection parameters. Set NEO4J_URI, NEO4J_USER, and NEO4J_PASSWORD environment variables for custom configuration.", + ); + } + const driver = neo4j.driver(uri, neo4j.auth.basic(user, password)); const dbService = new DbService(driver); const gqlServer = new GraphQLServer(dbService); From 05782eec58a14b161b79b5adb72fb3f7927ca772 Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Sun, 20 Apr 2025 00:55:11 +0530 Subject: [PATCH 7/9] chore: fix pnpm lock --- pnpm-lock.yaml | 270 +++++-------------------------------------------- 1 file changed, 23 insertions(+), 247 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ff5c54c..e5c2f8f1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -178,15 +178,9 @@ importers: dotenv: specifier: ^16.5.0 version: 16.5.0 - nodemon: - specifier: ^3.1.9 - version: 3.1.9 testcontainers: specifier: ^10.24.2 version: 10.24.2 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@22.13.10)(typescript@5.8.3) tsx: specifier: ^4.19.3 version: 4.19.3 @@ -421,10 +415,6 @@ packages: peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -849,9 +839,6 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} @@ -1570,18 +1557,6 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1795,10 +1770,6 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} - acorn@8.14.1: resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} engines: {node: '>=0.4.0'} @@ -1835,10 +1806,6 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - archiver-utils@5.0.2: resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} engines: {node: '>= 14'} @@ -1847,9 +1814,6 @@ packages: resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} engines: {node: '>= 14'} - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1977,10 +1941,6 @@ packages: resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} engines: {node: '>=12.0.0'} - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -2063,10 +2023,6 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -2150,9 +2106,6 @@ packages: resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} engines: {node: '>= 14'} - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-inspect@1.0.1: resolution: {integrity: sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==} engines: {node: '>=16.0.0'} @@ -2241,10 +2194,6 @@ packages: devalue@5.1.1: resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - docker-compose@0.24.8: resolution: {integrity: sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==} engines: {node: '>= 6.0.0'} @@ -2729,10 +2678,6 @@ packages: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -2771,9 +2716,6 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - ignore@4.0.6: resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} engines: {node: '>= 4'} @@ -2827,10 +2769,6 @@ packages: resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} engines: {node: '>= 0.4'} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - is-boolean-object@1.2.2: resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} @@ -3158,9 +3096,6 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - map-or-similar@1.5.0: resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} @@ -3274,11 +3209,6 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - nodemon@3.1.9: - resolution: {integrity: sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==} - engines: {node: '>=10'} - hasBin: true - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -3473,9 +3403,6 @@ packages: psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -3536,10 +3463,6 @@ packages: readdir-glob@1.1.3: resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -3711,10 +3634,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-update-notifier@2.0.0: - resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} - engines: {node: '>=10'} - sirv@3.0.1: resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} engines: {node: '>=18'} @@ -3832,10 +3751,6 @@ packages: stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -3982,10 +3897,6 @@ packages: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - touch@3.1.1: - resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} - hasBin: true - tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -4000,20 +3911,6 @@ packages: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -4127,9 +4024,6 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -4189,9 +4083,6 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - v8-compile-cache@2.4.0: resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} @@ -4360,10 +4251,6 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -4410,7 +4297,7 @@ snapshots: '@babel/traverse': 7.26.10 '@babel/types': 7.26.10 convert-source-map: 2.0.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4490,7 +4377,7 @@ snapshots: '@babel/parser': 7.26.10 '@babel/template': 7.26.9 '@babel/types': 7.26.10 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -4565,10 +4452,6 @@ snapshots: - '@chromatic-com/playwright' - react - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - '@emotion/babel-plugin@11.13.5': dependencies: '@babel/helper-module-imports': 7.25.9 @@ -4754,7 +4637,7 @@ snapshots: '@eslint/config-array@0.19.2': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4768,7 +4651,7 @@ snapshots: '@eslint/eslintrc@1.4.1': dependencies: ajv: 6.12.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -4782,7 +4665,7 @@ snapshots: '@eslint/eslintrc@3.3.0': dependencies: ajv: 6.12.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -4903,7 +4786,7 @@ snapshots: '@humanwhocodes/config-array@0.9.5': dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4970,11 +4853,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - '@js-sdsl/ordered-map@4.4.2': {} '@mdx-js/react@3.1.0(@types/react@19.0.12)(react@19.0.0)': @@ -5544,7 +5422,7 @@ snapshots: '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1)))(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1))': dependencies: '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1)) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 svelte: 5.23.2 vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1) transitivePeerDependencies: @@ -5553,7 +5431,7 @@ snapshots: '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1))': dependencies: '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1)))(svelte@5.23.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1)) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 @@ -5741,14 +5619,6 @@ snapshots: dependencies: '@testing-library/dom': 9.3.4 - '@tsconfig/node10@1.0.11': {} - - '@tsconfig/node12@1.0.11': {} - - '@tsconfig/node14@1.0.3': {} - - '@tsconfig/node16@1.0.4': {} - '@types/aria-query@5.0.4': {} '@types/cookie@0.6.0': {} @@ -5834,7 +5704,7 @@ snapshots: '@typescript-eslint/types': 8.26.1 '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 eslint: 9.22.0(jiti@2.4.2) typescript: 5.8.2 transitivePeerDependencies: @@ -5849,7 +5719,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) '@typescript-eslint/utils': 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2) - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 eslint: 9.22.0(jiti@2.4.2) ts-api-utils: 2.0.1(typescript@5.8.2) typescript: 5.8.2 @@ -5862,7 +5732,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.26.1 '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -5957,7 +5827,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 @@ -6105,10 +5975,6 @@ snapshots: dependencies: acorn: 8.14.1 - acorn-walk@8.3.4: - dependencies: - acorn: 8.14.1 - acorn@8.14.1: {} ajv@6.12.6: @@ -6136,11 +6002,6 @@ snapshots: ansi-styles@6.2.1: {} - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - archiver-utils@5.0.2: dependencies: glob: 10.4.5 @@ -6161,8 +6022,6 @@ snapshots: tar-stream: 3.1.7 zip-stream: 6.0.1 - arg@4.1.3: {} - argparse@2.0.1: {} aria-query@5.1.3: @@ -6307,8 +6166,6 @@ snapshots: dependencies: open: 8.4.2 - binary-extensions@2.3.0: {} - bl@4.1.0: dependencies: buffer: 5.7.1 @@ -6399,18 +6256,6 @@ snapshots: check-error@2.1.1: {} - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - chokidar@4.0.3: dependencies: readdirp: 4.1.2 @@ -6484,8 +6329,6 @@ snapshots: crc-32: 1.2.2 readable-stream: 4.7.0 - create-require@1.1.1: {} - cross-inspect@1.0.1: dependencies: tslib: 2.8.1 @@ -6522,11 +6365,9 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - debug@4.4.0(supports-color@5.5.0): + debug@4.4.0: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 5.5.0 dedent-js@1.0.1: {} @@ -6579,15 +6420,13 @@ snapshots: devalue@5.1.1: {} - diff@4.0.2: {} - docker-compose@0.24.8: dependencies: yaml: 2.7.1 docker-modem@5.0.6: dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 readable-stream: 3.6.2 split-ca: 1.0.1 ssh2: 1.16.0 @@ -6803,7 +6642,7 @@ snapshots: esbuild-register@3.6.0(esbuild@0.25.1): dependencies: - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 esbuild: 0.25.1 transitivePeerDependencies: - supports-color @@ -6906,7 +6745,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 doctrine: 3.0.0 enquirer: 2.4.1 escape-string-regexp: 4.0.0 @@ -6960,7 +6799,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 escape-string-regexp: 4.0.0 eslint-scope: 8.3.0 eslint-visitor-keys: 4.2.0 @@ -7257,8 +7096,6 @@ snapshots: has-bigints@1.1.0: {} - has-flag@3.0.0: {} - has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -7296,8 +7133,6 @@ snapshots: ieee754@1.2.1: {} - ignore-by-default@1.0.1: {} - ignore@4.0.6: {} ignore@5.3.2: {} @@ -7351,10 +7186,6 @@ snapshots: dependencies: has-bigints: 1.1.0 - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - is-boolean-object@1.2.2: dependencies: call-bound: 1.0.4 @@ -7475,7 +7306,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -7653,8 +7484,6 @@ snapshots: dependencies: semver: 7.7.1 - make-error@1.3.6: {} - map-or-similar@1.5.0: {} math-intrinsics@1.1.0: {} @@ -7815,19 +7644,6 @@ snapshots: node-releases@2.0.19: {} - nodemon@3.1.9: - dependencies: - chokidar: 3.6.0 - debug: 4.4.0(supports-color@5.5.0) - ignore-by-default: 1.0.1 - minimatch: 3.1.2 - pstree.remy: 1.1.8 - semver: 7.7.1 - simple-update-notifier: 2.0.0 - supports-color: 5.5.0 - touch: 3.1.1 - undefsafe: 2.0.5 - normalize-path@3.0.0: {} normalize-range@0.1.2: {} @@ -8033,8 +7849,6 @@ snapshots: dependencies: punycode: 2.3.1 - pstree.remy@1.1.8: {} - pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -8103,10 +7917,6 @@ snapshots: dependencies: minimatch: 5.1.6 - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - readdirp@4.1.2: {} recast@0.23.11: @@ -8319,10 +8129,6 @@ snapshots: signal-exit@4.1.0: {} - simple-update-notifier@2.0.0: - dependencies: - semver: 7.7.1 - sirv@3.0.1: dependencies: '@polka/url': 1.0.0-next.28 @@ -8471,10 +8277,6 @@ snapshots: stylis@4.2.0: {} - supports-color@5.5.0: - dependencies: - has-flag: 3.0.0 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -8592,7 +8394,7 @@ snapshots: archiver: 7.0.1 async-lock: 1.4.1 byline: 5.0.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 docker-compose: 0.24.8 dockerode: 4.0.5 get-port: 7.1.0 @@ -8634,8 +8436,6 @@ snapshots: totalist@3.0.1: {} - touch@3.1.1: {} - tough-cookie@4.1.4: dependencies: psl: 1.15.0 @@ -8649,24 +8449,6 @@ snapshots: ts-dedent@2.2.0: {} - ts-node@10.9.2(@types/node@22.13.10)(typescript@5.8.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.13.10 - acorn: 8.14.1 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.8.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - tslib@2.8.1: {} tsx@4.19.3: @@ -8777,8 +8559,6 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - undefsafe@2.0.5: {} - undici-types@5.26.5: {} undici-types@6.20.0: {} @@ -8831,14 +8611,12 @@ snapshots: uuid@9.0.1: {} - v8-compile-cache-lib@3.0.1: {} - v8-compile-cache@2.4.0: {} vite-node@3.0.9(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1): dependencies: cac: 6.7.14 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.3 vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.1) @@ -8883,7 +8661,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 expect-type: 1.2.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -8922,7 +8700,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 expect-type: 1.2.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -8961,7 +8739,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.0(supports-color@5.5.0) + debug: 4.4.0 expect-type: 1.2.0 magic-string: 0.30.17 pathe: 2.0.3 @@ -9087,8 +8865,6 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yn@3.1.1: {} - yocto-queue@0.1.0: {} yoctocolors-cjs@2.1.2: {} From 298a0e6f2751afbc7c61ea29d4659ce58f7b0d99 Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Sun, 20 Apr 2025 00:56:28 +0530 Subject: [PATCH 8/9] chore: fix workflow --- .github/workflows/tests-evault-core.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests-evault-core.yml b/.github/workflows/tests-evault-core.yml index 4d4d852e..0b600c9d 100644 --- a/.github/workflows/tests-evault-core.yml +++ b/.github/workflows/tests-evault-core.yml @@ -8,7 +8,7 @@ on: pull_request: branches: [main] paths: - - 'infrastructure/w3id/**' + - 'infrastructure/evault-core/**' jobs: test: From 6484f20ad71049f5c2a9e2b6ac9baf2e0383243f Mon Sep 17 00:00:00 2001 From: Merul Dhiman Date: Sun, 20 Apr 2025 01:08:53 +0530 Subject: [PATCH 9/9] chore: fix port in dockerfile --- docker/Dockerfile.evault | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile.evault b/docker/Dockerfile.evault index 1442ecbb..2cbee198 100644 --- a/docker/Dockerfile.evault +++ b/docker/Dockerfile.evault @@ -18,6 +18,6 @@ FROM node:22-slim AS core-api WORKDIR /app RUN npm i -g corepack@latest COPY --from=deps /out/ /app -EXPOSE 1209 +EXPOSE 4000 workdir /app/infrastructure/evault-core CMD ["pnpm", "dev"]