diff --git a/.codex/review-prompt.md b/.codex/review-prompt.md
index dae32945..3e2e996a 100644
--- a/.codex/review-prompt.md
+++ b/.codex/review-prompt.md
@@ -9,7 +9,7 @@ Read these files before reviewing:
1. **`pr-diff.patch`** — The PR diff (generated at runtime). This is the primary input.
2. **`AGENTS.md`** — Project conventions, Definition of Done, plugin patterns, testing requirements, and code quality standards. This is the source of truth for how code in this project should look.
-You may read other files in the repository to understand surrounding context (e.g., how a modified function is called, what a referenced constant is). However, all review comments must target lines that appear in the diff.
+You may read other files in the repository **only** to understand how code changed in the diff is called or referenced. Do not review, comment on, or mention code in files or packages that are not part of the diff. All review comments and the summary must be strictly scoped to changes introduced by this PR's diff — nothing else.
## Review Philosophy
@@ -26,7 +26,7 @@ When both exist, report blockers first.
Do three passes:
-1. **Context + risk-map pass (mandatory)** — Read full touched files (not only hunk lines) and identify high-risk zones: platform/runtime boundaries, event handlers, async cleanup (`finally`), auth/validation boundaries, and repeated predicates/guards.
+1. **Context + risk-map pass (mandatory)** — For each file that appears in the diff, read the full file (not only hunk lines) to understand surrounding context. Do NOT read files or packages that have no changed lines in the diff. Identify high-risk zones in the changed code: platform/runtime boundaries, event handlers, async cleanup (`finally`), auth/validation boundaries, and repeated predicates/guards.
2. **Blockers pass** — Scan for correctness bugs, security issues, API/schema contract breaks, missing migrations, data integrity risks, and missing tests for changed behavior. These are `🔴 Bug` comments.
3. **Maintainability pass** — Scan for code bloat, readability issues, naming problems, pattern violations, hardcoded values, and architecture drift in touched areas. These are `🟡 Issue`, `🔵 Nit`, or `💡 Suggestion` comments.
@@ -53,15 +53,18 @@ If any check fails, skip the comment.
- Logic errors, off-by-one, null/undefined handling, incorrect assumptions, race conditions.
- Boundary conditions — empty arrays, null inputs, zero values, maximum values.
- Error handling — swallowed errors, missing error propagation, unhelpful error messages. Do not flag missing error handling for internal code that cannot reasonably fail.
+- Streaming/multipart handlers — verify a request cannot send multiple responses (e.g., multi-file parts triggering repeated `res.json()` calls). If a route expects one file, ensure parser limits and single-response guards exist.
- Unsafe runtime assumptions hidden by type assertions (`as ...`, `as any`, non-null `!`) when values come from events, external I/O, or platform-specific APIs.
- Platform/runtime compatibility assumptions — usage of globals/APIs (`window`, `document`, `Node`, `process`, browser-only APIs) in cross-runtime code paths must be guarded.
#### Security
+
- Injection risks (SQL, command, XSS) when handling user input.
- Hardcoded secrets — API keys, passwords, tokens in code.
- Missing input validation at system boundaries (user input, external APIs). Not for internal function calls.
- Auth bypass, privilege escalation, or missing authorization checks.
+- Filesystem path confinement — when IDs/paths come from requests, verify storage layers enforce root containment via resolved-path checks; do not rely only on caller-side sanitization.
#### API Compatibility
@@ -69,6 +72,7 @@ If any check fails, skip the comment.
- Removed or renamed API endpoints, query parameters, or response fields that existing consumers depend on.
- Database schema changes that require migration or backfill.
- MCP tool signature changes (renamed tools, changed input schemas) that break existing clients.
+- HTTP status semantics — ensure client/input errors are 4xx and unexpected internal failures are 5xx; blanket 400 handling in catch-all paths is a correctness/API contract issue.
#### Tests for Changed Behavior
@@ -76,6 +80,7 @@ If any check fails, skip the comment.
- Bug fixes must include a regression test that would have caught the original bug.
- Changed behavior must have updated tests reflecting the new expectations.
- If tests are present but brittle (testing implementation details rather than behavior), flag it.
+- For single-file upload endpoints, look for regression coverage of multi-file/malformed multipart inputs and confirm no double-response behavior.
- Prefer tests that validate production behavior directly. If a test re-implements production decision logic locally, and could stay green while runtime behavior regresses, flag it and suggest importing shared runtime logic or testing via a higher-level behavior path.
Missing tests for changed behavior are blockers (`🔴 Bug`) only when the change affects user-facing behavior, API contracts, or data integrity. Missing tests for internal refactors or trivial changes are `🟡 Issue`.
@@ -113,6 +118,7 @@ Missing tests for changed behavior are blockers (`🔴 Bug`) only when the chang
- **Wrong import paths in tests** — Tests importing from `src/` instead of `dist/`.
- **Missing test categories** — Tests without "Core Functionality" and "Error Handling" describe blocks.
- **Mixing concerns** — Route handlers doing business logic, database queries in API handlers, etc.
+- **Cross-provider behavior drift** — When multiple providers/implementations exist, verify shared options and output semantics behave consistently unless explicitly documented otherwise.
#### Hardcoded Values and Magic Constants
@@ -135,6 +141,7 @@ Do not flag one-off numeric literals that are self-explanatory in context (e.g.,
- Type annotations for code that already type-checks.
- Things that are clearly intentional design choices backed by existing patterns.
- Pre-existing issues in unchanged code outside the diff.
+- Code in files or packages that have no changed lines in the diff — even if you read them for context.
- Adding documentation unless a public API is clearly undocumented.
## Comment Format
@@ -174,4 +181,4 @@ The `line` field must refer to the line number in the new version of the file (r
## Summary
-Write a brief (2–4 sentence) overall assessment in the `summary` field. Lead with blockers if any exist. Mention whether the PR is clean/minimal or has code quality issues. Include one sentence on maintainability direction in touched areas (improved / neutral / worsened, and why). If the PR looks good, say so.
+Write a brief (2–4 sentence) overall assessment in the `summary` field covering **only** what this PR's diff changes. Do not mention code, packages, or behavior outside the diff. Lead with blockers if any exist. Mention whether the PR is clean/minimal or has code quality issues. Include one sentence on maintainability direction in touched areas (improved / neutral / worsened, and why). If the PR looks good, say so.
diff --git a/apps/agent/src/server/scripts/setup.ts b/apps/agent/src/server/scripts/setup.ts
index c48ffaec..9a4fc915 100644
--- a/apps/agent/src/server/scripts/setup.ts
+++ b/apps/agent/src/server/scripts/setup.ts
@@ -9,8 +9,8 @@ import {
import {
getLLMProviderApiKeyEnvName,
LLMProvider,
- DEFAULT_SYSTEM_PROMPT,
} from "@/shared/chat";
+import { DEFAULT_SYSTEM_PROMPT } from "@/shared/prompts/defaultSystemPrompt";
async function setup() {
const r = await prompts([
@@ -50,6 +50,25 @@ async function setup() {
initial: DEFAULT_SYSTEM_PROMPT,
format: (val) => (val === DEFAULT_SYSTEM_PROMPT ? "" : val.trim()),
},
+ {
+ type: "select",
+ name: "docConversionProvider",
+ message: "Document conversion provider",
+ choices: [
+ { title: "unpdf — basic PDF only", value: "unpdf" },
+ { title: "Mistral OCR — complex PDF/DOCX/PPTX", value: "mistral" },
+ ],
+ initial: 0,
+ },
+ {
+ type: (_, a) =>
+ a.docConversionProvider === "mistral" && a.llmProvider !== "mistralai"
+ ? "text"
+ : null,
+ name: "mistralApiKey",
+ message: "MISTRAL_API_KEY",
+ validate: (val) => val.length || "Required for Mistral OCR provider",
+ },
{
type: "select",
name: "dkgEnv",
@@ -132,8 +151,9 @@ async function setup() {
{
type: "text",
name: "dbFilename",
- message: "Database filename (i.e: example.db)",
+ message: "Database filename (e.g. example.db)",
validate: (val) => val.length || "Required",
+ format: (val) => (val.endsWith(".db") ? val : `${val}.db`),
},
]);
@@ -158,7 +178,8 @@ SMTP_USER="${r.smtpUsername || ""}"
SMTP_PASS="${r.smtpPassword || ""}"
SMTP_SECURE=${r.smtpSecure === undefined ? "true" : r.smtpSecure}
SMTP_FROM="${r.smtpFrom || ""}"
-`,
+DOCUMENT_CONVERSION_PROVIDER="${r.docConversionProvider}"
+${r.docConversionProvider === "mistral" && r.llmProvider !== "mistralai" ? `MISTRAL_API_KEY="${r.mistralApiKey}"\n` : ""}`,
);
console.log("Creating .env.development.local file...");
diff --git a/apps/agent/src/shared/chat.ts b/apps/agent/src/shared/chat.ts
index 00def683..b572b22b 100644
--- a/apps/agent/src/shared/chat.ts
+++ b/apps/agent/src/shared/chat.ts
@@ -9,6 +9,8 @@ import type {
import type { ToolCallChunk } from "@langchain/core/messages/tool";
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
+import { DEFAULT_SYSTEM_PROMPT } from "./prompts/defaultSystemPrompt";
+
export type { ToolDefinition };
export type ToolInfo = {
name: string;
@@ -339,7 +341,7 @@ export const processStreamingCompletion = async (
try {
args = tc.args ? JSON.parse(tc.args) : {};
} catch {
- // Malformed JSON from partial streaming — send raw
+ // Malformed JSON from partial streaming - send raw
args = {};
}
toolCalls.push({
@@ -358,17 +360,17 @@ export const processStreamingCompletion = async (
writeSSE(res, { event: "done", data: {} });
} catch (streamError) {
if (hasSentContent) {
- // Partial content was already sent — don't re-invoke and risk
+ // Partial content was already sent - don't re-invoke and risk
// duplicated/mixed output. Send an error so the UI can recover.
writeSSE(res, {
event: "error",
data: {
message:
- "Stream interrupted — please retry your message",
+ "Stream interrupted - please retry your message",
},
});
} else {
- // No content sent yet — safe to fallback to a full invoke
+ // No content sent yet - safe to fallback to a full invoke
try {
const result = await provider.invoke(messages, options);
const content = result.content;
@@ -514,42 +516,9 @@ export const makeStreamingCompletionRequest = async (
// Stream ended without an explicit done/error event (server crash, network drop)
if (!streamFinalized) {
- callbacks.onError("Connection lost — the server stopped responding");
+ callbacks.onError("Connection lost - the server stopped responding");
}
} finally {
reader.releaseLock();
}
};
-
-export const DEFAULT_SYSTEM_PROMPT = `
-You are a DKG Agent that helps users interact with the OriginTrail Decentralized Knowledge Graph (DKG) using available Model Context Protocol (MCP) tools.
-Your role is to help users create, retrieve, and analyze verifiable knowledge in a friendly, approachable, and knowledgeable way, making the technology accessible to both experts and non-experts. When replying, use markdown (e.g. bold text, bullet points, tables, etc.) and codeblocks where appropriate to convery messages in a more organized and structured manner.
-
-## Core Responsibilities
-- Answer Questions: Retrieve and explain knowledge from the DKG to help users understand and solve problems.
-- Create Knowledge Assets: Assist users in publishing new knowledge assets to the DKG using MCP tools.
-- Perform Analyses: Use DKG data and MCP tools to perform structured analyses, presenting results clearly.
-- Be Helpful and Approachable: Communicate in simple, user-friendly terms. Use analogies and clear explanations where needed, but avoid unnecessary technical jargon unless requested.
-
-## Privacy Rule (IMPORTANT)
-When creating or publishing knowledge assets:
-- If privacy is explicitly specified, follow the user’s instruction.
-- If privacy is NOT specified, ALWAYS set privacy to "private".
-- NEVER default to "public" without explicit user consent.
-This ensures sensitive information is not unintentionally exposed.
-
-## Interaction Guidelines
-1. Clarify intent: When a request is vague, ask polite clarifying questions.
-2. Transparency: If information cannot be verified, clearly state limitations and suggest alternatives.
-3. Explain outcomes: When retrieving or publishing data, explain what happened in simple terms.
-4. Accessibility: Use examples, step-by-step reasoning, or simple metaphors to make complex concepts understandable.
-5. Trustworthy behavior: Always emphasize verifiability and reliability of knowledge retrieved or created.
-
-## Examples of Behavior
-- User asks to publish knowledge without specifying privacy → Agent publishes with "privacy": "private" and explains:
-"I’ve published this knowledge privately so only you (or authorized parties) can access it. If you’d like it public, just let me know."
-
-- User asks to retrieve knowledge → Agent uses MCP retrieval tools and explains results in a simple, structured way.
-
-- User asks a complex analytical question → Agent retrieves relevant knowledge from the DKG, performs the analysis, and presents results in a clear format (e.g., list, table, etc.).
-`.trim();
diff --git a/apps/agent/src/shared/prompts/defaultSystemPrompt.ts b/apps/agent/src/shared/prompts/defaultSystemPrompt.ts
new file mode 100644
index 00000000..7cdd1086
--- /dev/null
+++ b/apps/agent/src/shared/prompts/defaultSystemPrompt.ts
@@ -0,0 +1,238 @@
+export const DEFAULT_SYSTEM_PROMPT = `
+You are a DKG Agent that helps users interact with the OriginTrail Decentralized Knowledge Graph (DKG) using available Model Context Protocol (MCP) tools.
+Refer to yourself as "agent", not "assistant". When replying, use markdown (e.g. bold text, bullet points, tables, etc.) and codeblocks where appropriate to convey messages in a more organized and structured manner.
+
+## Role & Communication Style
+
+Help users create, retrieve, and analyze verifiable knowledge on the DKG in a friendly, approachable way. Communicate like a helpful colleague, not a technical manual.
+
+Always use plain, non-technical language. Hide complexity behind simple concepts:
+- Say "add to the DKG" instead of "publish a knowledge asset" or "create JSON-LD"
+- Say "search the DKG" instead of "run a SPARQL query"
+- Say "your document" instead of "blob" or "file ID"
+- Say "the DKG" instead of explaining decentralized infrastructure
+- Never mention "JSON-LD", "SPARQL", "UAL", "Schema.org", "FOAF", or other technical terms unless the user uses them first
+- If the user uses technical terms first, you may respond in kind
+
+Technical details (query language, identifiers, internal formats, ontologies, namespaces, prefixes, tool names) are internal. Do not reveal them unless the user explicitly asks or uses those terms first.
+
+Core responsibilities:
+- Search the DKG and explain findings in simple terms
+- Help users add documents or information to the DKG
+- Convert PDF, DOCX, and PPTX documents into structured knowledge
+- Analyze DKG data to answer complex questions
+
+## CRITICAL: Search the DKG First
+
+Before answering questions about real-world facts, research, data, or claims, you MUST search the DKG first using \`dkg-sparql-query\`.
+
+Exceptions - no DKG search needed for:
+- Greetings, small talk, or "what can you do?" questions
+- How-to questions about using the agent (unless user asks for DKG-backed facts)
+- Purely clarifying requests (you need more details before a search makes sense)
+- Reformatting, summarizing, or explaining text the user already provided (unless they ask "what does the DKG say?")
+
+Query limit: maximum 3 \`dkg-sparql-query\` calls per user request. If early attempts return nothing useful, refine and retry. After 3 attempts, summarize what you found (or didn't) and move on.
+
+After searching:
+- If the DKG has relevant knowledge -> use it. Begin with: "Based on knowledge in the DKG..."
+- If the DKG has no relevant knowledge -> you may provide general knowledge, but you MUST state:
+ "Note: I did not find this information on the DKG. The following is based on general knowledge and is not verifiable on the Decentralized Knowledge Graph."
+
+Guardrail: Only state conclusions directly supported by retrieved results. If results are incomplete or ambiguous, say so. Do not fill gaps with assumptions - clearly label any general context as unverifiable.
+
+## Knowledge Retrieval [internal]
+
+\`dkg-sparql-query\` is the primary tool for ALL searches and information retrieval.
+\`dkg-get\` is ONLY for fetching by UAL (Unique Asset Locator). UAL format examples:
+- did:dkg:otp:2043/0x8f678eB0E57ee8A109B295710E23076fA3a443fe/6200395
+- did:dkg:otp:2043/0x8f678eB0E57ee8A109B295710E23076fA3a443fe/6200395/1
+Do NOT use \`dkg-get\` with DOIs, URLs, or any other identifier format.
+
+Example SPARQL queries:
+
+Find reports by author:
+PREFIX schema:
+SELECT ?report ?title ?dateCreated
+WHERE {
+ ?report a schema:Report ;
+ schema:name ?title ;
+ schema:author ?author ;
+ schema:dateCreated ?dateCreated .
+ ?author schema:name "Jane Smith" .
+}
+
+Find organizations mentioned in documents:
+PREFIX schema:
+SELECT DISTINCT ?orgName
+WHERE {
+ ?doc schema:about ?org .
+ ?org a schema:Organization ;
+ schema:name ?orgName .
+}
+
+Find people and email addresses:
+PREFIX schema:
+PREFIX foaf:
+SELECT ?name ?email
+WHERE {
+ ?person a schema:Person ;
+ schema:name ?name .
+ OPTIONAL { ?person foaf:mbox ?email }
+}
+
+Find reports from a time period:
+PREFIX schema:
+PREFIX xsd:
+SELECT ?title ?author ?dateCreated
+WHERE {
+ ?report a schema:Report ;
+ schema:name ?title ;
+ schema:dateCreated ?dateCreated .
+ OPTIONAL { ?report schema:author/schema:name ?author }
+ FILTER(?dateCreated >= "2025-10-01"^^xsd:date)
+}
+ORDER BY DESC(?dateCreated)
+
+## Knowledge Publishing
+
+When a user wants to add knowledge to the DKG, follow the appropriate workflow.
+
+For documents (PDF, DOCX, PPTX):
+1. Convert to Markdown using the document-to-markdown tool.
+2. Deep Knowledge Extraction: analyze the ENTIRE markdown - not just metadata and abstracts. Extract ALL substantive knowledge (methodology, results, findings, data points, conclusions).
+3. Transform to JSON-LD [internal]: create a comprehensive, richly-structured representation capturing the full depth.
+4. Publish to DKG using the create tool if requested.
+
+CRITICAL: Deep Knowledge Extraction
+Extract comprehensive knowledge, not surface-level metadata:
+
+For scientific/research papers:
+- Study objectives, hypotheses, methodology, study design (sample sizes, duration, protocols)
+- Demographics, inclusion/exclusion criteria, interventions studied
+- All quantitative results (percentages, p-values, confidence intervals)
+- Primary/secondary outcomes, adverse events, safety data
+- Key findings, conclusions, limitations, comparisons to prior research
+- Tables and figures data (describe key data from each)
+
+For business/financial documents:
+- Financial metrics and KPIs with values, trends, comparisons over time
+- Strategic initiatives and outcomes, risk factors, projections with supporting data
+
+For technical documents:
+- Specifications, parameters, performance benchmarks
+- Implementation details, requirements, known issues
+
+The goal: a knowledge asset so complete that someone can get substantive answers from the DKG without reading the original document.
+
+For text or data provided in chat:
+1. Analyze what entities, relationships, and information to add.
+2. Transform to JSON-LD [internal] using recommended vocabularies.
+3. Publish to DKG using the create tool if requested.
+
+### JSON-LD guidance [internal]
+- Use recommended vocabularies in @context
+- Assign specific, meaningful types and unique identifiers
+- Extract all relevant properties (dates, locations, identifiers, quantities, statuses)
+- Represent relationships between entities using nested objects with their own types
+- Capture as much structured information as the source provides
+
+Example JSON-LD - research paper [internal]:
+\`\`\`json
+{
+ "@context": {
+ "@vocab": "https://schema.org/",
+ "foaf": "http://xmlns.com/foaf/0.1/"
+ },
+ "@id": "https://doi.org/10.1016/j.example.2025.12345",
+ "@type": ["ScholarlyArticle", "MedicalScholarlyArticle"],
+ "name": "Long-term Efficacy of Drug X in Patients with Condition Y",
+ "abstract": "Objective: To evaluate long-term efficacy... [full abstract]",
+ "datePublished": "2025-01-15",
+ "author": [
+ {
+ "@type": "Person",
+ "name": "Jane Smith",
+ "affiliation": {"@type": "Organization", "name": "University Hospital"}
+ }
+ ],
+ "publisher": {"@type": "Organization", "name": "Elsevier"},
+ "isPartOf": {
+ "@type": "Periodical",
+ "name": "Journal of Medical Research",
+ "volumeNumber": "42",
+ "issueNumber": "3"
+ },
+ "keywords": ["drug X", "condition Y", "randomized controlled trial"],
+ "studyDesign": {
+ "@type": "MedicalStudy",
+ "studyType": "Randomized, double-blind, placebo-controlled trial",
+ "healthCondition": {"@type": "MedicalCondition", "name": "Condition Y"},
+ "studySubject": {
+ "@type": "MedicalStudy",
+ "description": "Adults aged 18-65 with diagnosed Condition Y",
+ "numberOfParticipants": 740
+ }
+ },
+ "studyResults": [
+ {
+ "@type": "PropertyValue",
+ "name": "Primary Outcome - Responder Rate",
+ "value": "52.3% vs 23.1% placebo",
+ "statisticalAnalysis": "p < 0.001"
+ }
+ ],
+ "adverseEvents": [
+ {
+ "@type": "PropertyValue",
+ "name": "Most Common TEAE",
+ "value": "Somnolence (14.2%), Dizziness (11.8%), Fatigue (8.3%)"
+ }
+ ],
+ "conclusion": "Drug X demonstrated sustained efficacy across all patient subgroups.",
+ "limitations": "Post hoc analysis; results should be interpreted with caution."
+}
+\`\`\`
+
+## Privacy
+
+When creating knowledge assets:
+- If privacy is specified, follow the user's instruction.
+- If NOT specified, ALWAYS default to "private".
+- NEVER set privacy to "public" without explicit user confirmation (e.g., "Yes, make it public").
+- In simple language: "I'll keep it private unless you tell me to make it public."
+
+## Ontologies [internal]
+
+Use these vocabularies when creating or querying knowledge assets:
+- Schema.org: https://schema.org
+- FOAF: http://xmlns.com/foaf/0.1/
+
+PREFIX schema:
+PREFIX foaf:
+
+## Guidelines
+
+1. Clarify intent: When a request is vague, ask polite clarifying questions in plain language.
+2. Transparency: If information cannot be verified, clearly state limitations and suggest alternatives.
+3. Explain outcomes: Describe what happened in simple terms (e.g., "I found 3 relevant studies" not "The query returned 3 results").
+4. Trustworthy behavior: Emphasize that knowledge comes from the DKG and is verifiable when it does.
+5. Proactive assistance: When a user uploads a document, offer to add it to the DKG. When a user asks a factual question, search the DKG first.
+6. Honest about capabilities: Only offer actions you can actually perform. Use the MCP tool list to determine what you can do. You cannot display images, open URLs, send emails, or access external systems except through provided MCP tools.
+
+## Response Examples
+
+Publishing a document:
+- "I've processed your document and pulled out the key information. Would you like me to add it to the DKG?"
+- After publishing: "Done! The key findings are now discoverable on the DKG. Want me to look for related information?"
+
+Searching:
+- "I found 3 studies about Drug X in the DKG. Here's what they show..." (in plain language)
+
+Nothing found:
+- "I searched the DKG but didn't find anything about Drug X. I can share what I know from general knowledge, but it won't be verifiable on the DKG. Would that help?"
+
+Technical terms - mirror the user's language:
+- If user says "Can you run a SPARQL query?" -> you may use technical language
+- If user says "Find stuff about vaccines" -> keep it simple
+`.trim();
diff --git a/package-lock.json b/package-lock.json
index 150c7fe3..46237b6d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2897,20 +2897,6 @@
"node": ">=14.0"
}
},
- "node_modules/@digitalbazaar/http-client/node_modules/web-streams-polyfill": {
- "version": "4.2.0",
- "license": "MIT",
- "optional": true,
- "peer": true,
- "workspaces": [
- "test/benchmark-test",
- "test/rollup-test",
- "test/webpack-test"
- ],
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/@dkg/agent": {
"resolved": "apps/agent",
"link": true
@@ -3018,68 +3004,59 @@
"source-map-support": "^0.5.21"
}
},
- "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": {
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": {
"version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"cpu": [
- "arm64"
+ "arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "darwin"
+ "android"
],
"engines": {
"node": ">=12"
}
},
- "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": {
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": {
"version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "hasInstallScript": true,
"license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
+ "optional": true,
+ "os": [
+ "android"
+ ],
"engines": {
"node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
}
},
- "node_modules/@esbuild-kit/esm-loader": {
- "version": "2.6.5",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "@esbuild-kit/core-utils": "^3.3.2",
- "get-tsconfig": "^4.7.0"
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.25.11",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.20",
"cpu": [
"arm64"
],
@@ -3090,909 +3067,1103 @@
"darwin"
],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.9.0",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "eslint-visitor-keys": "^3.4.3"
- },
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ "node": ">=12"
}
},
- "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
+ "node": ">=12"
}
},
- "node_modules/@eslint-community/regexpp": {
- "version": "4.12.2",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
"engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ "node": ">=12"
}
},
- "node_modules/@eslint/config-array": {
- "version": "0.21.1",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/object-schema": "^2.1.7",
- "debug": "^4.3.1",
- "minimatch": "^3.1.2"
- },
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=12"
}
},
- "node_modules/@eslint/config-array/node_modules/brace-expansion": {
- "version": "1.1.12",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@eslint/config-array/node_modules/minimatch": {
- "version": "3.1.2",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
"dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "*"
+ "node": ">=12"
}
},
- "node_modules/@eslint/config-helpers": {
- "version": "0.4.1",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
"dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.16.0"
- },
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=12"
}
},
- "node_modules/@eslint/core": {
- "version": "0.16.0",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
"dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=12"
}
},
- "node_modules/@eslint/eslintrc": {
- "version": "3.3.1",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^10.0.1",
- "globals": "^14.0.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.1.2",
- "strip-json-comments": "^3.1.1"
- },
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
+ "node": ">=12"
}
},
- "node_modules/@eslint/eslintrc/node_modules/argparse": {
- "version": "2.0.1",
- "dev": true,
- "license": "Python-2.0"
- },
- "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
- "version": "1.1.12",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
- "version": "4.1.0",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
"dev": true,
"license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@eslint/eslintrc/node_modules/minimatch": {
- "version": "3.1.2",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": "*"
+ "node": ">=12"
}
},
- "node_modules/@eslint/js": {
- "version": "9.38.0",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
+ "node": ">=12"
}
},
- "node_modules/@eslint/object-schema": {
- "version": "2.1.7",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=12"
}
},
- "node_modules/@eslint/plugin-kit": {
- "version": "0.4.0",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.16.0",
- "levn": "^0.4.1"
- },
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=12"
}
},
- "node_modules/@ethereumjs/common": {
- "version": "2.6.5",
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "crc-32": "^1.2.0",
- "ethereumjs-util": "^7.1.5"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@ethereumjs/rlp": {
- "version": "5.0.2",
- "license": "MPL-2.0",
- "bin": {
- "rlp": "bin/rlp.cjs"
- },
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
"engines": {
- "node": ">=18"
+ "node": ">=12"
}
},
- "node_modules/@ethereumjs/tx": {
- "version": "3.5.2",
- "license": "MPL-2.0",
- "dependencies": {
- "@ethereumjs/common": "^2.6.4",
- "ethereumjs-util": "^7.1.5"
+ "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/@ethereumjs/util": {
- "version": "9.1.0",
- "license": "MPL-2.0",
- "dependencies": {
- "@ethereumjs/rlp": "^5.0.2",
- "ethereum-cryptography": "^2.2.1"
+ "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": {
+ "version": "0.18.20",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
},
"engines": {
- "node": ">=18"
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
}
},
- "node_modules/@ethereumjs/util/node_modules/@noble/curves": {
- "version": "1.4.2",
+ "node_modules/@esbuild-kit/esm-loader": {
+ "version": "2.6.5",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@noble/hashes": "1.4.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
+ "@esbuild-kit/core-utils": "^3.3.2",
+ "get-tsconfig": "^4.7.0"
}
},
- "node_modules/@ethereumjs/util/node_modules/@noble/hashes": {
- "version": "1.4.0",
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz",
+ "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
"engines": {
- "node": ">= 16"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
+ "node": ">=18"
}
},
- "node_modules/@ethereumjs/util/node_modules/@scure/base": {
- "version": "1.1.9",
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz",
+ "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
"license": "MIT",
- "funding": {
- "url": "https://paulmillr.com/funding/"
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethereumjs/util/node_modules/@scure/bip32": {
- "version": "1.4.0",
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz",
+ "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@noble/curves": "~1.4.0",
- "@noble/hashes": "~1.4.0",
- "@scure/base": "~1.1.6"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethereumjs/util/node_modules/@scure/bip39": {
- "version": "1.3.0",
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz",
+ "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@noble/hashes": "~1.4.0",
- "@scure/base": "~1.1.6"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": {
- "version": "2.2.1",
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.11",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@noble/curves": "1.4.2",
- "@noble/hashes": "1.4.0",
- "@scure/bip32": "1.4.0",
- "@scure/bip39": "1.3.0"
- }
- },
- "node_modules/@ethersproject/abi": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "optional": true,
+ "os": [
+ "darwin"
],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/address": "^5.8.0",
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/constants": "^5.8.0",
- "@ethersproject/hash": "^5.8.0",
- "@ethersproject/keccak256": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/strings": "^5.8.0"
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/abstract-provider": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz",
+ "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/networks": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/transactions": "^5.8.0",
- "@ethersproject/web": "^5.8.0"
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/abstract-signer": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz",
+ "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-provider": "^5.8.0",
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/properties": "^5.8.0"
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/address": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz",
+ "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/keccak256": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/rlp": "^5.8.0"
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/base64": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz",
+ "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==",
+ "cpu": [
+ "arm"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/basex": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz",
+ "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/properties": "^5.8.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/bignumber": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz",
+ "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==",
+ "cpu": [
+ "ia32"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "bn.js": "^5.2.1"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/bytes": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz",
+ "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==",
+ "cpu": [
+ "loong64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/constants": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz",
+ "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==",
+ "cpu": [
+ "mips64el"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bignumber": "^5.8.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/contracts": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz",
+ "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==",
+ "cpu": [
+ "ppc64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/abi": "^5.8.0",
- "@ethersproject/abstract-provider": "^5.8.0",
- "@ethersproject/abstract-signer": "^5.8.0",
- "@ethersproject/address": "^5.8.0",
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/constants": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/transactions": "^5.8.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/hash": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz",
+ "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==",
+ "cpu": [
+ "riscv64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-signer": "^5.8.0",
- "@ethersproject/address": "^5.8.0",
- "@ethersproject/base64": "^5.8.0",
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/keccak256": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/strings": "^5.8.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/hdnode": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz",
+ "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==",
+ "cpu": [
+ "s390x"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-signer": "^5.8.0",
- "@ethersproject/basex": "^5.8.0",
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/pbkdf2": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/sha2": "^5.8.0",
- "@ethersproject/signing-key": "^5.8.0",
- "@ethersproject/strings": "^5.8.0",
- "@ethersproject/transactions": "^5.8.0",
- "@ethersproject/wordlists": "^5.8.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/json-wallets": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz",
+ "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-signer": "^5.8.0",
- "@ethersproject/address": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/hdnode": "^5.8.0",
- "@ethersproject/keccak256": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/pbkdf2": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/random": "^5.8.0",
- "@ethersproject/strings": "^5.8.0",
- "@ethersproject/transactions": "^5.8.0",
- "aes-js": "3.0.0",
- "scrypt-js": "3.0.1"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/json-wallets/node_modules/aes-js": {
- "version": "3.0.0",
- "license": "MIT"
- },
- "node_modules/@ethersproject/keccak256": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz",
+ "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "js-sha3": "0.8.0"
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/logger": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz",
+ "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==",
+ "cpu": [
+ "x64"
],
- "license": "MIT"
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
},
- "node_modules/@ethersproject/networks": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz",
+ "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/pbkdf2": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz",
+ "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/sha2": "^5.8.0"
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/properties": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz",
+ "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/providers": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz",
+ "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-provider": "^5.8.0",
- "@ethersproject/abstract-signer": "^5.8.0",
- "@ethersproject/address": "^5.8.0",
- "@ethersproject/base64": "^5.8.0",
- "@ethersproject/basex": "^5.8.0",
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/constants": "^5.8.0",
- "@ethersproject/hash": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/networks": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/random": "^5.8.0",
- "@ethersproject/rlp": "^5.8.0",
- "@ethersproject/sha2": "^5.8.0",
- "@ethersproject/strings": "^5.8.0",
- "@ethersproject/transactions": "^5.8.0",
- "@ethersproject/web": "^5.8.0",
- "bech32": "1.1.4",
- "ws": "8.18.0"
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/providers/node_modules/ws": {
- "version": "8.18.0",
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz",
+ "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
"engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/random": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz",
+ "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==",
+ "cpu": [
+ "ia32"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/rlp": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz",
+ "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@ethersproject/sha2": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "hash.js": "1.1.7"
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
- "node_modules/@ethersproject/signing-key": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "bn.js": "^5.2.1",
- "elliptic": "6.6.1",
- "hash.js": "1.1.7"
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
- "node_modules/@ethersproject/solidity": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "dev": true,
"license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.1",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/keccak256": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/sha2": "^5.8.0",
- "@ethersproject/strings": "^5.8.0"
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@ethersproject/strings": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
+ "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/constants": "^5.8.0",
- "@ethersproject/logger": "^5.8.0"
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
}
},
- "node_modules/@ethersproject/transactions": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "@ethersproject/address": "^5.8.0",
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/constants": "^5.8.0",
- "@ethersproject/keccak256": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/rlp": "^5.8.0",
- "@ethersproject/signing-key": "^5.8.0"
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
}
},
- "node_modules/@ethersproject/units": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.1",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "@ethersproject/bignumber": "^5.8.0",
- "@ethersproject/constants": "^5.8.0",
- "@ethersproject/logger": "^5.8.0"
+ "@eslint/core": "^0.16.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@ethersproject/wallet": {
- "version": "5.8.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
+ "node_modules/@eslint/core": {
+ "version": "0.16.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/argparse": {
+ "version": "2.0.1",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
+ "version": "4.1.0",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.38.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.7",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.0",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.16.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@ethereumjs/common": {
+ "version": "2.6.5",
+ "license": "MIT",
+ "dependencies": {
+ "crc-32": "^1.2.0",
+ "ethereumjs-util": "^7.1.5"
+ }
+ },
+ "node_modules/@ethereumjs/rlp": {
+ "version": "5.0.2",
+ "license": "MPL-2.0",
+ "bin": {
+ "rlp": "bin/rlp.cjs"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@ethereumjs/tx": {
+ "version": "3.5.2",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "@ethereumjs/common": "^2.6.4",
+ "ethereumjs-util": "^7.1.5"
+ }
+ },
+ "node_modules/@ethereumjs/util": {
+ "version": "9.1.0",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "@ethereumjs/rlp": "^5.0.2",
+ "ethereum-cryptography": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@ethereumjs/util/node_modules/@noble/curves": {
+ "version": "1.4.2",
+ "license": "MIT",
+ "dependencies": {
+ "@noble/hashes": "1.4.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@ethereumjs/util/node_modules/@noble/hashes": {
+ "version": "1.4.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@ethereumjs/util/node_modules/@scure/base": {
+ "version": "1.1.9",
+ "license": "MIT",
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@ethereumjs/util/node_modules/@scure/bip32": {
+ "version": "1.4.0",
+ "license": "MIT",
+ "dependencies": {
+ "@noble/curves": "~1.4.0",
+ "@noble/hashes": "~1.4.0",
+ "@scure/base": "~1.1.6"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@ethereumjs/util/node_modules/@scure/bip39": {
+ "version": "1.3.0",
+ "license": "MIT",
+ "dependencies": {
+ "@noble/hashes": "~1.4.0",
+ "@scure/base": "~1.1.6"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": {
+ "version": "2.2.1",
+ "license": "MIT",
+ "dependencies": {
+ "@noble/curves": "1.4.2",
+ "@noble/hashes": "1.4.0",
+ "@scure/bip32": "1.4.0",
+ "@scure/bip39": "1.3.0"
+ }
+ },
+ "node_modules/@ethersproject/abi": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
"dependencies": {
- "@ethersproject/abstract-provider": "^5.8.0",
- "@ethersproject/abstract-signer": "^5.8.0",
"@ethersproject/address": "^5.8.0",
"@ethersproject/bignumber": "^5.8.0",
"@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/constants": "^5.8.0",
"@ethersproject/hash": "^5.8.0",
- "@ethersproject/hdnode": "^5.8.0",
- "@ethersproject/json-wallets": "^5.8.0",
"@ethersproject/keccak256": "^5.8.0",
"@ethersproject/logger": "^5.8.0",
"@ethersproject/properties": "^5.8.0",
- "@ethersproject/random": "^5.8.0",
- "@ethersproject/signing-key": "^5.8.0",
- "@ethersproject/transactions": "^5.8.0",
- "@ethersproject/wordlists": "^5.8.0"
+ "@ethersproject/strings": "^5.8.0"
}
},
- "node_modules/@ethersproject/web": {
+ "node_modules/@ethersproject/abstract-provider": {
"version": "5.8.0",
"funding": [
{
@@ -4006,14 +4177,16 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/base64": "^5.8.0",
+ "@ethersproject/bignumber": "^5.8.0",
"@ethersproject/bytes": "^5.8.0",
"@ethersproject/logger": "^5.8.0",
+ "@ethersproject/networks": "^5.8.0",
"@ethersproject/properties": "^5.8.0",
- "@ethersproject/strings": "^5.8.0"
+ "@ethersproject/transactions": "^5.8.0",
+ "@ethersproject/web": "^5.8.0"
}
},
- "node_modules/@ethersproject/wordlists": {
+ "node_modules/@ethersproject/abstract-signer": {
"version": "5.8.0",
"funding": [
{
@@ -4027,27 +4200,622 @@
],
"license": "MIT",
"dependencies": {
+ "@ethersproject/abstract-provider": "^5.8.0",
+ "@ethersproject/bignumber": "^5.8.0",
"@ethersproject/bytes": "^5.8.0",
- "@ethersproject/hash": "^5.8.0",
"@ethersproject/logger": "^5.8.0",
- "@ethersproject/properties": "^5.8.0",
- "@ethersproject/strings": "^5.8.0"
+ "@ethersproject/properties": "^5.8.0"
}
},
- "node_modules/@expo-google-fonts/manrope": {
- "version": "0.4.2",
- "license": "MIT AND OFL-1.1"
- },
- "node_modules/@expo-google-fonts/space-grotesk": {
- "version": "0.4.1",
- "license": "MIT AND OFL-1.1"
- },
- "node_modules/@expo/cli": {
- "version": "0.24.20",
+ "node_modules/@ethersproject/address": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "@0no-co/graphql.web": "^1.0.8",
- "@babel/runtime": "^7.20.0",
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/keccak256": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/rlp": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/base64": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/basex": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/bignumber": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "bn.js": "^5.2.1"
+ }
+ },
+ "node_modules/@ethersproject/bytes": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/logger": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/constants": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/contracts": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abi": "^5.8.0",
+ "@ethersproject/abstract-provider": "^5.8.0",
+ "@ethersproject/abstract-signer": "^5.8.0",
+ "@ethersproject/address": "^5.8.0",
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/constants": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/transactions": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/hash": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.8.0",
+ "@ethersproject/address": "^5.8.0",
+ "@ethersproject/base64": "^5.8.0",
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/keccak256": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/strings": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/hdnode": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.8.0",
+ "@ethersproject/basex": "^5.8.0",
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/pbkdf2": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/sha2": "^5.8.0",
+ "@ethersproject/signing-key": "^5.8.0",
+ "@ethersproject/strings": "^5.8.0",
+ "@ethersproject/transactions": "^5.8.0",
+ "@ethersproject/wordlists": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/json-wallets": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-signer": "^5.8.0",
+ "@ethersproject/address": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/hdnode": "^5.8.0",
+ "@ethersproject/keccak256": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/pbkdf2": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/random": "^5.8.0",
+ "@ethersproject/strings": "^5.8.0",
+ "@ethersproject/transactions": "^5.8.0",
+ "aes-js": "3.0.0",
+ "scrypt-js": "3.0.1"
+ }
+ },
+ "node_modules/@ethersproject/json-wallets/node_modules/aes-js": {
+ "version": "3.0.0",
+ "license": "MIT"
+ },
+ "node_modules/@ethersproject/keccak256": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "js-sha3": "0.8.0"
+ }
+ },
+ "node_modules/@ethersproject/logger": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@ethersproject/networks": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/logger": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/pbkdf2": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/sha2": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/properties": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/logger": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/providers": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.8.0",
+ "@ethersproject/abstract-signer": "^5.8.0",
+ "@ethersproject/address": "^5.8.0",
+ "@ethersproject/base64": "^5.8.0",
+ "@ethersproject/basex": "^5.8.0",
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/constants": "^5.8.0",
+ "@ethersproject/hash": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/networks": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/random": "^5.8.0",
+ "@ethersproject/rlp": "^5.8.0",
+ "@ethersproject/sha2": "^5.8.0",
+ "@ethersproject/strings": "^5.8.0",
+ "@ethersproject/transactions": "^5.8.0",
+ "@ethersproject/web": "^5.8.0",
+ "bech32": "1.1.4",
+ "ws": "8.18.0"
+ }
+ },
+ "node_modules/@ethersproject/providers/node_modules/ws": {
+ "version": "8.18.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@ethersproject/random": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/rlp": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/sha2": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "hash.js": "1.1.7"
+ }
+ },
+ "node_modules/@ethersproject/signing-key": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "bn.js": "^5.2.1",
+ "elliptic": "6.6.1",
+ "hash.js": "1.1.7"
+ }
+ },
+ "node_modules/@ethersproject/solidity": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/keccak256": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/sha2": "^5.8.0",
+ "@ethersproject/strings": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/strings": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/constants": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/transactions": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/address": "^5.8.0",
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/constants": "^5.8.0",
+ "@ethersproject/keccak256": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/rlp": "^5.8.0",
+ "@ethersproject/signing-key": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/units": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/constants": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/wallet": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.8.0",
+ "@ethersproject/abstract-signer": "^5.8.0",
+ "@ethersproject/address": "^5.8.0",
+ "@ethersproject/bignumber": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/hash": "^5.8.0",
+ "@ethersproject/hdnode": "^5.8.0",
+ "@ethersproject/json-wallets": "^5.8.0",
+ "@ethersproject/keccak256": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/random": "^5.8.0",
+ "@ethersproject/signing-key": "^5.8.0",
+ "@ethersproject/transactions": "^5.8.0",
+ "@ethersproject/wordlists": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/web": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/base64": "^5.8.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/strings": "^5.8.0"
+ }
+ },
+ "node_modules/@ethersproject/wordlists": {
+ "version": "5.8.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/hash": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
+ "@ethersproject/strings": "^5.8.0"
+ }
+ },
+ "node_modules/@expo-google-fonts/manrope": {
+ "version": "0.4.2",
+ "license": "MIT AND OFL-1.1"
+ },
+ "node_modules/@expo-google-fonts/space-grotesk": {
+ "version": "0.4.1",
+ "license": "MIT AND OFL-1.1"
+ },
+ "node_modules/@expo/cli": {
+ "version": "0.24.20",
+ "license": "MIT",
+ "dependencies": {
+ "@0no-co/graphql.web": "^1.0.8",
+ "@babel/runtime": "^7.20.0",
"@expo/code-signing-certificates": "^0.0.5",
"@expo/config": "~11.0.13",
"@expo/config-plugins": "~10.1.2",
@@ -5560,14 +6328,165 @@
"dev": true,
"license": "MIT",
"dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
+ "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "make-dir": "^3.1.0",
+ "node-fetch": "^2.6.7",
+ "nopt": "^5.0.0",
+ "npmlog": "^5.0.1",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.5",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "node-pre-gyp": "bin/node-pre-gyp"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "license": "ISC",
+ "optional": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "license": "ISC",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
},
"engines": {
- "node": ">=6 <7 || >=8"
+ "node": ">=10"
}
},
+ "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC",
+ "optional": true
+ },
"node_modules/@mistralai/mistralai": {
"version": "1.10.0",
"dependencies": {
@@ -6138,6 +7057,26 @@
"@noble/hashes": "^1.1.5"
}
},
+ "node_modules/@pdf-lib/standard-fonts": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
+ "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pako": "^1.0.6"
+ }
+ },
+ "node_modules/@pdf-lib/upng": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
+ "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pako": "^1.0.10"
+ }
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"license": "MIT",
@@ -6204,15 +7143,6 @@
"scale-ts": "^1.6.0"
}
},
- "node_modules/@polkadot-api/substrate-client": {
- "version": "0.1.4",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@polkadot-api/json-rpc-provider": "0.0.1",
- "@polkadot-api/utils": "0.1.0"
- }
- },
"node_modules/@polkadot-api/utils": {
"version": "0.1.0",
"license": "MIT",
@@ -7017,110 +7947,390 @@
"react-native-screens": ">= 4.0.0"
}
},
- "node_modules/@react-navigation/core": {
- "version": "7.13.0",
+ "node_modules/@react-navigation/core": {
+ "version": "7.13.0",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/routers": "^7.5.1",
+ "escape-string-regexp": "^4.0.0",
+ "fast-deep-equal": "^3.1.3",
+ "nanoid": "^3.3.11",
+ "query-string": "^7.1.3",
+ "react-is": "^19.1.0",
+ "use-latest-callback": "^0.2.4",
+ "use-sync-external-store": "^1.5.0"
+ },
+ "peerDependencies": {
+ "react": ">= 18.2.0"
+ }
+ },
+ "node_modules/@react-navigation/core/node_modules/react-is": {
+ "version": "19.2.0",
+ "license": "MIT"
+ },
+ "node_modules/@react-navigation/elements": {
+ "version": "2.7.1",
+ "license": "MIT",
+ "dependencies": {
+ "color": "^4.2.3",
+ "use-latest-callback": "^0.2.4",
+ "use-sync-external-store": "^1.5.0"
+ },
+ "peerDependencies": {
+ "@react-native-masked-view/masked-view": ">= 0.2.0",
+ "@react-navigation/native": "^7.1.19",
+ "react": ">= 18.2.0",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@react-native-masked-view/masked-view": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@react-navigation/native": {
+ "version": "7.1.19",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/core": "^7.13.0",
+ "escape-string-regexp": "^4.0.0",
+ "fast-deep-equal": "^3.1.3",
+ "nanoid": "^3.3.11",
+ "use-latest-callback": "^0.2.4"
+ },
+ "peerDependencies": {
+ "react": ">= 18.2.0",
+ "react-native": "*"
+ }
+ },
+ "node_modules/@react-navigation/native-stack": {
+ "version": "7.6.0",
+ "license": "MIT",
+ "dependencies": {
+ "@react-navigation/elements": "^2.7.1",
+ "color": "^4.2.3",
+ "sf-symbols-typescript": "^2.1.0",
+ "warn-once": "^0.1.1"
+ },
+ "peerDependencies": {
+ "@react-navigation/native": "^7.1.19",
+ "react": ">= 18.2.0",
+ "react-native": "*",
+ "react-native-safe-area-context": ">= 4.0.0",
+ "react-native-screens": ">= 4.0.0"
+ }
+ },
+ "node_modules/@react-navigation/routers": {
+ "version": "7.5.1",
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz",
+ "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz",
+ "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.52.5",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz",
+ "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz",
+ "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz",
+ "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz",
+ "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz",
+ "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz",
+ "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz",
+ "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz",
+ "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz",
+ "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz",
+ "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz",
+ "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz",
+ "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@react-navigation/routers": "^7.5.1",
- "escape-string-regexp": "^4.0.0",
- "fast-deep-equal": "^3.1.3",
- "nanoid": "^3.3.11",
- "query-string": "^7.1.3",
- "react-is": "^19.1.0",
- "use-latest-callback": "^0.2.4",
- "use-sync-external-store": "^1.5.0"
- },
- "peerDependencies": {
- "react": ">= 18.2.0"
- }
+ "optional": true,
+ "os": [
+ "linux"
+ ]
},
- "node_modules/@react-navigation/core/node_modules/react-is": {
- "version": "19.2.0",
- "license": "MIT"
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz",
+ "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
},
- "node_modules/@react-navigation/elements": {
- "version": "2.7.1",
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz",
+ "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "color": "^4.2.3",
- "use-latest-callback": "^0.2.4",
- "use-sync-external-store": "^1.5.0"
- },
- "peerDependencies": {
- "@react-native-masked-view/masked-view": ">= 0.2.0",
- "@react-navigation/native": "^7.1.19",
- "react": ">= 18.2.0",
- "react-native": "*",
- "react-native-safe-area-context": ">= 4.0.0"
- },
- "peerDependenciesMeta": {
- "@react-native-masked-view/masked-view": {
- "optional": true
- }
- }
+ "optional": true,
+ "os": [
+ "linux"
+ ]
},
- "node_modules/@react-navigation/native": {
- "version": "7.1.19",
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz",
+ "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@react-navigation/core": "^7.13.0",
- "escape-string-regexp": "^4.0.0",
- "fast-deep-equal": "^3.1.3",
- "nanoid": "^3.3.11",
- "use-latest-callback": "^0.2.4"
- },
- "peerDependencies": {
- "react": ">= 18.2.0",
- "react-native": "*"
- }
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
},
- "node_modules/@react-navigation/native-stack": {
- "version": "7.6.0",
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz",
+ "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@react-navigation/elements": "^2.7.1",
- "color": "^4.2.3",
- "sf-symbols-typescript": "^2.1.0",
- "warn-once": "^0.1.1"
- },
- "peerDependencies": {
- "@react-navigation/native": "^7.1.19",
- "react": ">= 18.2.0",
- "react-native": "*",
- "react-native-safe-area-context": ">= 4.0.0",
- "react-native-screens": ">= 4.0.0"
- }
+ "optional": true,
+ "os": [
+ "win32"
+ ]
},
- "node_modules/@react-navigation/routers": {
- "version": "7.5.1",
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz",
+ "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.11"
- }
+ "optional": true,
+ "os": [
+ "win32"
+ ]
},
- "node_modules/@rollup/rollup-darwin-arm64": {
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz",
+ "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==",
"cpu": [
- "arm64"
+ "x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "darwin"
+ "win32"
]
},
- "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.52.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz",
- "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz",
+ "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==",
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
- "linux"
+ "win32"
]
},
"node_modules/@rtsao/scc": {
@@ -9028,6 +10238,13 @@
"three": ">=0.168"
}
},
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "license": "ISC",
+ "optional": true
+ },
"node_modules/abort-controller": {
"version": "3.0.0",
"license": "MIT",
@@ -9330,11 +10547,33 @@
"node": ">=8"
}
},
+ "node_modules/aproba": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz",
+ "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==",
+ "license": "ISC",
+ "optional": true
+ },
"node_modules/archy": {
"version": "1.0.0",
"dev": true,
"license": "MIT"
},
+ "node_modules/are-we-there-yet": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
+ "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
+ "deprecated": "This package is no longer supported.",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^3.6.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/arg": {
"version": "5.0.2",
"license": "MIT"
@@ -10883,6 +12122,22 @@
"version": "1.0.8",
"license": "Apache-2.0"
},
+ "node_modules/canvas": {
+ "version": "2.11.2",
+ "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz",
+ "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@mapbox/node-pre-gyp": "^1.0.0",
+ "nan": "^2.17.0",
+ "simple-get": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/canvas-color-tracker": {
"version": "1.3.2",
"license": "MIT",
@@ -10893,6 +12148,44 @@
"node": ">=12"
}
},
+ "node_modules/canvas/node_modules/decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "mimic-response": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/canvas/node_modules/mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/canvas/node_modules/simple-get": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
+ "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
"node_modules/caseless": {
"version": "0.12.0",
"license": "Apache-2.0"
@@ -11258,6 +12551,16 @@
"simple-swizzle": "^0.2.2"
}
},
+ "node_modules/color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "license": "ISC",
+ "optional": true,
+ "bin": {
+ "color-support": "bin.js"
+ }
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"license": "MIT",
@@ -11371,6 +12674,13 @@
"node": "^14.18.0 || >=16.10.0"
}
},
+ "node_modules/console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
+ "license": "ISC",
+ "optional": true
+ },
"node_modules/console-table-printer": {
"version": "2.15.0",
"license": "MIT",
@@ -12213,6 +13523,13 @@
"node": ">=0.4.0"
}
},
+ "node_modules/delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/denque": {
"version": "2.1.0",
"license": "Apache-2.0",
@@ -15370,6 +16687,20 @@
"version": "1.0.0",
"license": "ISC"
},
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/fsu": {
"version": "1.1.1",
"dev": true,
@@ -15409,6 +16740,35 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/gauge": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
+ "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
+ "deprecated": "This package is no longer supported.",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.2",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.1",
+ "object-assign": "^4.1.1",
+ "signal-exit": "^3.0.0",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/gauge/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "license": "ISC",
+ "optional": true
+ },
"node_modules/generate-function": {
"version": "2.3.1",
"license": "MIT",
@@ -16264,6 +17624,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
+ "license": "ISC",
+ "optional": true
+ },
"node_modules/hash-base": {
"version": "3.1.2",
"license": "MIT",
@@ -18420,7 +19787,7 @@
},
"node_modules/make-dir": {
"version": "3.1.0",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"semver": "^6.0.0"
@@ -18434,7 +19801,7 @@
},
"node_modules/make-dir/node_modules/semver": {
"version": "6.3.1",
- "dev": true,
+ "devOptional": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -19679,6 +21046,13 @@
"node": ">=12.0.0"
}
},
+ "node_modules/nan": {
+ "version": "2.25.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.25.0.tgz",
+ "integrity": "sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/nano-json-stream-parser": {
"version": "0.1.2",
"license": "MIT"
@@ -20060,7 +21434,23 @@
"version": "7.0.10",
"license": "MIT-0",
"engines": {
- "node": ">=6.0.0"
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/normalize-path": {
@@ -20102,6 +21492,20 @@
"node": ">=8"
}
},
+ "node_modules/npmlog": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
+ "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
+ "deprecated": "This package is no longer supported.",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "are-we-there-yet": "^2.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^3.0.0",
+ "set-blocking": "^2.0.0"
+ }
+ },
"node_modules/nth-check": {
"version": "2.1.1",
"license": "BSD-2-Clause",
@@ -20912,6 +22316,13 @@
"quansync": "^0.2.7"
}
},
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true,
+ "license": "(MIT AND Zlib)"
+ },
"node_modules/param-case": {
"version": "2.1.1",
"dev": true,
@@ -21187,6 +22598,26 @@
"node": ">= 0.10"
}
},
+ "node_modules/pdf-lib": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
+ "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pdf-lib/standard-fonts": "^1.0.0",
+ "@pdf-lib/upng": "^1.0.1",
+ "pako": "^1.0.11",
+ "tslib": "^1.11.1"
+ }
+ },
+ "node_modules/pdf-lib/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true,
+ "license": "0BSD"
+ },
"node_modules/performance-now": {
"version": "2.1.0",
"license": "MIT"
@@ -23374,7 +24805,7 @@
},
"node_modules/set-blocking": {
"version": "2.0.0",
- "dev": true,
+ "devOptional": true,
"license": "ISC"
},
"node_modules/set-function-length": {
@@ -23694,14 +25125,6 @@
"npm": ">= 3.0.0"
}
},
- "node_modules/smoldot": {
- "version": "2.0.26",
- "license": "GPL-3.0-or-later WITH Classpath-exception-2.0",
- "optional": true,
- "dependencies": {
- "ws": "^8.8.1"
- }
- },
"node_modules/snake-case": {
"version": "2.1.0",
"dev": true,
@@ -25257,6 +26680,21 @@
"fsevents": "~2.3.3"
}
},
+ "node_modules/tsx/node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/tunnel-agent": {
"version": "0.6.0",
"license": "Apache-2.0",
@@ -25283,6 +26721,20 @@
"turbo-windows-arm64": "2.5.8"
}
},
+ "node_modules/turbo-darwin-64": {
+ "version": "2.5.8",
+ "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.5.8.tgz",
+ "integrity": "sha512-Dh5bCACiHO8rUXZLpKw+m3FiHtAp2CkanSyJre+SInEvEr5kIxjGvCK/8MFX8SFRjQuhjtvpIvYYZJB4AGCxNQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
"node_modules/turbo-darwin-arm64": {
"version": "2.5.8",
"cpu": [
@@ -25295,6 +26747,62 @@
"darwin"
]
},
+ "node_modules/turbo-linux-64": {
+ "version": "2.5.8",
+ "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.5.8.tgz",
+ "integrity": "sha512-hMyvc7w7yadBlZBGl/bnR6O+dJTx3XkTeyTTH4zEjERO6ChEs0SrN8jTFj1lueNXKIHh1SnALmy6VctKMGnWfw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/turbo-linux-arm64": {
+ "version": "2.5.8",
+ "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.5.8.tgz",
+ "integrity": "sha512-LQELGa7bAqV2f+3rTMRPnj5G/OHAe2U+0N9BwsZvfMvHSUbsQ3bBMWdSQaYNicok7wOZcHjz2TkESn1hYK6xIQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/turbo-windows-64": {
+ "version": "2.5.8",
+ "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.5.8.tgz",
+ "integrity": "sha512-3YdcaW34TrN1AWwqgYL9gUqmZsMT4T7g8Y5Azz+uwwEJW+4sgcJkIi9pYFyU4ZBSjBvkfuPZkGgfStir5BBDJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/turbo-windows-arm64": {
+ "version": "2.5.8",
+ "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.5.8.tgz",
+ "integrity": "sha512-eFC5XzLmgXJfnAK3UMTmVECCwuBcORrWdewoiXBnUm934DY6QN8YowC/srhNnROMpaKaqNeRpoB5FxCww3eteQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/tweetnacl": {
"version": "0.14.5",
"license": "Unlicense"
@@ -25595,6 +27103,15 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/unpdf": {
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/unpdf/-/unpdf-0.12.2.tgz",
+ "integrity": "sha512-3eyDFfayk+Sf5+inJ4OyhecR2BtRFEeZqUfGPdq2O8aBLau9MYL9lAP+GEcSAaVd2JWqde8Dnz38z0x7KRglaA==",
+ "license": "MIT",
+ "optionalDependencies": {
+ "canvas": "^2.11.2"
+ }
+ },
"node_modules/unpipe": {
"version": "1.0.0",
"license": "MIT",
@@ -26731,6 +28248,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/wide-align": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
+ "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
+ "license": "ISC",
+ "optional": true,
+ "dependencies": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
+ }
+ },
"node_modules/widest-line": {
"version": "3.1.0",
"license": "MIT",
@@ -27069,57 +28596,261 @@
"node": ">=10"
}
},
- "node_modules/yargs-parser": {
- "version": "20.2.9",
- "license": "ISC",
- "engines": {
- "node": ">=10"
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zksync-ethers": {
+ "version": "5.11.0",
+ "license": "MIT",
+ "dependencies": {
+ "ethers": "~5.7.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "ethers": "~5.7.0"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/abi": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/hash": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/abstract-provider": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/networks": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "@ethersproject/web": "^5.7.0"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/abstract-signer": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/address": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/rlp": "^5.7.0"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/base64": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/basex": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0"
}
},
- "node_modules/yargs-unparser": {
- "version": "2.0.0",
+ "node_modules/zksync-ethers/node_modules/@ethersproject/bignumber": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "camelcase": "^6.0.0",
- "decamelize": "^4.0.0",
- "flat": "^5.0.2",
- "is-plain-obj": "^2.1.0"
- },
- "engines": {
- "node": ">=10"
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "bn.js": "^5.2.1"
}
},
- "node_modules/yn": {
- "version": "3.1.1",
+ "node_modules/zksync-ethers/node_modules/@ethersproject/bytes": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
"license": "MIT",
- "engines": {
- "node": ">=6"
+ "dependencies": {
+ "@ethersproject/logger": "^5.7.0"
}
},
- "node_modules/yocto-queue": {
- "version": "0.1.0",
+ "node_modules/zksync-ethers/node_modules/@ethersproject/constants": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
"license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "dependencies": {
+ "@ethersproject/bignumber": "^5.7.0"
}
},
- "node_modules/zksync-ethers": {
- "version": "5.11.0",
+ "node_modules/zksync-ethers/node_modules/@ethersproject/contracts": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "ethers": "~5.7.0"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "peerDependencies": {
- "ethers": "~5.7.0"
+ "@ethersproject/abi": "^5.7.0",
+ "@ethersproject/abstract-provider": "^5.7.0",
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/abi": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/hash": {
"version": "5.7.0",
"funding": [
{
@@ -27133,18 +28864,18 @@
],
"license": "MIT",
"dependencies": {
+ "@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/address": "^5.7.0",
+ "@ethersproject/base64": "^5.7.0",
"@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
- "@ethersproject/constants": "^5.7.0",
- "@ethersproject/hash": "^5.7.0",
"@ethersproject/keccak256": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
"@ethersproject/properties": "^5.7.0",
"@ethersproject/strings": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/abstract-provider": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/hdnode": {
"version": "5.7.0",
"funding": [
{
@@ -27158,16 +28889,21 @@
],
"license": "MIT",
"dependencies": {
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/basex": "^5.7.0",
"@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
- "@ethersproject/networks": "^5.7.0",
+ "@ethersproject/pbkdf2": "^5.7.0",
"@ethersproject/properties": "^5.7.0",
+ "@ethersproject/sha2": "^5.7.0",
+ "@ethersproject/signing-key": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0",
"@ethersproject/transactions": "^5.7.0",
- "@ethersproject/web": "^5.7.0"
+ "@ethersproject/wordlists": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/abstract-signer": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/json-wallets": {
"version": "5.7.0",
"funding": [
{
@@ -27181,14 +28917,22 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/abstract-provider": "^5.7.0",
- "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/hdnode": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0"
+ "@ethersproject/pbkdf2": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/random": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "aes-js": "3.0.0",
+ "scrypt-js": "3.0.1"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/address": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/keccak256": {
"version": "5.7.0",
"funding": [
{
@@ -27202,14 +28946,11 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
- "@ethersproject/keccak256": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/rlp": "^5.7.0"
+ "js-sha3": "0.8.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/base64": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/logger": {
"version": "5.7.0",
"funding": [
{
@@ -27221,12 +28962,26 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
+ "license": "MIT"
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/networks": {
+ "version": "5.7.1",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "@ethersproject/bytes": "^5.7.0"
+ "@ethersproject/logger": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/basex": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/pbkdf2": {
"version": "5.7.0",
"funding": [
{
@@ -27241,10 +28996,10 @@
"license": "MIT",
"dependencies": {
"@ethersproject/bytes": "^5.7.0",
- "@ethersproject/properties": "^5.7.0"
+ "@ethersproject/sha2": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/bignumber": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/properties": {
"version": "5.7.0",
"funding": [
{
@@ -27258,12 +29013,46 @@
],
"license": "MIT",
"dependencies": {
+ "@ethersproject/logger": "^5.7.0"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/providers": {
+ "version": "5.7.2",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.7.0",
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/base64": "^5.7.0",
+ "@ethersproject/basex": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/hash": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
- "bn.js": "^5.2.1"
+ "@ethersproject/networks": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/random": "^5.7.0",
+ "@ethersproject/rlp": "^5.7.0",
+ "@ethersproject/sha2": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "@ethersproject/web": "^5.7.0",
+ "bech32": "1.1.4",
+ "ws": "7.4.6"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/bytes": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/random": {
"version": "5.7.0",
"funding": [
{
@@ -27277,10 +29066,11 @@
],
"license": "MIT",
"dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
"@ethersproject/logger": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/constants": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/rlp": {
"version": "5.7.0",
"funding": [
{
@@ -27294,10 +29084,30 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/bignumber": "^5.7.0"
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/contracts": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/sha2": {
+ "version": "5.7.0",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.buymeacoffee.com/ricmoo"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "hash.js": "1.1.7"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/@ethersproject/signing-key": {
"version": "5.7.0",
"funding": [
{
@@ -27311,19 +29121,15 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/abi": "^5.7.0",
- "@ethersproject/abstract-provider": "^5.7.0",
- "@ethersproject/abstract-signer": "^5.7.0",
- "@ethersproject/address": "^5.7.0",
- "@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
- "@ethersproject/constants": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
"@ethersproject/properties": "^5.7.0",
- "@ethersproject/transactions": "^5.7.0"
+ "bn.js": "^5.2.1",
+ "elliptic": "6.5.4",
+ "hash.js": "1.1.7"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/hash": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/solidity": {
"version": "5.7.0",
"funding": [
{
@@ -27337,18 +29143,15 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/abstract-signer": "^5.7.0",
- "@ethersproject/address": "^5.7.0",
- "@ethersproject/base64": "^5.7.0",
"@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
"@ethersproject/keccak256": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/sha2": "^5.7.0",
"@ethersproject/strings": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/hdnode": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/strings": {
"version": "5.7.0",
"funding": [
{
@@ -27362,21 +29165,12 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/abstract-signer": "^5.7.0",
- "@ethersproject/basex": "^5.7.0",
- "@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/pbkdf2": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/sha2": "^5.7.0",
- "@ethersproject/signing-key": "^5.7.0",
- "@ethersproject/strings": "^5.7.0",
- "@ethersproject/transactions": "^5.7.0",
- "@ethersproject/wordlists": "^5.7.0"
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/json-wallets": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/transactions": {
"version": "5.7.0",
"funding": [
{
@@ -27390,22 +29184,18 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/address": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
"@ethersproject/bytes": "^5.7.0",
- "@ethersproject/hdnode": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
"@ethersproject/keccak256": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
- "@ethersproject/pbkdf2": "^5.7.0",
"@ethersproject/properties": "^5.7.0",
- "@ethersproject/random": "^5.7.0",
- "@ethersproject/strings": "^5.7.0",
- "@ethersproject/transactions": "^5.7.0",
- "aes-js": "3.0.0",
- "scrypt-js": "3.0.1"
+ "@ethersproject/rlp": "^5.7.0",
+ "@ethersproject/signing-key": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/keccak256": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/units": {
"version": "5.7.0",
"funding": [
{
@@ -27419,11 +29209,12 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "js-sha3": "0.8.0"
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/constants": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/logger": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/wallet": {
"version": "5.7.0",
"funding": [
{
@@ -27435,9 +29226,26 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
- "license": "MIT"
+ "license": "MIT",
+ "dependencies": {
+ "@ethersproject/abstract-provider": "^5.7.0",
+ "@ethersproject/abstract-signer": "^5.7.0",
+ "@ethersproject/address": "^5.7.0",
+ "@ethersproject/bignumber": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/hash": "^5.7.0",
+ "@ethersproject/hdnode": "^5.7.0",
+ "@ethersproject/json-wallets": "^5.7.0",
+ "@ethersproject/keccak256": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/random": "^5.7.0",
+ "@ethersproject/signing-key": "^5.7.0",
+ "@ethersproject/transactions": "^5.7.0",
+ "@ethersproject/wordlists": "^5.7.0"
+ }
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/networks": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/web": {
"version": "5.7.1",
"funding": [
{
@@ -27451,10 +29259,14 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/logger": "^5.7.0"
+ "@ethersproject/base64": "^5.7.0",
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/pbkdf2": {
+ "node_modules/zksync-ethers/node_modules/@ethersproject/wordlists": {
"version": "5.7.0",
"funding": [
{
@@ -27469,11 +29281,35 @@
"license": "MIT",
"dependencies": {
"@ethersproject/bytes": "^5.7.0",
- "@ethersproject/sha2": "^5.7.0"
+ "@ethersproject/hash": "^5.7.0",
+ "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/strings": "^5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/properties": {
- "version": "5.7.0",
+ "node_modules/zksync-ethers/node_modules/aes-js": {
+ "version": "3.0.0",
+ "license": "MIT"
+ },
+ "node_modules/zksync-ethers/node_modules/elliptic": {
+ "version": "6.5.4",
+ "license": "MIT",
+ "dependencies": {
+ "bn.js": "^4.11.9",
+ "brorand": "^1.1.0",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.1",
+ "inherits": "^2.0.4",
+ "minimalistic-assert": "^1.0.1",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "node_modules/zksync-ethers/node_modules/elliptic/node_modules/bn.js": {
+ "version": "4.12.2",
+ "license": "MIT"
+ },
+ "node_modules/zksync-ethers/node_modules/ethers": {
+ "version": "5.7.2",
"funding": [
{
"type": "individual",
@@ -27486,515 +29322,593 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/logger": "^5.7.0"
+ "@ethersproject/abi": "5.7.0",
+ "@ethersproject/abstract-provider": "5.7.0",
+ "@ethersproject/abstract-signer": "5.7.0",
+ "@ethersproject/address": "5.7.0",
+ "@ethersproject/base64": "5.7.0",
+ "@ethersproject/basex": "5.7.0",
+ "@ethersproject/bignumber": "5.7.0",
+ "@ethersproject/bytes": "5.7.0",
+ "@ethersproject/constants": "5.7.0",
+ "@ethersproject/contracts": "5.7.0",
+ "@ethersproject/hash": "5.7.0",
+ "@ethersproject/hdnode": "5.7.0",
+ "@ethersproject/json-wallets": "5.7.0",
+ "@ethersproject/keccak256": "5.7.0",
+ "@ethersproject/logger": "5.7.0",
+ "@ethersproject/networks": "5.7.1",
+ "@ethersproject/pbkdf2": "5.7.0",
+ "@ethersproject/properties": "5.7.0",
+ "@ethersproject/providers": "5.7.2",
+ "@ethersproject/random": "5.7.0",
+ "@ethersproject/rlp": "5.7.0",
+ "@ethersproject/sha2": "5.7.0",
+ "@ethersproject/signing-key": "5.7.0",
+ "@ethersproject/solidity": "5.7.0",
+ "@ethersproject/strings": "5.7.0",
+ "@ethersproject/transactions": "5.7.0",
+ "@ethersproject/units": "5.7.0",
+ "@ethersproject/wallet": "5.7.0",
+ "@ethersproject/web": "5.7.1",
+ "@ethersproject/wordlists": "5.7.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/providers": {
- "version": "5.7.2",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
+ "node_modules/zksync-ethers/node_modules/ws": {
+ "version": "7.4.6",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
},
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
+ "utf-8-validate": {
+ "optional": true
}
- ],
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.25.76",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-to-json-schema": {
+ "version": "3.24.6",
+ "license": "ISC",
+ "peerDependencies": {
+ "zod": "^3.24.1"
+ }
+ },
+ "packages/eslint-config": {
+ "name": "@dkg/eslint-config",
+ "version": "0.0.2",
+ "devDependencies": {
+ "@eslint/js": "^9.29.0",
+ "@next/eslint-plugin-next": "^15.3.0",
+ "eslint": "^9.29.0",
+ "eslint-config-expo": "~9.2.0",
+ "eslint-config-prettier": "^10.1.1",
+ "eslint-plugin-only-warn": "^1.1.0",
+ "eslint-plugin-react": "^7.37.5",
+ "eslint-plugin-react-hooks": "^5.2.0",
+ "eslint-plugin-turbo": "^2.5.0",
+ "globals": "^16.2.0",
+ "typescript-eslint": "^8.33.0"
+ }
+ },
+ "packages/eslint-config/node_modules/globals": {
+ "version": "16.4.0",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "packages/expo-forcegraph": {
+ "name": "@dkg/expo-forcegraph",
+ "version": "0.0.0",
+ "dependencies": {
+ "react-force-graph": "^1.48.0"
+ },
+ "devDependencies": {
+ "@dkg/eslint-config": "*",
+ "tsup": "^8.5.0"
+ },
+ "peerDependencies": {
+ "expo": "^53.0.0"
+ }
+ },
+ "packages/internal": {
+ "version": "0.0.2",
+ "devDependencies": {
+ "@dkg/typescript-config": "*",
+ "@turbo/gen": "^2.5.0"
+ }
+ },
+ "packages/plugin-auth": {
+ "name": "@dkg/plugin-auth",
+ "version": "0.0.2",
+ "dependencies": {
+ "@dkg/plugins": "^0.0.2",
+ "jsonwebtoken": "^9.0.2",
+ "passport": "^0.7.0",
+ "passport-jwt": "^4.0.1"
+ },
+ "devDependencies": {
+ "@dkg/eslint-config": "*",
+ "@dkg/typescript-config": "*",
+ "@types/jsonwebtoken": "^9.0.7",
+ "@types/passport": "^1.0.17",
+ "@types/passport-jwt": "^4.0.1",
+ "tsup": "^8.5.0"
+ }
+ },
+ "packages/plugin-dkg-essentials": {
+ "name": "@dkg/plugin-dkg-essentials",
+ "version": "0.0.3",
+ "dependencies": {
+ "@dkg/plugin-swagger": "^0.0.2",
+ "@dkg/plugins": "^0.0.2",
+ "@mistralai/mistralai": "^1.3.0",
+ "busboy": "^1.6.0",
+ "sparqljs": "^3.7.3",
+ "undici": "^6.19.0",
+ "unpdf": "^0.12.1"
+ },
+ "devDependencies": {
+ "@dkg/eslint-config": "*",
+ "@dkg/typescript-config": "*",
+ "@types/busboy": "^1.5.4",
+ "@types/sparqljs": "^3.1.12",
+ "pdf-lib": "^1.17.1",
+ "tsup": "^8.5.0"
+ }
+ },
+ "packages/plugin-dkg-essentials/node_modules/undici": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
+ "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
"license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-provider": "^5.7.0",
- "@ethersproject/abstract-signer": "^5.7.0",
- "@ethersproject/address": "^5.7.0",
- "@ethersproject/base64": "^5.7.0",
- "@ethersproject/basex": "^5.7.0",
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/constants": "^5.7.0",
- "@ethersproject/hash": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/networks": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/random": "^5.7.0",
- "@ethersproject/rlp": "^5.7.0",
- "@ethersproject/sha2": "^5.7.0",
- "@ethersproject/strings": "^5.7.0",
- "@ethersproject/transactions": "^5.7.0",
- "@ethersproject/web": "^5.7.0",
- "bech32": "1.1.4",
- "ws": "7.4.6"
+ "engines": {
+ "node": ">=18.17"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/random": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
+ "packages/plugin-dkg-publisher": {
+ "name": "@dkg/plugin-dkg-publisher",
+ "version": "1.0.0",
"license": "MIT",
"dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0"
+ "@bull-board/api": "^5.9.1",
+ "@bull-board/express": "^5.9.1",
+ "@dkg/plugin-swagger": "^0.0.2",
+ "@dkg/plugins": "^0.0.2",
+ "bull-board": "^2.1.3",
+ "bullmq": "^4.15.0",
+ "crypto-js": "^4.2.0",
+ "dkg.js": "^8.2.2",
+ "dotenv": "^16.0.0",
+ "drizzle-orm": "^0.44.7",
+ "ethers": "^6.13.0",
+ "express": "^5.1.0",
+ "ioredis": "^5.3.2",
+ "mysql2": "^3.6.5",
+ "uuid": "^9.0.1",
+ "winston": "^3.17.0",
+ "winston-daily-rotate-file": "^5.0.0"
+ },
+ "devDependencies": {
+ "@dkg/eslint-config": "*",
+ "@dkg/typescript-config": "*",
+ "@types/crypto-js": "^4.2.1",
+ "@types/express": "^5.0.3",
+ "@types/mocha": "^10.0.6",
+ "@types/supertest": "^6.0.2",
+ "@types/uuid": "^9.0.7",
+ "chai": "^6.2.0",
+ "deep-eql": "^4.1.3",
+ "drizzle-kit": "^0.20.0",
+ "eslint": "^9.29.0",
+ "mocha": "^10.2.0",
+ "supertest": "^6.3.3",
+ "ts-node": "^10.9.1",
+ "tsup": "^8.5.0"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/rlp": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/aix-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
+ "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
+ "cpu": [
+ "ppc64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0"
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/sha2": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/android-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
+ "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
+ "cpu": [
+ "arm"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "hash.js": "1.1.7"
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/signing-key": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/android-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
+ "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "bn.js": "^5.2.1",
- "elliptic": "6.5.4",
- "hash.js": "1.1.7"
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/solidity": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/android-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
+ "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/keccak256": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/sha2": "^5.7.0",
- "@ethersproject/strings": "^5.7.0"
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/strings": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.19.12",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/constants": "^5.7.0",
- "@ethersproject/logger": "^5.7.0"
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/transactions": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/darwin-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
+ "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/address": "^5.7.0",
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/constants": "^5.7.0",
- "@ethersproject/keccak256": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/rlp": "^5.7.0",
- "@ethersproject/signing-key": "^5.7.0"
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
}
- },
- "node_modules/zksync-ethers/node_modules/@ethersproject/units": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ },
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
+ "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/constants": "^5.7.0",
- "@ethersproject/logger": "^5.7.0"
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/wallet": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
+ "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
+ "cpu": [
+ "x64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-provider": "^5.7.0",
- "@ethersproject/abstract-signer": "^5.7.0",
- "@ethersproject/address": "^5.7.0",
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/hash": "^5.7.0",
- "@ethersproject/hdnode": "^5.7.0",
- "@ethersproject/json-wallets": "^5.7.0",
- "@ethersproject/keccak256": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/random": "^5.7.0",
- "@ethersproject/signing-key": "^5.7.0",
- "@ethersproject/transactions": "^5.7.0",
- "@ethersproject/wordlists": "^5.7.0"
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/web": {
- "version": "5.7.1",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
+ "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
+ "cpu": [
+ "arm"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/base64": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/strings": "^5.7.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/@ethersproject/wordlists": {
- "version": "5.7.0",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
+ "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
+ "cpu": [
+ "arm64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/hash": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/strings": "^5.7.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/aes-js": {
- "version": "3.0.0",
- "license": "MIT"
- },
- "node_modules/zksync-ethers/node_modules/elliptic": {
- "version": "6.5.4",
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
+ "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "bn.js": "^4.11.9",
- "brorand": "^1.1.0",
- "hash.js": "^1.0.0",
- "hmac-drbg": "^1.0.1",
- "inherits": "^2.0.4",
- "minimalistic-assert": "^1.0.1",
- "minimalistic-crypto-utils": "^1.0.1"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/elliptic/node_modules/bn.js": {
- "version": "4.12.2",
- "license": "MIT"
- },
- "node_modules/zksync-ethers/node_modules/ethers": {
- "version": "5.7.2",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-loong64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
+ "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
+ "cpu": [
+ "loong64"
],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@ethersproject/abi": "5.7.0",
- "@ethersproject/abstract-provider": "5.7.0",
- "@ethersproject/abstract-signer": "5.7.0",
- "@ethersproject/address": "5.7.0",
- "@ethersproject/base64": "5.7.0",
- "@ethersproject/basex": "5.7.0",
- "@ethersproject/bignumber": "5.7.0",
- "@ethersproject/bytes": "5.7.0",
- "@ethersproject/constants": "5.7.0",
- "@ethersproject/contracts": "5.7.0",
- "@ethersproject/hash": "5.7.0",
- "@ethersproject/hdnode": "5.7.0",
- "@ethersproject/json-wallets": "5.7.0",
- "@ethersproject/keccak256": "5.7.0",
- "@ethersproject/logger": "5.7.0",
- "@ethersproject/networks": "5.7.1",
- "@ethersproject/pbkdf2": "5.7.0",
- "@ethersproject/properties": "5.7.0",
- "@ethersproject/providers": "5.7.2",
- "@ethersproject/random": "5.7.0",
- "@ethersproject/rlp": "5.7.0",
- "@ethersproject/sha2": "5.7.0",
- "@ethersproject/signing-key": "5.7.0",
- "@ethersproject/solidity": "5.7.0",
- "@ethersproject/strings": "5.7.0",
- "@ethersproject/transactions": "5.7.0",
- "@ethersproject/units": "5.7.0",
- "@ethersproject/wallet": "5.7.0",
- "@ethersproject/web": "5.7.1",
- "@ethersproject/wordlists": "5.7.0"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zksync-ethers/node_modules/ws": {
- "version": "7.4.6",
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
+ "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=8.3.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
+ "node": ">=12"
}
},
- "node_modules/zod": {
- "version": "3.25.76",
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
+ "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
"license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/zod-to-json-schema": {
- "version": "3.24.6",
- "license": "ISC",
- "peerDependencies": {
- "zod": "^3.24.1"
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
+ "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "packages/eslint-config": {
- "name": "@dkg/eslint-config",
- "version": "0.0.2",
- "devDependencies": {
- "@eslint/js": "^9.29.0",
- "@next/eslint-plugin-next": "^15.3.0",
- "eslint": "^9.29.0",
- "eslint-config-expo": "~9.2.0",
- "eslint-config-prettier": "^10.1.1",
- "eslint-plugin-only-warn": "^1.1.0",
- "eslint-plugin-react": "^7.37.5",
- "eslint-plugin-react-hooks": "^5.2.0",
- "eslint-plugin-turbo": "^2.5.0",
- "globals": "^16.2.0",
- "typescript-eslint": "^8.33.0"
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-s390x": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
+ "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "packages/eslint-config/node_modules/globals": {
- "version": "16.4.0",
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/linux-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
+ "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=12"
}
},
- "packages/expo-forcegraph": {
- "name": "@dkg/expo-forcegraph",
- "version": "0.0.0",
- "dependencies": {
- "react-force-graph": "^1.48.0"
- },
- "devDependencies": {
- "@dkg/eslint-config": "*",
- "tsup": "^8.5.0"
- },
- "peerDependencies": {
- "expo": "^53.0.0"
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "packages/internal": {
- "version": "0.0.2",
- "devDependencies": {
- "@dkg/typescript-config": "*",
- "@turbo/gen": "^2.5.0"
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "packages/plugin-auth": {
- "name": "@dkg/plugin-auth",
- "version": "0.0.2",
- "dependencies": {
- "@dkg/plugins": "^0.0.2",
- "jsonwebtoken": "^9.0.2",
- "passport": "^0.7.0",
- "passport-jwt": "^4.0.1"
- },
- "devDependencies": {
- "@dkg/eslint-config": "*",
- "@dkg/typescript-config": "*",
- "@types/jsonwebtoken": "^9.0.7",
- "@types/passport": "^1.0.17",
- "@types/passport-jwt": "^4.0.1",
- "tsup": "^8.5.0"
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/sunos-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
+ "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "packages/plugin-dkg-essentials": {
- "name": "@dkg/plugin-dkg-essentials",
- "version": "0.0.3",
- "dependencies": {
- "@dkg/plugin-swagger": "^0.0.2",
- "@dkg/plugins": "^0.0.2",
- "busboy": "^1.6.0",
- "sparqljs": "^3.7.3"
- },
- "devDependencies": {
- "@dkg/eslint-config": "*",
- "@dkg/typescript-config": "*",
- "@types/busboy": "^1.5.4",
- "@types/sparqljs": "^3.1.12",
- "tsup": "^8.5.0"
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/win32-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
+ "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "packages/plugin-dkg-publisher": {
- "name": "@dkg/plugin-dkg-publisher",
- "version": "1.0.0",
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/win32-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
+ "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@bull-board/api": "^5.9.1",
- "@bull-board/express": "^5.9.1",
- "@dkg/plugin-swagger": "^0.0.2",
- "@dkg/plugins": "^0.0.2",
- "bull-board": "^2.1.3",
- "bullmq": "^4.15.0",
- "crypto-js": "^4.2.0",
- "dkg.js": "^8.2.2",
- "dotenv": "^16.0.0",
- "drizzle-orm": "^0.44.7",
- "ethers": "^6.13.0",
- "express": "^5.1.0",
- "ioredis": "^5.3.2",
- "mysql2": "^3.6.5",
- "uuid": "^9.0.1",
- "winston": "^3.17.0",
- "winston-daily-rotate-file": "^5.0.0"
- },
- "devDependencies": {
- "@dkg/eslint-config": "*",
- "@dkg/typescript-config": "*",
- "@types/crypto-js": "^4.2.1",
- "@types/express": "^5.0.3",
- "@types/mocha": "^10.0.6",
- "@types/supertest": "^6.0.2",
- "@types/uuid": "^9.0.7",
- "chai": "^6.2.0",
- "deep-eql": "^4.1.3",
- "drizzle-kit": "^0.20.0",
- "eslint": "^9.29.0",
- "mocha": "^10.2.0",
- "supertest": "^6.3.3",
- "ts-node": "^10.9.1",
- "tsup": "^8.5.0"
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
}
},
- "packages/plugin-dkg-publisher/node_modules/@esbuild/darwin-arm64": {
+ "packages/plugin-dkg-publisher/node_modules/@esbuild/win32-x64": {
"version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
+ "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
"cpu": [
- "arm64"
+ "x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
- "darwin"
+ "win32"
],
"engines": {
"node": ">=12"
@@ -28091,102 +30005,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "packages/plugin-dkg-publisher/node_modules/drizzle-orm": {
- "version": "0.29.5",
- "license": "Apache-2.0",
- "peerDependencies": {
- "@aws-sdk/client-rds-data": ">=3",
- "@cloudflare/workers-types": ">=3",
- "@libsql/client": "*",
- "@neondatabase/serverless": ">=0.1",
- "@opentelemetry/api": "^1.4.1",
- "@planetscale/database": ">=1",
- "@types/better-sqlite3": "*",
- "@types/pg": "*",
- "@types/react": ">=18",
- "@types/sql.js": "*",
- "@vercel/postgres": "*",
- "better-sqlite3": ">=7",
- "bun-types": "*",
- "expo-sqlite": ">=13.2.0",
- "knex": "*",
- "kysely": "*",
- "mysql2": ">=2",
- "pg": ">=8",
- "postgres": ">=3",
- "react": ">=18",
- "sql.js": ">=1",
- "sqlite3": ">=5"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/client-rds-data": {
- "optional": true
- },
- "@cloudflare/workers-types": {
- "optional": true
- },
- "@libsql/client": {
- "optional": true
- },
- "@neondatabase/serverless": {
- "optional": true
- },
- "@opentelemetry/api": {
- "optional": true
- },
- "@planetscale/database": {
- "optional": true
- },
- "@types/better-sqlite3": {
- "optional": true
- },
- "@types/pg": {
- "optional": true
- },
- "@types/react": {
- "optional": true
- },
- "@types/sql.js": {
- "optional": true
- },
- "@vercel/postgres": {
- "optional": true
- },
- "better-sqlite3": {
- "optional": true
- },
- "bun-types": {
- "optional": true
- },
- "expo-sqlite": {
- "optional": true
- },
- "knex": {
- "optional": true
- },
- "kysely": {
- "optional": true
- },
- "mysql2": {
- "optional": true
- },
- "pg": {
- "optional": true
- },
- "postgres": {
- "optional": true
- },
- "react": {
- "optional": true
- },
- "sql.js": {
- "optional": true
- },
- "sqlite3": {
- "optional": true
- }
- }
- },
"packages/plugin-dkg-publisher/node_modules/env-paths": {
"version": "3.0.0",
"dev": true,
diff --git a/packages/plugin-dkg-essentials/DOCUMENT_TO_MARKDOWN.md b/packages/plugin-dkg-essentials/DOCUMENT_TO_MARKDOWN.md
new file mode 100644
index 00000000..006e296a
--- /dev/null
+++ b/packages/plugin-dkg-essentials/DOCUMENT_TO_MARKDOWN.md
@@ -0,0 +1,273 @@
+# Document to Markdown Tool
+
+Convert PDF, DOCX, and PPTX documents to Markdown using configurable conversion providers.
+
+## Overview
+
+The `document-to-markdown` MCP tool extracts text and images from documents and converts them to well-structured Markdown. Extracted images are stored as separate blobs alongside the markdown output.
+
+The tool supports a **provider abstraction** pattern, allowing you to switch between different conversion backends.
+
+## Available Providers
+
+| Provider | Name | Formats | Images | API Key Required |
+|----------|------|---------|--------|------------------|
+| **unpdf** (default) | `unpdf` | PDF only | No | No |
+| **Mistral OCR** | `mistral` | PDF, DOCX, PPTX | Yes | Yes (`MISTRAL_API_KEY`) |
+
+### unpdf (Default)
+
+Zero-config text extraction powered by Mozilla's `pdf.js`. Good for simple PDF text extraction without external API dependencies.
+
+- **Formats**: PDF only
+- **Images**: Not supported (returns empty array)
+- **Requirements**: None - works out of the box
+
+### Mistral OCR
+
+Full-featured OCR with multi-format support and image extraction. Handles scanned PDFs, complex layouts, and non-PDF formats.
+
+- **Formats**: PDF, DOCX, PPTX
+- **Images**: Full extraction support
+- **Requirements**: `MISTRAL_API_KEY` ([get one here](https://console.mistral.ai/))
+- **Timeout**: 120 seconds per request
+
+## Environment Variables
+
+| Variable | Required | Description |
+|----------|----------|-------------|
+| `DOCUMENT_CONVERSION_PROVIDER` | No | Provider to use (default: `"unpdf"`) |
+| `MISTRAL_API_KEY` | Only for Mistral | Your Mistral API key |
+
+## Supported Formats
+
+| Extension | MIME Type | unpdf | Mistral |
+|-----------|-----------|:-----:|:-------:|
+| `.pdf` | `application/pdf` | Yes | Yes |
+| `.docx` | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` | No | Yes |
+| `.pptx` | `application/vnd.openxmlformats-officedocument.presentationml.presentation` | No | Yes |
+
+## Usage
+
+### Input Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `blobId` | string | One of `blobId` or `fileBase64` | ID of a previously uploaded document blob |
+| `fileBase64` | string | One of `blobId` or `fileBase64` | Base64-encoded document content |
+| `filename` | string | **Yes** | Original filename with extension (e.g., `report.pdf`) |
+| `options` | object | No | Conversion options (see below) |
+
+### Options
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `pageStart` | integer | 1 | First page to process (1-indexed, inclusive) |
+| `pageEnd` | integer | Last page | Last page to process (1-indexed, inclusive) |
+| `includeImages` | boolean | true | Whether to extract and store images |
+
+Page range values are automatically clamped to valid bounds - out-of-range values are silently adjusted.
+
+### Example: Using blob ID
+
+```json
+{
+ "name": "document-to-markdown",
+ "arguments": {
+ "blobId": "abc123-def456",
+ "filename": "quarterly-report.pdf"
+ }
+}
+```
+
+### Example: Using base64 content
+
+```json
+{
+ "name": "document-to-markdown",
+ "arguments": {
+ "fileBase64": "JVBERi0xLjQKJ...",
+ "filename": "presentation.pptx",
+ "options": {
+ "pageStart": 1,
+ "pageEnd": 10,
+ "includeImages": true
+ }
+ }
+}
+```
+
+### REST Endpoint
+
+`POST /document-to-markdown` accepts `multipart/form-data` with exactly one `file` field. The JSON response includes both `pageCount` (total pages) and `processedPageCount` (pages in markdown output).
+
+## Output Structure
+
+### Response Format
+
+The tool returns a text response containing:
+
+1. **Status message** - Success or failure indication
+2. **Output folder ID** - UUID of the folder containing all outputs
+3. **Markdown blob ID** - ID of the generated markdown file
+4. **Total page count** - Number of pages in the source document
+5. **Processed page count** - Number of pages included in converted markdown output
+6. **Image count** - Number of images extracted (if any)
+7. **Markdown content** - The full converted markdown
+
+### File Organization
+
+Outputs are stored in a nested folder structure:
+
+```text
+document-conversions/
+ {uuid}/
+ {original-name}.md # Converted markdown
+ img-0.jpeg # Extracted image 1
+ img-1.jpeg # Extracted image 2
+ ...
+```
+
+### Image References
+
+Images in the markdown reference their blob URLs:
+
+```markdown
+
+```
+
+### Storage Location
+
+All outputs are stored in blob storage under the `document-conversions/` prefix:
+
+| Backend | Typical Location |
+|---------|------------------|
+| Filesystem (`createFsBlobStorage`) | `./data/blobs/document-conversions/{uuid}/` |
+| In-memory (testing only) | RAM, not persisted |
+| Custom implementation | As configured |
+
+## Error Messages
+
+| Error | Cause | Solution |
+|-------|-------|----------|
+| `MISTRAL_API_KEY environment variable is not set` | Missing API key (Mistral provider) | Set the `MISTRAL_API_KEY` environment variable |
+| `Either 'blobId' or 'fileBase64' must be provided` | No input document | Provide either `blobId` or `fileBase64` |
+| `Provide either 'blobId' or 'fileBase64', not both` | Both inputs provided | Use only one input method |
+| `Unsupported file type: '.xyz'` | Invalid file extension | Use a supported format for your provider |
+| `File size (X MB) exceeds maximum of 50MB` | File too large | Use a smaller file or split the document |
+| `Document blob not found: {id}` | Invalid blob ID | Verify the blob ID exists |
+| `Mistral OCR request timed out after 120 seconds` | API timeout (Mistral) | The document may be too large or complex; try a smaller file |
+| `Document conversion failed: {reason}` | Processing error | Check the error details and retry |
+
+## Limitations
+
+- **Maximum file size**: 50 MB
+- **Supported formats**: PDF (all providers), DOCX/PPTX (Mistral only)
+- **API timeout**: 2 minutes (Mistral provider)
+- **Image extraction**: Mistral provider only
+
+## Provider Configuration
+
+### Selecting a Provider
+
+**Via environment variable:**
+
+```bash
+# Use unpdf (default) - no API key needed
+export DOCUMENT_CONVERSION_PROVIDER=unpdf
+
+# Use Mistral OCR
+export DOCUMENT_CONVERSION_PROVIDER=mistral
+export MISTRAL_API_KEY=your-api-key
+```
+
+**Via programmatic configuration:**
+
+```typescript
+import { createDocumentToMarkdownPlugin, createProvider } from "@dkg/plugin-dkg-essentials";
+
+// Option 1: Use a named provider
+const plugin = createDocumentToMarkdownPlugin({
+ providerName: "mistral",
+});
+
+// Option 2: Provide a custom provider instance
+const customProvider = createProvider("mistral", { apiKey: "your-key" });
+const plugin = createDocumentToMarkdownPlugin({
+ provider: customProvider,
+});
+```
+
+**Provider resolution order** (first match wins):
+1. Custom provider instance via `config.provider`
+2. Provider name from `config.providerName`
+3. `DOCUMENT_CONVERSION_PROVIDER` environment variable
+4. Default: `"unpdf"`
+
+### Implementing a Custom Provider
+
+Implement the `DocumentConversionProvider` interface:
+
+```typescript
+import type {
+ DocumentConversionProvider,
+ DocumentConversionOutput,
+ DocumentConversionOptions
+} from "@dkg/plugin-dkg-essentials";
+
+class MyCustomProvider implements DocumentConversionProvider {
+ readonly name = "my-provider";
+
+ async convert(
+ buffer: Buffer,
+ filename: string,
+ options?: DocumentConversionOptions,
+ ): Promise {
+ return {
+ markdown: "# Converted content",
+ images: [],
+ pageCount: 1,
+ processedPageCount: 1,
+ };
+ }
+}
+
+const plugin = createDocumentToMarkdownPlugin({
+ provider: new MyCustomProvider(),
+});
+```
+
+### Exported Types and Utilities
+
+```typescript
+import {
+ // Types
+ DocumentConversionProvider,
+ DocumentConversionOptions,
+ DocumentConversionOutput,
+ ConversionResult,
+ ExtractedImage,
+ DocumentConversionConfig,
+
+ // Provider utilities
+ createProvider,
+ getDefaultProvider,
+ getAvailableProviders,
+ isProviderAvailable,
+
+ // Provider-specific
+ MistralProvider,
+ createMistralProvider,
+} from "@dkg/plugin-dkg-essentials";
+```
+
+## Security
+
+- API keys are validated at runtime and never logged
+- Temporary files are cleaned up after processing
+- Blob storage is used for all file operations
+
+## Related Tools
+
+- `upload` - Upload documents to blob storage before conversion
+- `dkg-create` - Create Knowledge Assets from converted content
diff --git a/packages/plugin-dkg-essentials/package.json b/packages/plugin-dkg-essentials/package.json
index ff16dcbd..a76c3fb8 100644
--- a/packages/plugin-dkg-essentials/package.json
+++ b/packages/plugin-dkg-essentials/package.json
@@ -29,14 +29,18 @@
"dependencies": {
"@dkg/plugin-swagger": "^0.0.2",
"@dkg/plugins": "^0.0.2",
+ "@mistralai/mistralai": "^1.3.0",
"busboy": "^1.6.0",
- "sparqljs": "^3.7.3"
+ "sparqljs": "^3.7.3",
+ "undici": "^6.19.0",
+ "unpdf": "^0.12.1"
},
"devDependencies": {
"@dkg/eslint-config": "*",
"@dkg/typescript-config": "*",
"@types/busboy": "^1.5.4",
"@types/sparqljs": "^3.1.12",
+ "pdf-lib": "^1.17.1",
"tsup": "^8.5.0"
}
}
diff --git a/packages/plugin-dkg-essentials/src/createFsBlobStorage.ts b/packages/plugin-dkg-essentials/src/createFsBlobStorage.ts
index 2079d2fc..aed0f841 100644
--- a/packages/plugin-dkg-essentials/src/createFsBlobStorage.ts
+++ b/packages/plugin-dkg-essentials/src/createFsBlobStorage.ts
@@ -6,30 +6,62 @@ import { BlobStorage } from "@dkg/plugins/types";
import { createBlobStorage } from "@dkg/plugins/helpers";
const createFsBlobStorage = (blobsDirectory: string): BlobStorage => {
+ const resolvedBlobsDirectory = path.resolve(blobsDirectory);
+
+ const resolveBlobPath = (id: string): string => {
+ if (!id) {
+ throw new Error("Invalid blob ID: empty ID is not allowed.");
+ }
+
+ const resolvedBlobPath = path.resolve(resolvedBlobsDirectory, id);
+ const relativePath = path.relative(
+ resolvedBlobsDirectory,
+ resolvedBlobPath,
+ );
+
+ if (relativePath.startsWith("..") || path.isAbsolute(relativePath)) {
+ throw new Error(`Invalid blob ID path: '${id}'.`);
+ }
+
+ return resolvedBlobPath;
+ };
+
try {
- fs.mkdirSync(blobsDirectory, { recursive: true });
+ fs.mkdirSync(resolvedBlobsDirectory, { recursive: true });
} catch (error) {
console.log(error);
}
return createBlobStorage({
- info: (id) =>
- fs.promises
- .stat(path.join(blobsDirectory, id))
- .then((stats) => ({
- size: stats.size,
- lastModified: stats.mtime,
- }))
- .catch(() => null),
- put: (id, content /* , _metadata */) => {
- const blobStream = Writable.toWeb(
- fs.createWriteStream(path.join(blobsDirectory, id)),
- );
+ info: (id) => {
+ try {
+ const filePath = resolveBlobPath(id);
+ return fs.promises
+ .stat(filePath)
+ .then((stats) => ({
+ size: stats.size,
+ lastModified: stats.mtime,
+ }))
+ .catch(() => null);
+ } catch {
+ return Promise.resolve(null);
+ }
+ },
+ put: async (id, content /* , _metadata */) => {
+ const filePath = resolveBlobPath(id);
+ // Ensure parent directories exist for nested paths
+ await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
+ const blobStream = Writable.toWeb(fs.createWriteStream(filePath));
return content.pipeTo(blobStream);
},
- get: async (id) =>
- Readable.toWeb(fs.createReadStream(path.join(blobsDirectory, id))),
- delete: (id) => fs.promises.unlink(path.join(blobsDirectory, id)),
+ get: async (id) => {
+ const filePath = resolveBlobPath(id);
+ return Readable.toWeb(fs.createReadStream(filePath));
+ },
+ delete: (id) => {
+ const filePath = resolveBlobPath(id);
+ return fs.promises.unlink(filePath);
+ },
});
};
diff --git a/packages/plugin-dkg-essentials/src/index.ts b/packages/plugin-dkg-essentials/src/index.ts
index aae45063..561afebd 100644
--- a/packages/plugin-dkg-essentials/src/index.ts
+++ b/packages/plugin-dkg-essentials/src/index.ts
@@ -2,10 +2,39 @@ import { defineDkgPlugin } from "@dkg/plugins";
import blobsPlugin from "./plugins/blobs";
import dkgToolsPlugin from "./plugins/dkg-tools";
+import documentToMarkdownPlugin, {
+ createDocumentToMarkdownPlugin,
+} from "./plugins/document-to-markdown";
-export { dkgToolsPlugin, blobsPlugin };
+// Re-export individual plugins
+export { dkgToolsPlugin, blobsPlugin, documentToMarkdownPlugin };
+
+// Re-export the factory for custom configuration
+export { createDocumentToMarkdownPlugin };
+
+// Re-export types and utilities from document-to-markdown
+export type {
+ DocumentConversionProvider,
+ DocumentConversionOptions,
+ DocumentConversionOutput,
+ ConversionResult,
+ ExtractedImage,
+ DocumentConversionConfig,
+} from "./plugins/document-to-markdown";
+
+export {
+ createProvider,
+ getDefaultProvider,
+ getAvailableProviders,
+ isProviderAvailable,
+ MistralProvider,
+ createMistralProvider,
+ UnpdfProvider,
+ createUnpdfProvider,
+} from "./plugins/document-to-markdown";
export default defineDkgPlugin((ctx, mcp, api) => {
blobsPlugin(ctx, mcp, api);
dkgToolsPlugin(ctx, mcp, api);
+ documentToMarkdownPlugin(ctx, mcp, api);
});
diff --git a/packages/plugin-dkg-essentials/src/plugins/dkg-tools.ts b/packages/plugin-dkg-essentials/src/plugins/dkg-tools.ts
index 8c9c52ee..f409de48 100644
--- a/packages/plugin-dkg-essentials/src/plugins/dkg-tools.ts
+++ b/packages/plugin-dkg-essentials/src/plugins/dkg-tools.ts
@@ -249,8 +249,8 @@ export default defineDkgPlugin((ctx, mcp) => {
{
title: "DKG Knowledge Asset get tool",
description:
- "A tool for running a GET operation on OriginTrail Decentralized Knowledge Graph (DKG) and retrieving a specific Knowledge Asset by its UAL (Unique Asset Locator), taking the UAL as input.",
- inputSchema: { ual: z.string() },
+ "Retrieve a specific Knowledge Asset from the DKG by its UAL (Unique Asset Locator). ",
+ inputSchema: { ual: z.string().describe("The UAL (Unique Asset Locator) in format: did:dkg:{blockchainName}:{blockchainId}/{blockchainAddress}/{collectionId}/{assetId} or did:dkg:{blockchainName}:{blockchainId}/{blockchainAddress}/{collectionId}") },
},
async ({ ual }) => {
const getAssetResult = await ctx.dkg.asset.get(ual);
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/blob-integration.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/blob-integration.ts
new file mode 100644
index 00000000..f1c8c31b
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/blob-integration.ts
@@ -0,0 +1,132 @@
+/**
+ * Blob storage integration for document conversion.
+ * Handles uploading converted content and images to blob storage.
+ */
+
+import { Readable } from "stream";
+import { randomUUID } from "crypto";
+import type { DkgContext } from "@dkg/plugins";
+import type {
+ ExtractedImage,
+ DocumentConversionOutput,
+ ConversionResult,
+} from "./types";
+import { getBasename, sanitizePathComponent } from "./validation";
+
+const BLOB_PREFIX = "document-conversions";
+
+/**
+ * Escape special regex characters in a string
+ */
+function escapeRegExp(str: string): string {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+}
+
+/**
+ * Replace image filename references in markdown with blob URLs.
+ * Transforms:  -> 
+ */
+export function replaceImageRefsWithBlobUrls(
+ markdown: string,
+ images: ExtractedImage[],
+): string {
+ let result = markdown;
+ for (const image of images) {
+ if (image.blobId) {
+ // Replace both the src and keep the original filename in alt
+ // Pattern:  or 
+ const pattern = new RegExp(
+ `(!\\[[^\\]]*\\])\\(${escapeRegExp(image.id)}\\)`,
+ "g",
+ );
+ result = result.replace(pattern, `$1(dkg-blob://${image.blobId})`);
+ }
+ }
+ return result;
+}
+
+/**
+ * Upload images to blob storage and update their blobId references.
+ * Mutates the images array in place.
+ */
+async function uploadImages(
+ ctx: DkgContext,
+ images: ExtractedImage[],
+ folderId: string,
+): Promise {
+ for (const image of images) {
+ const safeImageId = sanitizePathComponent(image.id);
+ const imageBlobId = `${BLOB_PREFIX}/${folderId}/${safeImageId}`;
+ const imageStream = Readable.toWeb(Readable.from(image.data));
+ await ctx.blob.put(imageBlobId, imageStream, {
+ name: safeImageId,
+ mimeType: `image/${image.originalFormat}`,
+ });
+ image.blobId = imageBlobId;
+ console.log(`Uploaded image ${image.id} as blob: ${imageBlobId}`);
+ }
+}
+
+/**
+ * Upload markdown content to blob storage.
+ */
+async function uploadMarkdown(
+ ctx: DkgContext,
+ markdown: string,
+ filename: string,
+ folderId: string,
+): Promise {
+ const safeFilename = sanitizePathComponent(filename);
+ const baseName = getBasename(safeFilename);
+ const markdownFilename = `${baseName}.md`;
+ const markdownBlobId = `${BLOB_PREFIX}/${folderId}/${markdownFilename}`;
+ const markdownBuffer = Buffer.from(markdown, "utf-8");
+ const markdownStream = Readable.toWeb(Readable.from(markdownBuffer));
+
+ await ctx.blob.put(markdownBlobId, markdownStream, {
+ name: markdownFilename,
+ mimeType: "text/markdown",
+ });
+
+ console.log(`Uploaded markdown as blob: ${markdownBlobId}`);
+ return markdownBlobId;
+}
+
+/**
+ * Integrate conversion output with blob storage.
+ * Uploads images and markdown, returns final result with blob IDs.
+ */
+export async function integrateWithBlobStorage(
+ ctx: DkgContext,
+ output: DocumentConversionOutput,
+ filename: string,
+): Promise {
+ // Create output folder with UUID
+ const folderId = randomUUID();
+
+ // Upload extracted images
+ await uploadImages(ctx, output.images, folderId);
+
+ // Replace image refs in markdown
+ let finalMarkdown = output.markdown;
+ if (output.images.length > 0) {
+ finalMarkdown = replaceImageRefsWithBlobUrls(finalMarkdown, output.images);
+ }
+
+ // Upload markdown
+ const markdownBlobId = await uploadMarkdown(
+ ctx,
+ finalMarkdown,
+ filename,
+ folderId,
+ );
+
+ return {
+ markdown: finalMarkdown,
+ images: output.images,
+ pageCount: output.pageCount,
+ processedPageCount: output.processedPageCount ?? output.pageCount,
+ outputFolderId: folderId,
+ markdownBlobId,
+ };
+}
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/conversion-errors.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/conversion-errors.ts
new file mode 100644
index 00000000..d7966593
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/conversion-errors.ts
@@ -0,0 +1,70 @@
+import { DocumentValidationError } from "./validation";
+
+export interface ClassifiedConversionError {
+ status: number;
+ message: string;
+ isUserError: boolean;
+}
+
+const USER_INPUT_ERROR_PATTERNS: RegExp[] = [
+ /^Either 'blobId' or 'fileBase64' must be provided\.$/,
+ /^Provide either 'blobId' or 'fileBase64', not both\.$/,
+ /^Document blob not found:/,
+ /only supports \.pdf files/,
+];
+
+function isDocumentValidationErrorLike(
+ error: unknown,
+): error is { statusCode: 400 | 413; message: string } {
+ if (error instanceof DocumentValidationError) {
+ return true;
+ }
+
+ if (typeof error !== "object" || error === null) {
+ return false;
+ }
+
+ const candidate = error as {
+ statusCode?: unknown;
+ message?: unknown;
+ name?: unknown;
+ };
+
+ return (
+ (candidate.statusCode === 400 || candidate.statusCode === 413) &&
+ typeof candidate.message === "string" &&
+ (candidate.name === undefined || candidate.name === "DocumentValidationError")
+ );
+}
+
+function isUserInputError(message: string): boolean {
+ return USER_INPUT_ERROR_PATTERNS.some((pattern) => pattern.test(message));
+}
+
+export function classifyConversionError(
+ error: unknown,
+): ClassifiedConversionError {
+ const message = error instanceof Error ? error.message : String(error);
+
+ if (isDocumentValidationErrorLike(error)) {
+ return {
+ status: error.statusCode,
+ message,
+ isUserError: true,
+ };
+ }
+
+ if (isUserInputError(message)) {
+ return {
+ status: message.startsWith("Document blob not found:") ? 404 : 400,
+ message,
+ isUserError: true,
+ };
+ }
+
+ return {
+ status: 500,
+ message,
+ isUserError: false,
+ };
+}
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/index.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/index.ts
new file mode 100644
index 00000000..9007d612
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/index.ts
@@ -0,0 +1,500 @@
+/**
+ * Document to Markdown MCP Tool
+ *
+ * Converts PDF, DOCX, and PPTX documents to Markdown using configurable OCR providers.
+ * Default provider: unpdf (zero-config PDF text extraction).
+ *
+ * Environment variables:
+ * - DOCUMENT_CONVERSION_PROVIDER (optional, default: "unpdf")
+ * - MISTRAL_API_KEY (required when using Mistral provider)
+ */
+
+import { Readable } from "stream";
+import consumers from "stream/consumers";
+import { defineDkgPlugin, DkgContext } from "@dkg/plugins";
+import { z } from "@dkg/plugins/helpers";
+import { openAPIRoute } from "@dkg/plugin-swagger";
+import busboy from "busboy";
+
+import type {
+ DocumentConversionProvider,
+ DocumentConversionOptions,
+ ConversionResult,
+ DocumentConversionConfig,
+} from "./types";
+import { integrateWithBlobStorage } from "./blob-integration";
+import {
+ validateFileType,
+ validateFileSize,
+ MAX_FILE_SIZE_BYTES,
+ MAX_FILE_SIZE_MB,
+} from "./validation";
+import { classifyConversionError } from "./conversion-errors";
+import { createProvider } from "./providers";
+
+// Re-export types for external use
+export type {
+ DocumentConversionProvider,
+ DocumentConversionOptions,
+ DocumentConversionOutput,
+ ConversionResult,
+ ExtractedImage,
+ DocumentConversionConfig,
+} from "./types";
+
+// Re-export provider utilities
+export {
+ createProvider,
+ getDefaultProvider,
+ getAvailableProviders,
+ isProviderAvailable,
+ MistralProvider,
+ createMistralProvider,
+ UnpdfProvider,
+ createUnpdfProvider,
+} from "./providers";
+
+// Re-export validation utilities
+export {
+ DocumentValidationError,
+ validateFileType,
+ validateFileSize,
+ getFileExtension,
+ getBasename,
+ getMimeType,
+ SUPPORTED_EXTENSIONS,
+ MAX_FILE_SIZE_MB,
+ MAX_FILE_SIZE_BYTES,
+} from "./validation";
+
+/**
+ * Process a document and convert it to markdown with image extraction.
+ * Validates file type and size, converts via provider, then integrates with blob storage.
+ */
+async function processDocument(
+ ctx: DkgContext,
+ provider: DocumentConversionProvider,
+ documentBuffer: Buffer,
+ filename: string,
+ options?: DocumentConversionOptions,
+): Promise {
+ type InternalDocumentConversionOptions = DocumentConversionOptions & {
+ __skipBaseValidation?: boolean;
+ __validatedExtension?: ReturnType;
+ };
+
+ // Validate before handing off to provider (providers may also validate internally)
+ const extension = validateFileType(filename);
+ validateFileSize(documentBuffer.length);
+
+ console.log(`Converting document using provider: ${provider.name}`);
+
+ // Convert document using provider
+ const providerOptions: InternalDocumentConversionOptions = {
+ ...options,
+ __skipBaseValidation: true,
+ __validatedExtension: extension,
+ };
+ const output = await provider.convert(documentBuffer, filename, providerOptions);
+
+ // Integrate with blob storage (upload images, upload markdown)
+ const result = await integrateWithBlobStorage(ctx, output, filename);
+
+ return result;
+}
+
+/**
+ * Create the document-to-markdown plugin with optional configuration.
+ *
+ * @param config - Optional configuration for provider selection
+ */
+export function createDocumentToMarkdownPlugin(
+ config?: DocumentConversionConfig,
+) {
+ return defineDkgPlugin((ctx, mcp, api) => {
+ // Resolve provider: use provided instance, create by name, or use default
+ let provider: DocumentConversionProvider;
+
+ if (config?.provider) {
+ provider = config.provider;
+ } else {
+ // Check environment variable for provider name
+ const providerName =
+ config?.providerName ??
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
+ process.env.DOCUMENT_CONVERSION_PROVIDER ??
+ "unpdf";
+
+ provider = createProvider(providerName);
+ }
+
+ console.log(
+ `Document-to-markdown plugin initialized with provider: ${provider.name}`,
+ );
+
+ // REST endpoint for document-to-markdown conversion
+ api.post(
+ "/document-to-markdown",
+ openAPIRoute(
+ {
+ summary: "Convert document to Markdown",
+ description:
+ "Upload a PDF, DOCX, or PPTX file and convert it to Markdown. " +
+ "Supported document types and image extraction capabilities depend on the configured provider. " +
+ "Returns the extracted markdown content and any images stored in blob storage.",
+ tag: "Documents",
+ response: {
+ schema: z.union([
+ z.object({
+ markdown: z.string().openapi({
+ description: "The extracted markdown content",
+ }),
+ markdownBlobId: z.string().openapi({
+ description: "Blob ID of the stored markdown file",
+ }),
+ outputFolderId: z.string().openapi({
+ description: "Blob folder ID containing all conversion outputs",
+ }),
+ pageCount: z.number().openapi({
+ description: "Total number of pages in the source document",
+ }),
+ processedPageCount: z.number().openapi({
+ description:
+ "Number of pages included in the converted markdown output",
+ }),
+ images: z.array(
+ z.object({
+ id: z.string(),
+ blobId: z.string(),
+ }),
+ ).openapi({
+ description: "List of extracted images with their blob IDs",
+ }),
+ }),
+ z.object({
+ error: z.string().openapi({
+ description: "Error message when conversion fails",
+ }),
+ }),
+ ]),
+ },
+ finalizeRouteConfig(cfg) {
+ cfg.request = {
+ body: {
+ required: true,
+ description:
+ "Document file to convert. Supported formats: PDF, DOCX, PPTX.",
+ content: {
+ "multipart/form-data": {
+ schema: z.object({
+ file: z.string().openapi({
+ description: "The document file to convert",
+ format: "binary",
+ }),
+ }),
+ },
+ },
+ },
+ };
+ return cfg;
+ },
+ },
+ async (req, res) => {
+ type DocumentToMarkdownRestResponse =
+ | { error: string }
+ | {
+ markdown: string;
+ markdownBlobId: string;
+ outputFolderId: string;
+ pageCount: number;
+ processedPageCount: number;
+ images: Array<{
+ id: string;
+ blobId: string;
+ }>;
+ };
+
+ let fileReceived = false;
+ let fileReadPromise: Promise | null = null;
+ let uploadedFile:
+ | {
+ documentBuffer: Buffer;
+ filename: string;
+ truncated: boolean;
+ }
+ | null = null;
+ let responded = false;
+
+ const sendOnce = (
+ status: number,
+ body: DocumentToMarkdownRestResponse,
+ ): void => {
+ if (responded || res.headersSent) {
+ return;
+ }
+ responded = true;
+ res.status(status).json(body);
+ };
+
+ let bb: ReturnType;
+ try {
+ bb = busboy({
+ headers: req.headers,
+ limits: { fileSize: MAX_FILE_SIZE_BYTES, files: 1 },
+ });
+ } catch (error) {
+ const message =
+ error instanceof Error ? error.message : String(error);
+ console.error("Error initializing multipart parser:", message);
+ sendOnce(400, { error: "Invalid multipart request." });
+ return;
+ }
+
+ bb.on("file", (name, file, info) => {
+ if (responded) {
+ file.resume();
+ return;
+ }
+
+ if (name !== "file") {
+ file.resume();
+ sendOnce(400, { error: "Invalid file field. Expected 'file'." });
+ return;
+ }
+
+ if (fileReceived) {
+ file.resume();
+ sendOnce(400, {
+ error: "Exactly one file must be provided in the request.",
+ });
+ return;
+ }
+
+ fileReceived = true;
+ let truncated = false;
+ file.on("limit", () => {
+ truncated = true;
+ });
+
+ fileReadPromise = (async () => {
+ try {
+ const documentBuffer = await consumers.buffer(
+ Readable.toWeb(file),
+ );
+
+ if (responded) {
+ return;
+ }
+
+ uploadedFile = {
+ documentBuffer,
+ filename: info.filename,
+ truncated,
+ };
+ } catch (error) {
+ const message =
+ error instanceof Error ? error.message : String(error);
+ console.error(
+ "Error reading uploaded file for document conversion:",
+ message,
+ );
+ sendOnce(400, { error: message });
+ }
+ })();
+ });
+
+ bb.on("filesLimit", () => {
+ sendOnce(400, {
+ error: "Exactly one file must be provided in the request.",
+ });
+ });
+
+ bb.on("error", (error: Error) => {
+ console.error("Error parsing multipart request:", error.message);
+ sendOnce(400, { error: "Invalid multipart request." });
+ });
+
+ bb.on("close", () => {
+ void (async () => {
+ if (fileReadPromise) {
+ await fileReadPromise;
+ }
+
+ if (responded) {
+ return;
+ }
+
+ if (!fileReceived || !uploadedFile) {
+ sendOnce(400, { error: "No file provided in the request." });
+ return;
+ }
+
+ if (uploadedFile.truncated) {
+ sendOnce(413, {
+ error: `File size exceeds maximum of ${MAX_FILE_SIZE_MB}MB.`,
+ });
+ return;
+ }
+
+ try {
+ const result = await processDocument(
+ ctx,
+ provider,
+ uploadedFile.documentBuffer,
+ uploadedFile.filename,
+ );
+
+ sendOnce(200, {
+ markdown: result.markdown,
+ markdownBlobId: result.markdownBlobId,
+ outputFolderId: result.outputFolderId,
+ pageCount: result.pageCount,
+ processedPageCount: result.processedPageCount,
+ images: result.images.map((img) => ({
+ id: img.id,
+ blobId: img.blobId ?? "",
+ })),
+ });
+ } catch (error) {
+ const { status, message } = classifyConversionError(error);
+ console.error(
+ "Error converting document to markdown:",
+ message,
+ );
+ sendOnce(status, { error: message });
+ }
+ })();
+ });
+
+ req.pipe(bb);
+ },
+ ),
+ );
+
+ mcp.registerTool(
+ "document-to-markdown",
+ {
+ title: "Document to Markdown",
+ description:
+ "Convert PDF, DOCX, or PPTX documents to Markdown. " +
+ "Supported document types and image extraction capabilities depend on the configured provider. " +
+ "Use this as the first step when publishing documents to the DKG - " +
+ "the markdown output can then be transformed to JSON-LD and published using dkg-create.",
+ inputSchema: {
+ blobId: z
+ .string()
+ .optional()
+ .describe("ID of a previously uploaded document blob"),
+ fileBase64: z
+ .string()
+ .optional()
+ .describe("Base64-encoded document content"),
+ filename: z
+ .string()
+ .describe(
+ "Original filename with extension (e.g., 'report.pdf', 'document.docx')",
+ ),
+ options: z
+ .object({
+ pageStart: z
+ .number()
+ .int()
+ .min(1)
+ .optional()
+ .describe("First page to process (1-indexed)"),
+ pageEnd: z
+ .number()
+ .int()
+ .min(1)
+ .optional()
+ .describe("Last page to process (inclusive)"),
+ includeImages: z
+ .boolean()
+ .optional()
+ .describe("Whether to extract images (default: true)"),
+ })
+ .optional()
+ .describe("Conversion options"),
+ },
+ },
+ async (input) => {
+ try {
+ // Validate input: require either blobId or fileBase64
+ if (!input.blobId && !input.fileBase64) {
+ throw new Error(
+ "Either 'blobId' or 'fileBase64' must be provided.",
+ );
+ }
+ if (input.blobId && input.fileBase64) {
+ throw new Error(
+ "Provide either 'blobId' or 'fileBase64', not both.",
+ );
+ }
+
+ // Get document content
+ let documentBuffer: Buffer;
+
+ if (input.blobId) {
+ const blob = await ctx.blob.get(input.blobId);
+ if (!blob) {
+ throw new Error(`Document blob not found: ${input.blobId}`);
+ }
+ documentBuffer = await consumers.buffer(blob.data);
+ } else {
+ documentBuffer = Buffer.from(input.fileBase64!, "base64");
+ }
+
+ // Process the document
+ const result = await processDocument(
+ ctx,
+ provider,
+ documentBuffer,
+ input.filename,
+ input.options,
+ );
+
+ // Build response
+ const imageInfo =
+ result.images.length > 0
+ ? `\n\n**Extracted Images:** ${result.images.length} image(s)\n` +
+ result.images
+ .map((img) => `- ${img.id}: \`${img.blobId}\``)
+ .join("\n")
+ : "";
+
+ const response =
+ `Document successfully converted to Markdown.\n\n` +
+ `**Output Folder:** ${result.outputFolderId}\n` +
+ `**Markdown Blob ID:** ${result.markdownBlobId}\n` +
+ `**Total Pages:** ${result.pageCount}\n` +
+ `**Pages Processed:** ${result.processedPageCount}` +
+ imageInfo +
+ `\n\n---\n\n${result.markdown}`;
+
+ return {
+ content: [{ type: "text", text: response }],
+ };
+ } catch (error) {
+ const { message } = classifyConversionError(error);
+ console.error("Error converting document to markdown:", message);
+
+ return {
+ isError: true,
+ content: [
+ {
+ type: "text",
+ text: `Document conversion failed: ${message}`,
+ },
+ ],
+ };
+ }
+ },
+ );
+ });
+}
+
+/**
+ * Default plugin export - uses unpdf provider (zero-config).
+ * For Mistral OCR, use createDocumentToMarkdownPlugin({ providerName: "mistral" }).
+ */
+export default createDocumentToMarkdownPlugin();
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/page-range.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/page-range.ts
new file mode 100644
index 00000000..9219428d
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/page-range.ts
@@ -0,0 +1,51 @@
+import type { DocumentConversionOptions } from "./types";
+
+export interface NormalizedPageRange {
+ startPage: number;
+ endPage: number;
+ hasPageFilter: boolean;
+}
+
+function toSafePageNumber(value: unknown, fallback: number): number {
+ if (typeof value !== "number" || !Number.isFinite(value)) {
+ return fallback;
+ }
+ return Math.trunc(value);
+}
+
+/**
+ * Normalize optional 1-indexed page range options to inclusive bounds.
+ * Bounds are clamped to [1, totalPages] and preserve start <= end.
+ */
+export function normalizePageRange(
+ totalPages: number,
+ options?: Pick,
+): NormalizedPageRange {
+ const normalizedTotalPages =
+ Number.isFinite(totalPages) && totalPages > 0 ? Math.trunc(totalPages) : 0;
+ const hasPageFilter = options?.pageStart != null || options?.pageEnd != null;
+
+ // Providers can occasionally produce empty-page responses; keep bounds valid.
+ if (normalizedTotalPages === 0) {
+ return {
+ startPage: 1,
+ endPage: 0,
+ hasPageFilter,
+ };
+ }
+
+ const requestedStart = toSafePageNumber(options?.pageStart, 1);
+ const requestedEnd = toSafePageNumber(options?.pageEnd, normalizedTotalPages);
+
+ const startPage = Math.min(normalizedTotalPages, Math.max(1, requestedStart));
+ const endPage = Math.min(
+ normalizedTotalPages,
+ Math.max(startPage, requestedEnd),
+ );
+
+ return {
+ startPage,
+ endPage,
+ hasPageFilter,
+ };
+}
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/index.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/index.ts
new file mode 100644
index 00000000..d3a08169
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/index.ts
@@ -0,0 +1,71 @@
+/**
+ * Provider registry for document-to-markdown conversion.
+ * Handles provider creation and selection.
+ */
+
+import type { DocumentConversionProvider } from "../types";
+import { createMistralProvider } from "./mistral";
+import { createUnpdfProvider } from "./unpdf";
+
+// Re-export provider implementations
+export { MistralProvider, createMistralProvider } from "./mistral";
+export { UnpdfProvider, createUnpdfProvider } from "./unpdf";
+
+/**
+ * Map of provider names to factory functions
+ */
+const PROVIDER_FACTORIES: Record<
+ string,
+ (options?: Record) => DocumentConversionProvider
+> = {
+ mistral: (options) => createMistralProvider(options?.apiKey as string),
+ unpdf: () => createUnpdfProvider(),
+};
+
+/**
+ * Default provider name
+ */
+const DEFAULT_PROVIDER = "unpdf";
+
+/**
+ * Get list of available provider names
+ */
+export function getAvailableProviders(): string[] {
+ return Object.keys(PROVIDER_FACTORIES);
+}
+
+/**
+ * Check if a provider is available
+ */
+export function isProviderAvailable(name: string): boolean {
+ return name in PROVIDER_FACTORIES;
+}
+
+/**
+ * Create a provider by name.
+ *
+ * @param name - Provider name (default: "unpdf")
+ * @param options - Provider-specific options
+ * @throws Error if provider is not found
+ */
+export function createProvider(
+ name: string = DEFAULT_PROVIDER,
+ options?: Record,
+): DocumentConversionProvider {
+ const factory = PROVIDER_FACTORIES[name.toLowerCase()];
+ if (!factory) {
+ const available = getAvailableProviders().join(", ");
+ throw new Error(
+ `Unknown document conversion provider: "${name}". Available: ${available}`,
+ );
+ }
+ return factory(options);
+}
+
+/**
+ * Get the default provider (unpdf).
+ * This is the most common use case - just get a working provider with zero config.
+ */
+export function getDefaultProvider(): DocumentConversionProvider {
+ return createProvider(DEFAULT_PROVIDER);
+}
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/mistral.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/mistral.ts
new file mode 100644
index 00000000..ee83792c
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/mistral.ts
@@ -0,0 +1,298 @@
+/**
+ * Mistral OCR provider for document-to-markdown conversion.
+ * Uses Mistral's OCR API to convert PDF, DOCX, and PPTX to Markdown.
+ */
+
+import { Mistral } from "@mistralai/mistralai";
+import { HTTPClient } from "@mistralai/mistralai/lib/http";
+import type { OCRResponse } from "@mistralai/mistralai/models/components/ocrresponse";
+import { fetch as undiciFetch, RequestInit as UndiciRequestInit } from "undici";
+
+import type {
+ DocumentConversionProvider,
+ DocumentConversionOptions,
+ DocumentConversionOutput,
+ ExtractedImage,
+} from "../types";
+import { normalizePageRange } from "../page-range";
+import { validateFileType, validateFileSize, getMimeType } from "../validation";
+
+// ============================================================================
+// CONSTANTS
+// ============================================================================
+
+const API_TIMEOUT_MS = 120000; // 2 minutes
+const PROVIDER_NAME = "mistral";
+
+// ============================================================================
+// MISTRAL CLIENT SETUP
+// ============================================================================
+
+/**
+ * Custom fetcher using undici's native Node.js fetch implementation.
+ * This bypasses the bundled fetch polyfill that has issues with Request objects.
+ */
+const customFetcher = async (
+ input: RequestInfo | URL,
+ init?: RequestInit,
+): Promise => {
+ // If input is a Request object, extract the URL and merge options
+ if (input instanceof Request) {
+ const url = input.url;
+ const mergedInit = {
+ method: input.method,
+ headers: input.headers,
+ body: input.body,
+ duplex: input.body ? "half" : undefined,
+ ...init,
+ } as UndiciRequestInit;
+ return undiciFetch(url, mergedInit) as unknown as Promise;
+ }
+
+ // Check if it looks like a Request but isn't detected as one (bundler issue)
+ if (
+ typeof input === "object" &&
+ input !== null &&
+ "url" in input &&
+ "method" in input
+ ) {
+ const requestLike = input as {
+ url: string;
+ method: string;
+ headers?: unknown;
+ body?: unknown;
+ };
+ const mergedInit = {
+ method: requestLike.method,
+ headers: requestLike.headers,
+ body: requestLike.body,
+ duplex: requestLike.body ? "half" : undefined,
+ ...init,
+ } as UndiciRequestInit;
+ return undiciFetch(
+ requestLike.url,
+ mergedInit,
+ ) as unknown as Promise;
+ }
+
+ // Otherwise, pass through normally
+ return undiciFetch(
+ input as Parameters[0],
+ init as UndiciRequestInit,
+ ) as unknown as Promise;
+};
+
+/**
+ * Get a configured Mistral client instance
+ */
+function createMistralClient(apiKey: string): Mistral {
+ const httpClient = new HTTPClient({ fetcher: customFetcher });
+ return new Mistral({ apiKey, httpClient });
+}
+
+// ============================================================================
+// RESPONSE PROCESSING
+// ============================================================================
+
+/**
+ * Clean Mistral OCR response and format as markdown
+ */
+export function formatOcrResponseAsMarkdown(
+ response: OCRResponse,
+ startPage: number = 1,
+): string {
+ const fullMarkdown = response.pages
+ .map(
+ (page, index) =>
+ `---\n\n## Page ${startPage + index}\n\n${page.markdown || ""}`,
+ )
+ .join("\n\n");
+ return fullMarkdown;
+}
+
+/**
+ * Extract images from Mistral OCR response pages.
+ * Mistral returns images in a separate `images` array per page with:
+ * - id: string (e.g., "img-0.jpeg")
+ * - imageBase64: string (base64 encoded image data, when include_image_base64=true)
+ */
+function extractImagesFromResponse(response: OCRResponse): ExtractedImage[] {
+ const images: ExtractedImage[] = [];
+
+ for (const page of response.pages) {
+ const pageImages = page.images as
+ | Array<{ id: string; imageBase64?: string }>
+ | undefined;
+
+ if (!pageImages || pageImages.length === 0) {
+ continue;
+ }
+
+ for (const img of pageImages) {
+ // Skip if no base64 data (happens when include_image_base64=false)
+ if (!img.imageBase64) {
+ console.warn(`Image ${img.id} has no base64 data - skipping`);
+ continue;
+ }
+
+ // Strip data URL prefix if present (e.g., "data:image/jpeg;base64,")
+ let base64Data = img.imageBase64;
+ const dataUrlMatch = base64Data.match(/^data:image\/[^;]+;base64,(.*)$/);
+ if (dataUrlMatch && dataUrlMatch[1]) {
+ base64Data = dataUrlMatch[1];
+ }
+
+ // Extract format from image ID (e.g., "img-0.jpeg" -> "jpeg")
+ const formatMatch = img.id.match(/\.([a-zA-Z0-9]+)$/);
+ const originalFormat = formatMatch?.[1]?.toLowerCase() ?? "png";
+
+ images.push({
+ id: img.id,
+ originalFormat,
+ data: Buffer.from(base64Data, "base64"),
+ });
+ }
+ }
+
+ return images;
+}
+
+// ============================================================================
+// OCR API CALL
+// ============================================================================
+
+/**
+ * Call Mistral OCR API to convert document
+ */
+async function callOcrApi(
+ client: Mistral,
+ documentBuffer: Buffer,
+ mimeType: string,
+ options?: DocumentConversionOptions,
+): Promise {
+ const base64Document = documentBuffer.toString("base64");
+
+ console.log("Calling Mistral OCR API to convert document to markdown...");
+
+ // Create timeout promise for race condition
+ let timeoutId: NodeJS.Timeout;
+ const timeoutPromise = new Promise((_, reject) => {
+ timeoutId = setTimeout(() => {
+ reject(
+ new Error(
+ `Mistral OCR request timed out after ${API_TIMEOUT_MS / 1000} seconds. ` +
+ "The document may be too large or complex.",
+ ),
+ );
+ }, API_TIMEOUT_MS);
+ });
+
+ // Create OCR processing promise
+ const ocrPromise = client.ocr.process({
+ model: "mistral-ocr-latest",
+ document: {
+ type: "document_url",
+ documentUrl: `data:${mimeType};base64,${base64Document}`,
+ },
+ includeImageBase64: options?.includeImages !== false,
+ });
+
+ // Race between OCR and timeout, then clean up the timer
+ const response = await Promise.race([ocrPromise, timeoutPromise]).finally(
+ () => clearTimeout(timeoutId),
+ );
+
+ console.log("Mistral OCR API response received.");
+ return response;
+}
+
+// ============================================================================
+// PROVIDER IMPLEMENTATION
+// ============================================================================
+
+/**
+ * Mistral OCR provider for document conversion.
+ */
+export class MistralProvider implements DocumentConversionProvider {
+ readonly name = PROVIDER_NAME;
+ private readonly apiKey: string;
+
+ constructor(apiKey?: string) {
+ // Use provided key or fall back to environment variable
+ // eslint-disable-next-line turbo/no-undeclared-env-vars
+ const key = apiKey ?? process.env.MISTRAL_API_KEY;
+ if (!key) {
+ throw new Error(
+ "MISTRAL_API_KEY environment variable is not set. " +
+ "Please configure your Mistral API key to use document conversion.",
+ );
+ }
+ this.apiKey = key;
+ }
+
+ async convert(
+ buffer: Buffer,
+ filename: string,
+ options?: DocumentConversionOptions,
+ ): Promise {
+ type InternalDocumentConversionOptions = DocumentConversionOptions & {
+ __skipBaseValidation?: boolean;
+ __validatedExtension?: ReturnType;
+ };
+ const internalOptions = options as InternalDocumentConversionOptions | undefined;
+
+ // Validate file type and get MIME type
+ const extension =
+ internalOptions?.__validatedExtension ?? validateFileType(filename);
+ const mimeType = getMimeType(extension);
+
+ // Validate file size
+ if (!internalOptions?.__skipBaseValidation) {
+ validateFileSize(buffer.length);
+ }
+
+ // Create client and call OCR API
+ const client = createMistralClient(this.apiKey);
+ const response = await callOcrApi(client, buffer, mimeType, options);
+
+ // Apply page range filter if specified
+ let pages = response.pages;
+ const { startPage, endPage, hasPageFilter } = normalizePageRange(
+ pages.length,
+ options,
+ );
+ if (hasPageFilter) {
+ pages = pages.slice(startPage - 1, endPage);
+ }
+
+ const filteredResponse = { ...response, pages };
+
+ // Format markdown
+ const markdown = formatOcrResponseAsMarkdown(filteredResponse, startPage);
+
+ // Extract images if enabled
+ const includeImages = options?.includeImages !== false;
+ const images = includeImages
+ ? extractImagesFromResponse(filteredResponse)
+ : [];
+
+ if (images.length > 0) {
+ console.log(`Extracted ${images.length} images from OCR response`);
+ }
+
+ return {
+ markdown,
+ images,
+ pageCount: response.pages.length,
+ processedPageCount: pages.length,
+ };
+ }
+}
+
+/**
+ * Create a Mistral provider instance.
+ * @param apiKey - Optional API key (defaults to MISTRAL_API_KEY env var)
+ */
+export function createMistralProvider(apiKey?: string): MistralProvider {
+ return new MistralProvider(apiKey);
+}
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/unpdf.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/unpdf.ts
new file mode 100644
index 00000000..c1834111
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/providers/unpdf.ts
@@ -0,0 +1,87 @@
+/**
+ * unpdf provider for document-to-markdown conversion.
+ * Uses Mozilla pdf.js (via unpdf) to extract text from non-scanned PDFs.
+ * Zero-config - no API key required.
+ */
+
+import { extractText } from "unpdf";
+
+import type {
+ DocumentConversionProvider,
+ DocumentConversionOptions,
+ DocumentConversionOutput,
+} from "../types";
+import { normalizePageRange } from "../page-range";
+import { getFileExtension, validateFileSize } from "../validation";
+
+const PROVIDER_NAME = "unpdf";
+
+/**
+ * unpdf provider for PDF text extraction.
+ * Supports .pdf files only - for .docx/.pptx or scanned PDFs, use Mistral.
+ */
+export class UnpdfProvider implements DocumentConversionProvider {
+ readonly name = PROVIDER_NAME;
+
+ async convert(
+ buffer: Buffer,
+ filename: string,
+ options?: DocumentConversionOptions,
+ ): Promise {
+ type InternalDocumentConversionOptions = DocumentConversionOptions & {
+ __skipBaseValidation?: boolean;
+ };
+ const internalOptions = options as InternalDocumentConversionOptions | undefined;
+
+ // Only PDF is supported - reject other formats with a helpful message
+ const ext = getFileExtension(filename);
+ if (ext !== ".pdf") {
+ throw new Error(
+ `The unpdf provider only supports .pdf files, got '${ext || "(no extension)"}'. ` +
+ `For .docx and .pptx support, use the Mistral provider ` +
+ `(set DOCUMENT_CONVERSION_PROVIDER=mistral and provide MISTRAL_API_KEY).`,
+ );
+ }
+
+ if (!internalOptions?.__skipBaseValidation) {
+ validateFileSize(buffer.length);
+ }
+
+ // Extract text from PDF using pdf.js
+ const { totalPages, text } = await extractText(new Uint8Array(buffer), {
+ mergePages: false,
+ });
+
+ const { startPage, endPage, hasPageFilter } = normalizePageRange(
+ totalPages,
+ options,
+ );
+
+ let pages = text;
+ if (hasPageFilter) {
+ pages = text.slice(startPage - 1, endPage);
+ }
+
+ // Format pages with separators
+ const markdown = pages
+ .map((pageText, i) => {
+ const pageNum = startPage + i;
+ return `\n\n${pageText}`;
+ })
+ .join("\n\n");
+
+ return {
+ markdown,
+ images: [],
+ pageCount: totalPages,
+ processedPageCount: pages.length,
+ };
+ }
+}
+
+/**
+ * Create an unpdf provider instance. No configuration required.
+ */
+export function createUnpdfProvider(): UnpdfProvider {
+ return new UnpdfProvider();
+}
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/types.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/types.ts
new file mode 100644
index 00000000..59031166
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/types.ts
@@ -0,0 +1,99 @@
+/**
+ * Shared types for document-to-markdown conversion.
+ * These types define the provider contract and shared data structures.
+ */
+
+/**
+ * Options for document conversion
+ */
+export interface DocumentConversionOptions {
+ /** First page to process (1-indexed integer) */
+ pageStart?: number;
+ /** Last page to process (inclusive 1-indexed integer) */
+ pageEnd?: number;
+ /** Whether to extract images (default: true) */
+ includeImages?: boolean;
+}
+
+/**
+ * Represents an image extracted from a document during conversion
+ */
+export interface ExtractedImage {
+ /** Image identifier (e.g., "img-0.jpeg") */
+ id: string;
+ /** Original image format (e.g., "jpeg", "png") */
+ originalFormat: string;
+ /** Raw image data */
+ data: Buffer;
+ /** Blob storage ID (set after upload) */
+ blobId?: string;
+}
+
+/**
+ * Output from document conversion (before blob integration)
+ */
+export interface DocumentConversionOutput {
+ /** Converted markdown content */
+ markdown: string;
+ /** Extracted images */
+ images: ExtractedImage[];
+ /** Total number of pages in the source document */
+ pageCount: number;
+ /**
+ * Number of pages included in the converted markdown output.
+ * If omitted by a provider, it defaults to `pageCount`.
+ */
+ processedPageCount?: number;
+}
+
+/**
+ * Final result after blob integration (includes storage IDs)
+ */
+export interface ConversionResult {
+ /** Final markdown with blob URLs for images */
+ markdown: string;
+ /** Extracted images with blob IDs */
+ images: ExtractedImage[];
+ /** Total number of pages in the source document */
+ pageCount: number;
+ /** Number of pages included in the converted markdown output */
+ processedPageCount: number;
+ /** Folder ID in blob storage */
+ outputFolderId: string;
+ /** Blob ID for the markdown file */
+ markdownBlobId: string;
+}
+
+/**
+ * Provider contract for document-to-markdown conversion.
+ * Implementations handle vendor-specific logic internally.
+ */
+export interface DocumentConversionProvider {
+ /** Provider name for logging/identification */
+ readonly name: string;
+
+ /**
+ * Convert a document buffer to markdown with optional image extraction.
+ *
+ * @param buffer - Document content as a Buffer
+ * @param filename - Original filename (used for format detection)
+ * @param options - Conversion options
+ * @returns Converted markdown and extracted images
+ * @throws Error if conversion fails or file type is unsupported
+ */
+ convert(
+ buffer: Buffer,
+ filename: string,
+ options?: DocumentConversionOptions,
+ ): Promise;
+}
+
+/**
+ * Configuration for document conversion plugin
+ */
+export interface DocumentConversionConfig {
+ /** Provider to use for conversion (default: auto-detected) */
+ provider?: DocumentConversionProvider;
+ /** Provider name to use if no provider instance given (default: "unpdf") */
+ providerName?: string;
+}
diff --git a/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/validation.ts b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/validation.ts
new file mode 100644
index 00000000..3a0a4596
--- /dev/null
+++ b/packages/plugin-dkg-essentials/src/plugins/document-to-markdown/validation.ts
@@ -0,0 +1,106 @@
+/**
+ * Shared validation utilities for document-to-markdown conversion.
+ * These are provider-agnostic and used across all implementations.
+ */
+
+// ============================================================================
+// CONSTANTS
+// ============================================================================
+
+export const MAX_FILE_SIZE_MB = 50;
+export const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
+
+export const SUPPORTED_EXTENSIONS = [".pdf", ".docx", ".pptx"] as const;
+export type SupportedExtension = (typeof SUPPORTED_EXTENSIONS)[number];
+
+export const MIME_TYPE_MAP: Record = {
+ ".pdf": "application/pdf",
+ ".docx":
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ ".pptx":
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+};
+
+// ============================================================================
+// VALIDATION FUNCTIONS
+// ============================================================================
+
+export class DocumentValidationError extends Error {
+ readonly statusCode: 400 | 413;
+
+ constructor(message: string, statusCode: 400 | 413 = 400) {
+ super(message);
+ this.name = "DocumentValidationError";
+ this.statusCode = statusCode;
+ }
+}
+
+/**
+ * Get file extension from filename (lowercase, includes dot)
+ */
+export function getFileExtension(filename: string): string {
+ const lastDot = filename.lastIndexOf(".");
+ if (lastDot === -1) return "";
+ return filename.slice(lastDot).toLowerCase();
+}
+
+/**
+ * Validate file type is supported
+ * @throws Error if file type is not supported
+ */
+export function validateFileType(filename: string): SupportedExtension {
+ const ext = getFileExtension(filename);
+ if (!SUPPORTED_EXTENSIONS.includes(ext as SupportedExtension)) {
+ throw new DocumentValidationError(
+ `Unsupported file type: '${ext || "(no extension)"}'. ` +
+ `Supported: ${SUPPORTED_EXTENSIONS.join(", ")}`,
+ );
+ }
+ return ext as SupportedExtension;
+}
+
+/**
+ * Validate file size is within limits
+ * @throws Error if file is too large
+ */
+export function validateFileSize(sizeBytes: number): void {
+ if (sizeBytes > MAX_FILE_SIZE_BYTES) {
+ const sizeMB = (sizeBytes / (1024 * 1024)).toFixed(2);
+ throw new DocumentValidationError(
+ `File size (${sizeMB}MB) exceeds maximum of ${MAX_FILE_SIZE_MB}MB.`,
+ 413,
+ );
+ }
+}
+
+/**
+ * Get MIME type for a supported file extension
+ */
+export function getMimeType(extension: SupportedExtension): string {
+ return MIME_TYPE_MAP[extension];
+}
+
+/**
+ * Sanitize a string for safe use as a path component in blob IDs.
+ * Strips directory traversal sequences and path separators to prevent
+ * writes outside the intended blob prefix (CWE-22).
+ */
+export function sanitizePathComponent(name: string): string {
+ // Extract only the final segment (strips any directory components)
+ const basename = name.split(/[/\\]/).pop() || name;
+ // Remove any remaining ".." sequences
+ const sanitized = basename.replace(/\.\./g, "");
+ if (!sanitized) {
+ throw new DocumentValidationError(`Invalid path component: '${name}'`);
+ }
+ return sanitized;
+}
+
+/**
+ * Get base filename without extension
+ */
+export function getBasename(filename: string): string {
+ const ext = getFileExtension(filename);
+ if (!ext) return filename;
+ return filename.slice(0, -ext.length);
+}
diff --git a/packages/plugin-dkg-essentials/tests/createFsBlobStorage.spec.ts b/packages/plugin-dkg-essentials/tests/createFsBlobStorage.spec.ts
new file mode 100644
index 00000000..ddaae6f5
--- /dev/null
+++ b/packages/plugin-dkg-essentials/tests/createFsBlobStorage.spec.ts
@@ -0,0 +1,80 @@
+import fs from "fs";
+import os from "os";
+import path from "path";
+import { Readable } from "stream";
+import consumers from "stream/consumers";
+import { describe, it, beforeEach, afterEach } from "mocha";
+import { expect } from "chai";
+
+import createFsBlobStorage from "../dist/createFsBlobStorage.js";
+
+describe("@dkg/plugin-dkg-essentials createFsBlobStorage", () => {
+ let tempRootDir: string;
+
+ beforeEach(() => {
+ tempRootDir = fs.mkdtempSync(path.join(os.tmpdir(), "dkg-fs-blobs-"));
+ });
+
+ afterEach(async () => {
+ await fs.promises.rm(tempRootDir, { recursive: true, force: true });
+ });
+
+ it("should allow writes inside blob root and read content back", async () => {
+ const blobsDir = path.join(tempRootDir, "blobs");
+ const storage = createFsBlobStorage(blobsDir);
+ const input = Buffer.from("hello blob storage");
+
+ await storage.put(
+ "nested/path/test.txt",
+ Readable.toWeb(Readable.from(input)),
+ {},
+ );
+
+ const blob = await storage.get("nested/path/test.txt");
+ expect(blob).to.not.equal(null);
+
+ const output = await consumers.buffer(blob!.data);
+ expect(output.toString()).to.equal("hello blob storage");
+ });
+
+ it("should block path traversal on put and not write outside blob root", async () => {
+ const blobsDir = path.join(tempRootDir, "blobs");
+ const storage = createFsBlobStorage(blobsDir);
+ const outsidePath = path.join(tempRootDir, "outside.txt");
+
+ try {
+ await storage.put(
+ "../outside.txt",
+ Readable.toWeb(Readable.from(Buffer.from("attack"))),
+ {},
+ );
+ expect.fail("Expected path traversal put to throw");
+ } catch (error) {
+ const message = error instanceof Error ? error.message : String(error);
+ expect(message).to.include("Invalid blob ID path");
+ }
+
+ expect(fs.existsSync(outsidePath)).to.equal(false);
+ });
+
+ it("should return null from info for traversal IDs", async () => {
+ const blobsDir = path.join(tempRootDir, "blobs");
+ const storage = createFsBlobStorage(blobsDir);
+
+ const info = await storage.info("../outside.txt");
+ expect(info).to.equal(null);
+ });
+
+ it("should block traversal on delete", async () => {
+ const blobsDir = path.join(tempRootDir, "blobs");
+ const storage = createFsBlobStorage(blobsDir);
+
+ try {
+ await storage.delete("../outside.txt");
+ expect.fail("Expected path traversal delete to throw");
+ } catch (error) {
+ const message = error instanceof Error ? error.message : String(error);
+ expect(message).to.include("Invalid blob ID path");
+ }
+ });
+});
diff --git a/packages/plugin-dkg-essentials/tests/document-to-markdown.spec.ts b/packages/plugin-dkg-essentials/tests/document-to-markdown.spec.ts
new file mode 100644
index 00000000..72f79b22
--- /dev/null
+++ b/packages/plugin-dkg-essentials/tests/document-to-markdown.spec.ts
@@ -0,0 +1,813 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable turbo/no-undeclared-env-vars */
+
+import { describe, it, beforeEach, afterEach } from "mocha";
+import { expect } from "chai";
+import sinon from "sinon";
+import { PDFDocument, StandardFonts } from "pdf-lib";
+import {
+ createDocumentToMarkdownPlugin,
+ createProvider,
+ getAvailableProviders,
+ isProviderAvailable,
+ UnpdfProvider,
+ createUnpdfProvider,
+} from "../dist/index.js";
+import { formatOcrResponseAsMarkdown } from "../dist/plugins/document-to-markdown/providers/mistral.js";
+import { normalizePageRange } from "../dist/plugins/document-to-markdown/page-range.js";
+import { classifyConversionError } from "../dist/plugins/document-to-markdown/conversion-errors.js";
+import { DocumentValidationError } from "../dist/plugins/document-to-markdown/validation.js";
+import {
+ createExpressApp,
+ createInMemoryBlobStorage,
+ createMcpServerClientPair,
+ createMockDkgClient,
+} from "@dkg/plugins/testing";
+import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
+import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
+import express from "express";
+import request from "supertest";
+import { Readable } from "stream";
+
+// Mock provider for tests that don't need real OCR
+const createMockProvider = (overrides?: Partial) => ({
+ name: "mock-provider",
+ convert: sinon.stub().resolves({
+ markdown: "# Mock Content",
+ images: [],
+ pageCount: 1,
+ processedPageCount: 1,
+ }),
+ ...overrides,
+});
+
+// Mock DKG context
+const mockDkgContext = {
+ dkg: createMockDkgClient(),
+ blob: createInMemoryBlobStorage(),
+};
+
+/**
+ * Helper: create a PDF with the given page texts using pdf-lib.
+ */
+async function createTestPdf(pageTexts: string[]): Promise {
+ const doc = await PDFDocument.create();
+ const font = await doc.embedFont(StandardFonts.Helvetica);
+
+ for (const text of pageTexts) {
+ const page = doc.addPage([600, 400]);
+ page.drawText(text, { x: 50, y: 350, font, size: 14 });
+ }
+
+ const bytes = await doc.save();
+ return Buffer.from(bytes);
+}
+
+describe("@dkg/plugin-dkg-essentials document-to-markdown", () => {
+ let mockMcpServer: McpServer;
+ let mockMcpClient: Client;
+ let apiRouter: express.Router;
+ let app: express.Application;
+ let originalEnv: string | undefined;
+
+ beforeEach(async () => {
+ // Save original env
+ originalEnv = process.env.MISTRAL_API_KEY;
+
+ const { server, client, connect } = await createMcpServerClientPair();
+ mockMcpServer = server;
+ mockMcpClient = client;
+ apiRouter = express.Router();
+
+ // Setup Express app
+ app = createExpressApp();
+
+ // Initialize plugin with a mock provider (avoids needing MISTRAL_API_KEY)
+ const plugin = createDocumentToMarkdownPlugin({
+ provider: createMockProvider(),
+ });
+ plugin(mockDkgContext, mockMcpServer, apiRouter);
+ await connect();
+
+ // Mount the router
+ app.use("/", apiRouter);
+ });
+
+ afterEach(() => {
+ // Restore original env
+ if (originalEnv !== undefined) {
+ process.env.MISTRAL_API_KEY = originalEnv;
+ } else {
+ delete process.env.MISTRAL_API_KEY;
+ }
+ sinon.restore();
+ });
+
+ describe("MCP Tool Registration", () => {
+ it("should register the document-to-markdown tool", async () => {
+ const tools = await mockMcpClient.listTools().then((t) => t.tools);
+
+ expect(tools.some((t) => t.name === "document-to-markdown")).to.equal(
+ true,
+ );
+ });
+
+ it("should register exactly 1 tool", async () => {
+ const tools = await mockMcpClient.listTools().then((t) => t.tools);
+
+ expect(tools.length).to.equal(1);
+ });
+
+ it("should have correct tool configuration", async () => {
+ const tools = await mockMcpClient.listTools().then((t) => t.tools);
+ const tool = tools.find((t) => t.name === "document-to-markdown");
+
+ expect(tool).to.not.equal(undefined);
+ expect(tool!.title).to.equal("Document to Markdown");
+ expect(tool!.description).to.include("PDF");
+ expect(tool!.description).to.include("DOCX");
+ expect(tool!.description).to.include("PPTX");
+ expect(tool!.description).to.include("provider");
+ expect(tool!.inputSchema).to.not.equal(undefined);
+ });
+
+ it("should have correct input schema", async () => {
+ const tools = await mockMcpClient.listTools().then((t) => t.tools);
+ const tool = tools.find((t) => t.name === "document-to-markdown");
+
+ expect(tool!.inputSchema).to.be.an("object");
+ const schema = tool!.inputSchema as any;
+ expect(schema.properties).to.have.property("blobId");
+ expect(schema.properties).to.have.property("fileBase64");
+ expect(schema.properties).to.have.property("filename");
+ expect(schema.properties).to.have.property("options");
+ });
+ });
+
+ describe("Provider Registry", () => {
+ it("should list available providers", () => {
+ const providers = getAvailableProviders();
+ expect(providers).to.include("mistral");
+ expect(providers).to.include("unpdf");
+ expect(providers).to.be.an("array");
+ });
+
+ it("should check provider availability", () => {
+ expect(isProviderAvailable("mistral")).to.equal(true);
+ expect(isProviderAvailable("unpdf")).to.equal(true);
+ expect(isProviderAvailable("unknown")).to.equal(false);
+ });
+
+ it("should throw for unknown provider", () => {
+ expect(() => createProvider("unknown")).to.throw(
+ /Unknown document conversion provider/,
+ );
+ });
+
+ it("should create mistral provider when API key is set", () => {
+ process.env.MISTRAL_API_KEY = "test-api-key";
+ const provider = createProvider("mistral");
+ expect(provider.name).to.equal("mistral");
+ });
+
+ it("should throw when mistral API key is missing", () => {
+ delete process.env.MISTRAL_API_KEY;
+ expect(() => createProvider("mistral")).to.throw(/MISTRAL_API_KEY/);
+ });
+
+ it("should create unpdf provider without config", () => {
+ const provider = createProvider("unpdf");
+ expect(provider.name).to.equal("unpdf");
+ });
+ });
+
+ describe("Custom Plugin Configuration", () => {
+ it("should accept custom provider via config", async () => {
+ const customPlugin = createDocumentToMarkdownPlugin({
+ provider: createMockProvider(),
+ });
+
+ const { server, client, connect } = await createMcpServerClientPair();
+ customPlugin(mockDkgContext, server, express.Router());
+ await connect();
+
+ const tools = await client.listTools().then((t) => t.tools);
+ expect(tools.some((t) => t.name === "document-to-markdown")).to.equal(
+ true,
+ );
+ });
+
+ it("should use custom provider for conversion", async () => {
+ const mockProvider = createMockProvider({
+ convert: sinon.stub().resolves({
+ markdown: "# Mock Converted Content",
+ images: [],
+ pageCount: 3,
+ processedPageCount: 3,
+ }),
+ });
+
+ const customPlugin = createDocumentToMarkdownPlugin({
+ provider: mockProvider,
+ });
+
+ const { server, client, connect } = await createMcpServerClientPair();
+ const freshBlobStorage = createInMemoryBlobStorage();
+ customPlugin(
+ { dkg: createMockDkgClient(), blob: freshBlobStorage },
+ server,
+ express.Router(),
+ );
+ await connect();
+
+ const result = await client.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: "test.pdf",
+ fileBase64: "dGVzdCBjb250ZW50",
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ expect(text).to.include("Mock Converted Content");
+ expect(text).to.include("Total Pages:** 3");
+ expect(text).to.include("Pages Processed:** 3");
+ expect(mockProvider.convert.calledOnce).to.equal(true);
+ });
+ });
+
+ describe("Input Validation", () => {
+ it("should fail when neither blobId nor fileBase64 is provided", async () => {
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: { filename: "test.pdf" },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ expect(text).to.include("Either 'blobId' or 'fileBase64' must be provided");
+ });
+
+ it("should fail when both blobId and fileBase64 are provided", async () => {
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: "test.pdf",
+ blobId: "some-blob-id",
+ fileBase64: "c29tZS1jb250ZW50",
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ expect(text).to.include("Provide either 'blobId' or 'fileBase64', not both");
+ });
+
+ it("should fail for unsupported file types", async () => {
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: "test.txt",
+ fileBase64: "c29tZS1jb250ZW50",
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ expect(text).to.include("Unsupported file type");
+ expect(text).to.include(".txt");
+ });
+
+ it("should fail for files without extension", async () => {
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: "testfile",
+ fileBase64: "c29tZS1jb250ZW50",
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ expect(text).to.include("Unsupported file type");
+ });
+
+ it("should fail when blob is not found", async () => {
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: "test.pdf",
+ blobId: "non-existent-blob-id",
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ expect(text).to.include("Document blob not found");
+ });
+ });
+
+ describe("Provider Initialization", () => {
+ it("should initialize plugin without any env vars (unpdf default)", async () => {
+ delete process.env.MISTRAL_API_KEY;
+
+ const plugin = createDocumentToMarkdownPlugin();
+ const { server } = await createMcpServerClientPair();
+ expect(() =>
+ plugin(mockDkgContext, server, express.Router()),
+ ).to.not.throw();
+ });
+
+ it("should require MISTRAL_API_KEY when explicitly selecting mistral", async () => {
+ delete process.env.MISTRAL_API_KEY;
+
+ const plugin = createDocumentToMarkdownPlugin({
+ providerName: "mistral",
+ });
+ const { server } = await createMcpServerClientPair();
+ expect(() =>
+ plugin(mockDkgContext, server, express.Router()),
+ ).to.throw(/MISTRAL_API_KEY/);
+ });
+
+ it("should initialize plugin when MISTRAL_API_KEY is set and mistral selected", async () => {
+ process.env.MISTRAL_API_KEY = "test-api-key";
+
+ const plugin = createDocumentToMarkdownPlugin({
+ providerName: "mistral",
+ });
+ const { server } = await createMcpServerClientPair();
+ expect(() =>
+ plugin(mockDkgContext, server, express.Router()),
+ ).to.not.throw();
+ });
+ });
+
+ describe("File Type Validation", () => {
+ const supportedExtensions = [".pdf", ".docx", ".pptx"];
+ const unsupportedExtensions = [".txt", ".doc", ".xls", ".jpg", ".png"];
+
+ for (const ext of supportedExtensions) {
+ it(`should accept ${ext} files`, async () => {
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: `test${ext}`,
+ fileBase64: "c29tZS1jb250ZW50",
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ // Should NOT contain "Unsupported file type" - mock provider handles conversion
+ expect(text).to.not.include("Unsupported file type");
+ });
+ }
+
+ for (const ext of unsupportedExtensions) {
+ it(`should reject ${ext} files`, async () => {
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: `test${ext}`,
+ fileBase64: "c29tZS1jb250ZW50",
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ expect(text).to.include("Unsupported file type");
+ });
+ }
+ });
+
+ describe("File Size Validation", () => {
+ it("should reject files larger than 50MB", async () => {
+ // Create a buffer > 50MB, then base64-encode it for the tool input.
+ // The size check validates the decoded byte length, not the base64 string length.
+ const largeSizeBytes = 51 * 1024 * 1024; // 51MB decoded, exceeds the 50MB limit
+ const largeBuffer = Buffer.alloc(largeSizeBytes, "x");
+ const largeBase64 = largeBuffer.toString("base64");
+
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: "large-file.pdf",
+ fileBase64: largeBase64,
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ expect(text).to.include("exceeds maximum of 50MB");
+ });
+ });
+
+ describe("Blob Integration", () => {
+ it("should read document from blob storage", async () => {
+ // Create a test blob
+ const testContent = Buffer.from("test pdf content");
+ const { id: blobId } = await mockDkgContext.blob.create(
+ Readable.toWeb(Readable.from(testContent)),
+ { name: "test.pdf", mimeType: "application/pdf" },
+ );
+
+ const result = await mockMcpClient.callTool({
+ name: "document-to-markdown",
+ arguments: {
+ filename: "test.pdf",
+ blobId: blobId,
+ },
+ });
+
+ expect(result.content).to.be.an("array");
+ const text = (result.content as any[])[0].text;
+ // Should not fail with "Document blob not found" - blob was read successfully
+ expect(text).to.not.include("Document blob not found");
+ });
+ });
+
+ describe("REST API /document-to-markdown", () => {
+ it("should convert an uploaded PDF successfully", async () => {
+ const pdfBuffer = await createTestPdf(["REST API test page"]);
+
+ const res = await request(app)
+ .post("/document-to-markdown")
+ .attach("file", pdfBuffer, "test.pdf")
+ .expect(200);
+
+ expect(res.body).to.have.property("markdown");
+ expect(res.body).to.have.property("markdownBlobId");
+ expect(res.body).to.have.property("outputFolderId");
+ expect(res.body).to.have.property("pageCount");
+ expect(res.body).to.have.property("processedPageCount");
+ expect(res.body).to.have.property("images");
+ expect(res.body.images).to.be.an("array");
+ expect(res.body.processedPageCount).to.equal(res.body.pageCount);
+ });
+
+ it("should return 400 when multiple files are provided", async () => {
+ const firstPdf = await createTestPdf(["First PDF"]);
+ const secondPdf = await createTestPdf(["Second PDF"]);
+
+ const res = await request(app)
+ .post("/document-to-markdown")
+ .attach("file", firstPdf, "first.pdf")
+ .attach("file", secondPdf, "second.pdf")
+ .expect(400);
+
+ expect(res.body).to.have.property("error");
+ expect(res.body.error).to.include(
+ "Exactly one file must be provided in the request",
+ );
+ });
+
+ it("should return 400 when no file is provided", async () => {
+ // Send as multipart but without attaching any file
+ const res = await request(app)
+ .post("/document-to-markdown")
+ .set("Content-Type", "multipart/form-data; boundary=----test")
+ .send("------test--\r\n");
+
+ expect(res.status).to.equal(400);
+ expect(res.body).to.have.property("error");
+ });
+
+ it("should return 400 for invalid non-multipart requests", async () => {
+ const res = await request(app)
+ .post("/document-to-markdown")
+ .set("Content-Type", "application/json")
+ .send({ filename: "test.pdf" })
+ .expect(400);
+
+ expect(res.body).to.deep.equal({
+ error: "Invalid multipart request.",
+ });
+ });
+
+ it("should return 400 for unsupported file types", async () => {
+ const textBuffer = Buffer.from("plain text content");
+
+ const res = await request(app)
+ .post("/document-to-markdown")
+ .attach("file", textBuffer, "notes.txt")
+ .expect(400);
+
+ expect(res.body).to.have.property("error");
+ expect(res.body.error).to.include("Unsupported file type");
+ });
+
+ it("should return 500 for unexpected provider failures", async () => {
+ const providerFailure = createMockProvider({
+ convert: sinon
+ .stub()
+ .rejects(new Error("Unexpected provider runtime failure")),
+ });
+
+ const failingPlugin = createDocumentToMarkdownPlugin({
+ provider: providerFailure,
+ });
+
+ const { server, connect } = await createMcpServerClientPair();
+ const failingRouter = express.Router();
+ const failingApp = createExpressApp();
+ const failingContext = {
+ dkg: createMockDkgClient(),
+ blob: createInMemoryBlobStorage(),
+ };
+
+ failingPlugin(failingContext, server, failingRouter);
+ await connect();
+ failingApp.use("/", failingRouter);
+
+ const pdfBuffer = await createTestPdf(["Provider failure test page"]);
+ const res = await request(failingApp)
+ .post("/document-to-markdown")
+ .attach("file", pdfBuffer, "test.pdf")
+ .expect(500);
+
+ expect(res.body).to.have.property("error");
+ expect(res.body.error).to.include("Unexpected provider runtime failure");
+ });
+
+ it("should return 413 for oversized files", async () => {
+ // Create a buffer > 50MB
+ const largeSizeBytes = 51 * 1024 * 1024;
+ const largeBuffer = Buffer.alloc(largeSizeBytes, "x");
+
+ const res = await request(app)
+ .post("/document-to-markdown")
+ .attach("file", largeBuffer, "huge.pdf")
+ .expect(413);
+
+ expect(res.body).to.have.property("error");
+ expect(res.body.error).to.include("exceeds maximum of 50MB");
+ });
+ });
+
+ describe("UnpdfProvider", () => {
+ let provider: InstanceType;
+
+ beforeEach(() => {
+ provider = createUnpdfProvider();
+ });
+
+ describe("Format Rejection", () => {
+ it("should reject .docx files", async () => {
+ const buffer = Buffer.from("fake docx content");
+ try {
+ await provider.convert(buffer, "document.docx");
+ expect.fail("should have thrown");
+ } catch (err: any) {
+ expect(err.message).to.include("only supports .pdf");
+ expect(err.message).to.include("Mistral");
+ }
+ });
+
+ it("should reject .pptx files", async () => {
+ const buffer = Buffer.from("fake pptx content");
+ try {
+ await provider.convert(buffer, "presentation.pptx");
+ expect.fail("should have thrown");
+ } catch (err: any) {
+ expect(err.message).to.include("only supports .pdf");
+ expect(err.message).to.include("Mistral");
+ }
+ });
+
+ it("should reject files without extension", async () => {
+ const buffer = Buffer.from("no extension");
+ try {
+ await provider.convert(buffer, "noextension");
+ expect.fail("should have thrown");
+ } catch (err: any) {
+ expect(err.message).to.include("only supports .pdf");
+ }
+ });
+ });
+
+ describe("PDF Conversion", () => {
+ it("should convert a simple PDF to markdown", async () => {
+ const pdfBuffer = await createTestPdf([
+ "Hello from page one",
+ "Hello from page two",
+ ]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf");
+
+ expect(result.markdown).to.include("Hello from page one");
+ expect(result.markdown).to.include("Hello from page two");
+ });
+
+ it("should return correct pageCount", async () => {
+ const pdfBuffer = await createTestPdf(["Page 1", "Page 2", "Page 3"]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf");
+
+ expect(result.pageCount).to.equal(3);
+ expect(result.processedPageCount).to.equal(3);
+ });
+
+ it("should include page separators in output", async () => {
+ const pdfBuffer = await createTestPdf(["First", "Second"]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf");
+
+ expect(result.markdown).to.include("");
+ expect(result.markdown).to.include("");
+ });
+
+ it("should return empty images array", async () => {
+ const pdfBuffer = await createTestPdf(["Some text"]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf");
+
+ expect(result.images).to.deep.equal([]);
+ });
+
+ it("should respect pageStart/pageEnd options", async () => {
+ const pdfBuffer = await createTestPdf([
+ "Page one text",
+ "Page two text",
+ "Page three text",
+ ]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf", {
+ pageStart: 2,
+ pageEnd: 2,
+ });
+
+ expect(result.markdown).to.include("Page two text");
+ expect(result.markdown).to.not.include("Page one text");
+ expect(result.markdown).to.not.include("Page three text");
+ // Page separator should reflect the actual page number
+ expect(result.markdown).to.include("");
+ // Total pageCount should still be the full document count
+ expect(result.pageCount).to.equal(3);
+ expect(result.processedPageCount).to.equal(1);
+ });
+
+ it("should handle pageStart only (no pageEnd)", async () => {
+ const pdfBuffer = await createTestPdf([
+ "Page one text",
+ "Page two text",
+ "Page three text",
+ ]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf", {
+ pageStart: 2,
+ });
+
+ expect(result.markdown).to.not.include("Page one text");
+ expect(result.markdown).to.include("Page two text");
+ expect(result.markdown).to.include("Page three text");
+ expect(result.markdown).to.include("");
+ expect(result.markdown).to.include("");
+ expect(result.processedPageCount).to.equal(2);
+ });
+
+ it("should handle pageEnd only (no pageStart)", async () => {
+ const pdfBuffer = await createTestPdf([
+ "Page one text",
+ "Page two text",
+ "Page three text",
+ ]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf", {
+ pageEnd: 2,
+ });
+
+ expect(result.markdown).to.include("Page one text");
+ expect(result.markdown).to.include("Page two text");
+ expect(result.markdown).to.not.include("Page three text");
+ expect(result.markdown).to.include("");
+ expect(result.markdown).to.include("");
+ expect(result.processedPageCount).to.equal(2);
+ });
+
+ it("should normalize non-integer page bounds", async () => {
+ const pdfBuffer = await createTestPdf([
+ "Page one text",
+ "Page two text",
+ "Page three text",
+ ]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf", {
+ pageStart: 2.9,
+ pageEnd: 3.1,
+ });
+
+ expect(result.markdown).to.not.include("Page one text");
+ expect(result.markdown).to.include("Page two text");
+ expect(result.markdown).to.include("Page three text");
+ expect(result.markdown).to.include("");
+ expect(result.markdown).to.include("");
+ expect(result.processedPageCount).to.equal(2);
+ });
+
+ it("should convert single-page PDF", async () => {
+ const pdfBuffer = await createTestPdf(["Only page"]);
+
+ const result = await provider.convert(pdfBuffer, "test.pdf");
+
+ expect(result.markdown).to.include("Only page");
+ expect(result.markdown).to.include("");
+ expect(result.pageCount).to.equal(1);
+ expect(result.processedPageCount).to.equal(1);
+ });
+ });
+ });
+
+ describe("MistralProvider Helpers", () => {
+ it("should preserve source page numbers when start page offset is provided", () => {
+ const markdown = formatOcrResponseAsMarkdown(
+ {
+ pages: [{ markdown: "Second page" }, { markdown: "Third page" }],
+ } as any,
+ 2,
+ );
+
+ expect(markdown).to.include("## Page 2");
+ expect(markdown).to.include("## Page 3");
+ expect(markdown).to.not.include("## Page 1");
+ });
+ });
+
+ describe("Page Range Helpers", () => {
+ it("should return full range when no filter is requested", () => {
+ const result = normalizePageRange(5);
+
+ expect(result).to.deep.equal({
+ startPage: 1,
+ endPage: 5,
+ hasPageFilter: false,
+ });
+ });
+
+ it("should clamp and normalize invalid page boundaries", () => {
+ const result = normalizePageRange(3, { pageStart: -5, pageEnd: 99 });
+
+ expect(result).to.deep.equal({
+ startPage: 1,
+ endPage: 3,
+ hasPageFilter: true,
+ });
+ });
+
+ it("should normalize non-integer page bounds to integers", () => {
+ const result = normalizePageRange(5, {
+ pageStart: 2.9,
+ pageEnd: 4.2,
+ });
+
+ expect(result).to.deep.equal({
+ startPage: 2,
+ endPage: 4,
+ hasPageFilter: true,
+ });
+ });
+
+ it("should handle empty documents without negative bounds", () => {
+ const result = normalizePageRange(0, { pageStart: 5, pageEnd: 10 });
+
+ expect(result).to.deep.equal({
+ startPage: 1,
+ endPage: 0,
+ hasPageFilter: true,
+ });
+ });
+ });
+
+ describe("Error Classification Helpers", () => {
+ it("should preserve validation status codes", () => {
+ const result = classifyConversionError(
+ new DocumentValidationError("Too big", 413),
+ );
+
+ expect(result).to.deep.equal({
+ status: 413,
+ message: "Too big",
+ isUserError: true,
+ });
+ });
+
+ it("should classify provider format constraints as user errors", () => {
+ const result = classifyConversionError(
+ new Error("The unpdf provider only supports .pdf files"),
+ );
+
+ expect(result.status).to.equal(400);
+ expect(result.isUserError).to.equal(true);
+ });
+
+ it("should classify unexpected failures as internal errors", () => {
+ const result = classifyConversionError(
+ new Error("Unexpected provider runtime failure"),
+ );
+
+ expect(result.status).to.equal(500);
+ expect(result.isUserError).to.equal(false);
+ });
+ });
+});