From 60b8a6b9a28267f5e42ba0713d90851474833290 Mon Sep 17 00:00:00 2001 From: Nik-Kras Date: Tue, 20 Jan 2026 11:12:29 +0000 Subject: [PATCH] fix: add .js extensions for Node.js ESM compatibility The package fails with ERR_MODULE_NOT_FOUND on Node.js because: - package.json has "type": "module" (ESM) - tsconfig.json used "moduleResolution": "bundler" which allows extensionless imports - tsc compiles without adding .js extensions - Node.js ESM requires explicit .js extensions Changes: - Update tsconfig.json: module/moduleResolution to NodeNext - Remove paths alias (incompatible with NodeNext at runtime) - Add .js extensions to all relative imports - Convert @/* path aliases to relative paths with .js Co-Authored-By: Claude Opus 4.5 --- src/diagram/create.ts | 6 +++--- src/diagram/delete.ts | 2 +- src/diagram/format.ts | 2 +- src/diagram/parse.ts | 6 +++--- src/diagram/primitives.ts | 2 +- src/diagram/query.ts | 4 ++-- src/diagram/tests/create.test.ts | 6 +++--- src/diagram/tests/format.test.ts | 4 ++-- src/diagram/tests/query.test.ts | 4 ++-- src/diagram/types.ts | 2 +- src/index.ts | 2 +- src/tools/handlers/createEdge.ts | 10 +++++----- src/tools/handlers/createNode.ts | 10 +++++----- src/tools/handlers/deleteElement.ts | 8 ++++---- src/tools/handlers/getFullDiagramState.ts | 8 ++++---- src/tools/handlers/types.ts | 2 +- src/tools/index.ts | 12 ++++++------ src/tools/middleware.ts | 4 ++-- src/utils/emoji.ts | 2 +- src/utils/tests/emoji.test.ts | 2 +- tsconfig.json | 10 +++------- 21 files changed, 52 insertions(+), 56 deletions(-) diff --git a/src/diagram/create.ts b/src/diagram/create.ts index 8e55c79..3973a5a 100644 --- a/src/diagram/create.ts +++ b/src/diagram/create.ts @@ -1,12 +1,12 @@ -import type { ColorPreset, EdgeStyle, ShapeType } from '@/tools/schemas'; +import type { ColorPreset, EdgeStyle, ShapeType } from '../tools/schemas.js'; import { colorPresets, createBaseElement, estimateTextHeight, estimateTextWidth, generateId, -} from './primitives'; -import { ElementType, type ExcalidrawElement } from './types'; +} from './primitives.js'; +import { ElementType, type ExcalidrawElement } from './types.js'; export type CreateNodeOptions = { label: string; diff --git a/src/diagram/delete.ts b/src/diagram/delete.ts index a7844c5..255d21c 100644 --- a/src/diagram/delete.ts +++ b/src/diagram/delete.ts @@ -1,4 +1,4 @@ -import type { ExcalidrawElement } from './types'; +import type { ExcalidrawElement } from './types.js'; export function deleteElementById( elements: ExcalidrawElement[], diff --git a/src/diagram/format.ts b/src/diagram/format.ts index 650be0b..e42a108 100644 --- a/src/diagram/format.ts +++ b/src/diagram/format.ts @@ -1,4 +1,4 @@ -import type { Diagram, Node } from './types'; +import type { Diagram, Node } from './types.js'; enum ItemType { Edge = 'edge', diff --git a/src/diagram/parse.ts b/src/diagram/parse.ts index 8db901c..fa37f46 100644 --- a/src/diagram/parse.ts +++ b/src/diagram/parse.ts @@ -1,6 +1,6 @@ -import { shapeEnum } from '@/tools/schemas'; -import { emojiForColorAndShape } from '@/utils/emoji'; -import { ElementType, type Diagram, type NodeShape } from './types'; +import { shapeEnum } from '../tools/schemas.js'; +import { emojiForColorAndShape } from '../utils/emoji.js'; +import { ElementType, type Diagram, type NodeShape } from './types.js'; const nodeTypes: Set = new Set([ ...shapeEnum.options, diff --git a/src/diagram/primitives.ts b/src/diagram/primitives.ts index b7a16ad..530c145 100644 --- a/src/diagram/primitives.ts +++ b/src/diagram/primitives.ts @@ -1,4 +1,4 @@ -import type { ColorPreset } from '@/tools/schemas'; +import type { ColorPreset } from '../tools/schemas.js'; type ColorConfig = { backgroundColor: string; diff --git a/src/diagram/query.ts b/src/diagram/query.ts index c426272..4589478 100644 --- a/src/diagram/query.ts +++ b/src/diagram/query.ts @@ -1,5 +1,5 @@ -import { shapeEnum } from '@/tools/schemas'; -import type { ExcalidrawElement } from './types'; +import { shapeEnum } from '../tools/schemas.js'; +import type { ExcalidrawElement } from './types.js'; export const findNodeById = ( elements: ExcalidrawElement[], diff --git a/src/diagram/tests/create.test.ts b/src/diagram/tests/create.test.ts index c849a73..6bcf6c3 100644 --- a/src/diagram/tests/create.test.ts +++ b/src/diagram/tests/create.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { Assert } from '@/utils/assert'; -import { createEdgeElements, createNodeElements } from '../create'; -import type { ExcalidrawElement } from '../types'; +import { Assert } from '../../utils/assert.js'; +import { createEdgeElements, createNodeElements } from '../create.js'; +import type { ExcalidrawElement } from '../types.js'; function makeNode( id: string, diff --git a/src/diagram/tests/format.test.ts b/src/diagram/tests/format.test.ts index 4b587b0..2dd0700 100644 --- a/src/diagram/tests/format.test.ts +++ b/src/diagram/tests/format.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { formatDiagramMarkdown } from '../format'; -import type { Diagram, Node } from '../types'; +import { formatDiagramMarkdown } from '../format.js'; +import type { Diagram, Node } from '../types.js'; function makeNode(id: string, label: string | null = null): Node { return { diff --git a/src/diagram/tests/query.test.ts b/src/diagram/tests/query.test.ts index 08f6d62..16346e0 100644 --- a/src/diagram/tests/query.test.ts +++ b/src/diagram/tests/query.test.ts @@ -3,8 +3,8 @@ import { calculateNextPosition, resolveNode, resolveNodeByRole, -} from '../query'; -import type { ExcalidrawElement } from '../types'; +} from '../query.js'; +import type { ExcalidrawElement } from '../types.js'; function makeNode( id: string, diff --git a/src/diagram/types.ts b/src/diagram/types.ts index dca9fef..440a072 100644 --- a/src/diagram/types.ts +++ b/src/diagram/types.ts @@ -1,4 +1,4 @@ -import type { ShapeType } from '@/tools/schemas'; +import type { ShapeType } from '../tools/schemas.js'; export enum ElementType { Arrow = 'arrow', diff --git a/src/index.ts b/src/index.ts index 579ad12..e0c3c13 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; -import { registerAllTools } from './tools/index'; +import { registerAllTools } from './tools/index.js'; const argv = yargs(hideBin(process.argv)) .option('diagram', { diff --git a/src/tools/handlers/createEdge.ts b/src/tools/handlers/createEdge.ts index 3c75831..1e262c5 100644 --- a/src/tools/handlers/createEdge.ts +++ b/src/tools/handlers/createEdge.ts @@ -1,8 +1,8 @@ -import { createEdgeElements } from '@/diagram/create'; -import { resolveNodeByRole } from '@/diagram/query'; -import type { ExcalidrawFile } from '@/diagram/types'; -import type { EdgeStyle } from '@/tools/schemas'; -import type { WriteHandlerResult } from './types'; +import { createEdgeElements } from '../../diagram/create.js'; +import { resolveNodeByRole } from '../../diagram/query.js'; +import type { ExcalidrawFile } from '../../diagram/types.js'; +import type { EdgeStyle } from '../schemas.js'; +import type { WriteHandlerResult } from './types.js'; interface CreateEdgeArgs { from: string; diff --git a/src/tools/handlers/createNode.ts b/src/tools/handlers/createNode.ts index 830b611..b7ce3be 100644 --- a/src/tools/handlers/createNode.ts +++ b/src/tools/handlers/createNode.ts @@ -1,8 +1,8 @@ -import { type CreateNodeOptions, createNodeElements } from '@/diagram/create'; -import { calculateNextPosition } from '@/diagram/query'; -import type { ExcalidrawFile } from '@/diagram/types'; -import type { WriteHandlerResult } from './types'; -import type { ColorPreset, ShapeType } from '@/tools/schemas'; +import { type CreateNodeOptions, createNodeElements } from '../../diagram/create.js'; +import { calculateNextPosition } from '../../diagram/query.js'; +import type { ExcalidrawFile } from '../../diagram/types.js'; +import type { WriteHandlerResult } from './types.js'; +import type { ColorPreset, ShapeType } from '../schemas.js'; interface CreateNodeArgs { label: string; diff --git a/src/tools/handlers/deleteElement.ts b/src/tools/handlers/deleteElement.ts index 6e53bdb..9743296 100644 --- a/src/tools/handlers/deleteElement.ts +++ b/src/tools/handlers/deleteElement.ts @@ -1,7 +1,7 @@ -import { deleteElementById } from '@/diagram/delete'; -import { resolveNode } from '@/diagram/query'; -import type { ExcalidrawFile } from '@/diagram/types'; -import type { WriteHandlerResult } from './types'; +import { deleteElementById } from '../../diagram/delete.js'; +import { resolveNode } from '../../diagram/query.js'; +import type { ExcalidrawFile } from '../../diagram/types.js'; +import type { WriteHandlerResult } from './types.js'; interface DeleteElementArgs { id: string; diff --git a/src/tools/handlers/getFullDiagramState.ts b/src/tools/handlers/getFullDiagramState.ts index 96e7964..eef08cf 100644 --- a/src/tools/handlers/getFullDiagramState.ts +++ b/src/tools/handlers/getFullDiagramState.ts @@ -1,7 +1,7 @@ -import { formatDiagramMarkdown } from '@/diagram/format'; -import { parseDiagram } from '@/diagram/parse'; -import type { ExcalidrawFile } from '@/diagram/types'; -import type { ReadHandlerResult } from './types'; +import { formatDiagramMarkdown } from '../../diagram/format.js'; +import { parseDiagram } from '../../diagram/parse.js'; +import type { ExcalidrawFile } from '../../diagram/types.js'; +import type { ReadHandlerResult } from './types.js'; export function getFullDiagramState(file: ExcalidrawFile): ReadHandlerResult { const diagram = parseDiagram(file); diff --git a/src/tools/handlers/types.ts b/src/tools/handlers/types.ts index 0ee93e4..83e599d 100644 --- a/src/tools/handlers/types.ts +++ b/src/tools/handlers/types.ts @@ -1,4 +1,4 @@ -import type { ExcalidrawFile } from '@/diagram/types'; +import type { ExcalidrawFile } from '../../diagram/types.js'; export type ReadHandlerResult = | { ok: true; message: string } diff --git a/src/tools/index.ts b/src/tools/index.ts index fefe82a..d92ddde 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,12 +1,12 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; -import { createEdge } from './handlers/createEdge'; -import { createNode } from './handlers/createNode'; -import { deleteElement } from './handlers/deleteElement'; -import { getFullDiagramState } from './handlers/getFullDiagramState'; -import { withDiagramRead, withDiagramWrite } from './middleware'; -import { colorEnum, edgeStyleEnum, shapeEnum } from './schemas'; +import { createEdge } from './handlers/createEdge.js'; +import { createNode } from './handlers/createNode.js'; +import { deleteElement } from './handlers/deleteElement.js'; +import { getFullDiagramState } from './handlers/getFullDiagramState.js'; +import { withDiagramRead, withDiagramWrite } from './middleware.js'; +import { colorEnum, edgeStyleEnum, shapeEnum } from './schemas.js'; export function registerAllTools(server: McpServer, diagramPath: string) { server.registerTool( diff --git a/src/tools/middleware.ts b/src/tools/middleware.ts index c051d62..9028188 100644 --- a/src/tools/middleware.ts +++ b/src/tools/middleware.ts @@ -2,8 +2,8 @@ import fs from 'node:fs/promises'; import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; -import type { ExcalidrawFile } from '@/diagram/types'; -import type { ReadHandlerResult, WriteHandlerResult } from './handlers/types'; +import type { ExcalidrawFile } from '../diagram/types.js'; +import type { ReadHandlerResult, WriteHandlerResult } from './handlers/types.js'; async function loadDiagram(path: string): Promise { const content = await fs.readFile(path, 'utf8'); diff --git a/src/utils/emoji.ts b/src/utils/emoji.ts index d9dae07..a638d39 100644 --- a/src/utils/emoji.ts +++ b/src/utils/emoji.ts @@ -1,4 +1,4 @@ -import type { ShapeType } from '@/tools/schemas'; +import type { ShapeType } from '../tools/schemas.js'; type ColorFamily = 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'purple'; diff --git a/src/utils/tests/emoji.test.ts b/src/utils/tests/emoji.test.ts index bf15a75..dddcbf8 100644 --- a/src/utils/tests/emoji.test.ts +++ b/src/utils/tests/emoji.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { emojiForColorAndShape } from '../emoji'; +import { emojiForColorAndShape } from '../emoji.js'; describe('emojiForColorAndShape', () => { it('returns correct emoji for each color family', () => { diff --git a/tsconfig.json b/tsconfig.json index eec92c5..980c779 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { "target": "ESNext", - "module": "ESNext", - "moduleResolution": "bundler", + "module": "NodeNext", + "moduleResolution": "NodeNext", "strict": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, @@ -10,11 +10,7 @@ "resolveJsonModule": true, "outDir": "dist", "rootDir": "src", - "types": ["node"], - "baseUrl": ".", - "paths": { - "@/*": ["src/*"] - } + "types": ["node"] }, "include": ["src/**/*.ts"] }