diff --git a/Dockerfile.backend b/Dockerfile.backend index f0a506e6..79057367 100644 --- a/Dockerfile.backend +++ b/Dockerfile.backend @@ -1,52 +1,25 @@ -# Build stage for the backend service in monorepo -FROM node:22-alpine AS builder - -WORKDIR /app - -# Copy package files for all workspaces -COPY package*.json ./ -COPY packages/shared-schema/package*.json ./packages/shared-schema/ -COPY packages/db/package*.json ./packages/db/ -COPY packages/aurora-sync/package*.json ./packages/aurora-sync/ -COPY packages/backend/package*.json ./packages/backend/ - -# Install all dependencies (including workspace dependencies) -RUN npm ci - -# Copy source code for shared-schema, db, aurora-sync, and backend -COPY packages/shared-schema ./packages/shared-schema -COPY packages/db ./packages/db -COPY packages/aurora-sync ./packages/aurora-sync -COPY packages/backend ./packages/backend - -# Build in dependency order: shared-schema -> db -> aurora-sync -> backend -RUN npm run build --workspace=@boardsesh/shared-schema -RUN npm run build --workspace=@boardsesh/db -RUN npm run build --workspace=@boardsesh/aurora-sync -RUN npm run build --workspace=boardsesh-backend - -# Production stage +# Backend service - runs TypeScript directly via tsx FROM node:22-alpine WORKDIR /app -# Copy package files (need full workspace structure for npm to resolve) +# Copy package files for all workspaces COPY package*.json ./ COPY packages/shared-schema/package*.json ./packages/shared-schema/ +COPY packages/crypto/package*.json ./packages/crypto/ COPY packages/db/package*.json ./packages/db/ COPY packages/aurora-sync/package*.json ./packages/aurora-sync/ COPY packages/backend/package*.json ./packages/backend/ -# Copy built shared-schema, db, and aurora-sync dist BEFORE npm ci (so main entry points exist) -COPY --from=builder /app/packages/shared-schema/dist ./packages/shared-schema/dist -COPY --from=builder /app/packages/db/dist ./packages/db/dist -COPY --from=builder /app/packages/aurora-sync/dist ./packages/aurora-sync/dist - -# Install production dependencies only -RUN npm ci --omit=dev --workspace=boardsesh-backend --workspace=@boardsesh/shared-schema --workspace=@boardsesh/db --workspace=@boardsesh/aurora-sync +# Copy source code for all shared packages and backend +COPY packages/shared-schema/src ./packages/shared-schema/src +COPY packages/crypto/src ./packages/crypto/src +COPY packages/db/src ./packages/db/src +COPY packages/aurora-sync/src ./packages/aurora-sync/src +COPY packages/backend/src ./packages/backend/src -# Copy built backend files -COPY --from=builder /app/packages/backend/dist ./packages/backend/dist +# Install production dependencies (tsx is now a production dep for running TypeScript) +RUN npm ci --omit=dev --workspace=boardsesh-backend --workspace=@boardsesh/shared-schema --workspace=@boardsesh/crypto --workspace=@boardsesh/db --workspace=@boardsesh/aurora-sync # Expose port EXPOSE 8080 @@ -55,6 +28,6 @@ EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 -# Start the server +# Start the server using tsx to run TypeScript directly WORKDIR /app/packages/backend -CMD ["node", "dist/index.js"] +CMD ["npx", "tsx", "src/index.ts"] diff --git a/package-lock.json b/package-lock.json index 85097a98..9cdfbdd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7693,7 +7693,6 @@ "version": "4.13.0", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", - "devOptional": true, "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -9447,7 +9446,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "devOptional": true, "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" @@ -10126,7 +10124,6 @@ "version": "4.21.0", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", - "devOptional": true, "license": "MIT", "dependencies": { "esbuild": "~0.27.0", @@ -10154,7 +10151,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=18" } @@ -10171,7 +10167,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -10188,7 +10183,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -10205,7 +10199,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -10222,7 +10215,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=18" } @@ -10239,7 +10231,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=18" } @@ -10256,7 +10247,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -10273,7 +10263,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -10290,7 +10279,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10307,7 +10295,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10324,7 +10311,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10341,7 +10327,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10358,7 +10343,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10375,7 +10359,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10392,7 +10375,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10409,7 +10391,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10426,7 +10407,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -10443,7 +10423,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -10460,7 +10439,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -10477,7 +10455,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -10494,7 +10471,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -10511,7 +10487,6 @@ "os": [ "openharmony" ], - "peer": true, "engines": { "node": ">=18" } @@ -10528,7 +10503,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=18" } @@ -10545,7 +10519,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -10562,7 +10535,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -10579,7 +10551,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -10588,7 +10559,6 @@ "version": "0.27.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", - "devOptional": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -11642,6 +11612,7 @@ "graphql-yoga": "^5.18.0", "ioredis": "^5.4.1", "jose": "^4.15.9", + "tsx": "^4.21.0", "uuid": "^13.0.0", "ws": "^8.18.3", "zod": "^3.24.0" @@ -11654,7 +11625,6 @@ "@types/ws": "^8.18.1", "drizzle-kit": "^0.31.8", "postgres": "^3.4.7", - "tsx": "^4.21.0", "typescript": "^5.9.3", "vitest": "^4.0.16" } diff --git a/packages/aurora-sync/package.json b/packages/aurora-sync/package.json index eb8dcb40..37b8788c 100644 --- a/packages/aurora-sync/package.json +++ b/packages/aurora-sync/package.json @@ -3,15 +3,32 @@ "version": "1.0.0", "description": "Aurora board sync utility for Boardsesh", "type": "module", - "main": "dist/index.js", + "main": "src/index.ts", + "types": "src/index.ts", "bin": { "aurora-sync": "./dist/cli/index.js" }, "exports": { - ".": "./dist/index.js", - "./runner": "./dist/runner/index.js", - "./api": "./dist/api/index.js", - "./sync": "./dist/sync/index.js" + ".": { + "types": "./src/index.ts", + "import": "./src/index.ts", + "default": "./src/index.ts" + }, + "./runner": { + "types": "./src/runner/index.ts", + "import": "./src/runner/index.ts", + "default": "./src/runner/index.ts" + }, + "./api": { + "types": "./src/api/index.ts", + "import": "./src/api/index.ts", + "default": "./src/api/index.ts" + }, + "./sync": { + "types": "./src/sync/index.ts", + "import": "./src/sync/index.ts", + "default": "./src/sync/index.ts" + } }, "scripts": { "dev": "tsx watch src/cli/index.ts", diff --git a/packages/aurora-sync/src/api/aurora-client.ts b/packages/aurora-sync/src/api/aurora-client.ts index adde3b19..474b5568 100644 --- a/packages/aurora-sync/src/api/aurora-client.ts +++ b/packages/aurora-sync/src/api/aurora-client.ts @@ -1,4 +1,4 @@ -import { HOST_BASES, AuroraBoardName, LoginResponse, Session, ClientOptions } from './types.js'; +import { HOST_BASES, AuroraBoardName, LoginResponse, Session, ClientOptions } from './types'; /** * Aurora Climbing API Client diff --git a/packages/aurora-sync/src/api/index.ts b/packages/aurora-sync/src/api/index.ts index d3fbfadd..e32e00fd 100644 --- a/packages/aurora-sync/src/api/index.ts +++ b/packages/aurora-sync/src/api/index.ts @@ -1,5 +1,5 @@ -export * from './types.js'; -export * from './sync-api-types.js'; -export { userSync } from './user-sync-api.js'; -export { sharedSync } from './shared-sync-api.js'; -export { AuroraClimbingClient } from './aurora-client.js'; +export * from './types'; +export * from './sync-api-types'; +export { userSync } from './user-sync-api'; +export { sharedSync } from './shared-sync-api'; +export { AuroraClimbingClient } from './aurora-client'; diff --git a/packages/aurora-sync/src/api/shared-sync-api.ts b/packages/aurora-sync/src/api/shared-sync-api.ts index 2a4f3e54..fd3e56d7 100644 --- a/packages/aurora-sync/src/api/shared-sync-api.ts +++ b/packages/aurora-sync/src/api/shared-sync-api.ts @@ -1,5 +1,5 @@ -import { SyncData } from './sync-api-types.js'; -import { WEB_HOSTS, SyncOptions, AuroraBoardName, SHARED_SYNC_TABLES } from './types.js'; +import { SyncData } from './sync-api-types'; +import { WEB_HOSTS, SyncOptions, AuroraBoardName, SHARED_SYNC_TABLES } from './types'; export async function sharedSync( board: AuroraBoardName, diff --git a/packages/aurora-sync/src/api/user-sync-api.ts b/packages/aurora-sync/src/api/user-sync-api.ts index c898c544..6ced7e1e 100644 --- a/packages/aurora-sync/src/api/user-sync-api.ts +++ b/packages/aurora-sync/src/api/user-sync-api.ts @@ -1,5 +1,5 @@ -import { SyncData } from './sync-api-types.js'; -import { WEB_HOSTS, SyncOptions, AuroraBoardName } from './types.js'; +import { SyncData } from './sync-api-types'; +import { WEB_HOSTS, SyncOptions, AuroraBoardName } from './types'; export async function userSync( board: AuroraBoardName, diff --git a/packages/aurora-sync/src/cli/index.ts b/packages/aurora-sync/src/cli/index.ts index febc064e..cb2420b8 100644 --- a/packages/aurora-sync/src/cli/index.ts +++ b/packages/aurora-sync/src/cli/index.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node import { program } from 'commander'; -import { SyncRunner } from '../runner/sync-runner.js'; +import { SyncRunner } from '../runner/sync-runner'; // Load environment variables from .env files if available import { config } from 'dotenv'; diff --git a/packages/aurora-sync/src/db/table-select.ts b/packages/aurora-sync/src/db/table-select.ts index f75abe4f..fe48f569 100644 --- a/packages/aurora-sync/src/db/table-select.ts +++ b/packages/aurora-sync/src/db/table-select.ts @@ -36,7 +36,7 @@ import { kilterTags, tensionTags, } from '@boardsesh/db/schema/boards'; -import { AuroraBoardName } from '../api/types.js'; +import { AuroraBoardName } from '../api/types'; // Re-export AuroraBoardName as BoardName for backward compatibility within this module export type BoardName = AuroraBoardName; diff --git a/packages/aurora-sync/src/index.ts b/packages/aurora-sync/src/index.ts index 6a877ba8..8cd72d14 100644 --- a/packages/aurora-sync/src/index.ts +++ b/packages/aurora-sync/src/index.ts @@ -1,17 +1,17 @@ // Main exports for @boardsesh/aurora-sync package // API exports -export * from './api/index.js'; +export * from './api/index'; // Sync exports -export * from './sync/index.js'; +export * from './sync/index'; // Runner exports -export * from './runner/index.js'; +export * from './runner/index'; // Crypto exports (re-exported from shared package) export { encrypt, decrypt } from '@boardsesh/crypto'; // DB utilities -export { getTable, getBoardTables, isValidBoardName, getBoardPrefix } from './db/table-select.js'; -export type { TableSet, BoardName } from './db/table-select.js'; +export { getTable, getBoardTables, isValidBoardName, getBoardPrefix } from './db/table-select'; +export type { TableSet, BoardName } from './db/table-select'; diff --git a/packages/aurora-sync/src/runner/index.ts b/packages/aurora-sync/src/runner/index.ts index dc6a23f6..e20711a3 100644 --- a/packages/aurora-sync/src/runner/index.ts +++ b/packages/aurora-sync/src/runner/index.ts @@ -1,2 +1,2 @@ -export { SyncRunner } from './sync-runner.js'; -export type { SyncRunnerConfig, SyncSummary, SyncError, CredentialRecord } from './types.js'; +export { SyncRunner } from './sync-runner'; +export type { SyncRunnerConfig, SyncSummary, SyncError, CredentialRecord } from './types'; diff --git a/packages/aurora-sync/src/runner/sync-runner.ts b/packages/aurora-sync/src/runner/sync-runner.ts index fd5fdc1f..a7c5c46c 100644 --- a/packages/aurora-sync/src/runner/sync-runner.ts +++ b/packages/aurora-sync/src/runner/sync-runner.ts @@ -5,11 +5,11 @@ import { eq, and, or, isNotNull } from 'drizzle-orm'; import ws from 'ws'; import { auroraCredentials } from '@boardsesh/db/schema/auth'; -import { syncUserData } from '../sync/user-sync.js'; -import { AuroraClimbingClient } from '../api/aurora-client.js'; +import { syncUserData } from '../sync/user-sync'; +import { AuroraClimbingClient } from '../api/aurora-client'; import { decrypt, encrypt } from '@boardsesh/crypto'; -import type { AuroraBoardName } from '../api/types.js'; -import type { SyncRunnerConfig, SyncSummary, CredentialRecord } from './types.js'; +import type { AuroraBoardName } from '../api/types'; +import type { SyncRunnerConfig, SyncSummary, CredentialRecord } from './types'; // Configure WebSocket constructor for Node.js environment neonConfig.webSocketConstructor = ws; diff --git a/packages/aurora-sync/src/sync/index.ts b/packages/aurora-sync/src/sync/index.ts index 83448dbc..554264c9 100644 --- a/packages/aurora-sync/src/sync/index.ts +++ b/packages/aurora-sync/src/sync/index.ts @@ -1,3 +1,3 @@ -export { syncUserData, getLastSyncTimes, getLastSharedSyncTimes } from './user-sync.js'; -export type { SyncUserDataResult } from './user-sync.js'; -export { convertQuality } from './convert-quality.js'; +export { syncUserData, getLastSyncTimes, getLastSharedSyncTimes } from './user-sync'; +export type { SyncUserDataResult } from './user-sync'; +export { convertQuality } from './convert-quality'; diff --git a/packages/aurora-sync/src/sync/user-sync.ts b/packages/aurora-sync/src/sync/user-sync.ts index 46bc5364..693c89e0 100644 --- a/packages/aurora-sync/src/sync/user-sync.ts +++ b/packages/aurora-sync/src/sync/user-sync.ts @@ -1,13 +1,13 @@ -import { userSync } from '../api/user-sync-api.js'; -import { SyncOptions, USER_TABLES, UserSyncData, AuroraBoardName } from '../api/types.js'; +import { userSync } from '../api/user-sync-api'; +import { SyncOptions, USER_TABLES, UserSyncData, AuroraBoardName } from '../api/types'; import { eq, and, inArray, sql } from 'drizzle-orm'; import { drizzle } from 'drizzle-orm/neon-serverless'; import type { NeonDatabase } from 'drizzle-orm/neon-serverless'; import type { Pool } from '@neondatabase/serverless'; -import { getTable } from '../db/table-select.js'; +import { getTable } from '../db/table-select'; import { boardseshTicks, playlists, playlistClimbs, playlistOwnership } from '@boardsesh/db/schema/app'; import { randomUUID } from 'crypto'; -import { convertQuality } from './convert-quality.js'; +import { convertQuality } from './convert-quality'; // Batch size for bulk inserts const BATCH_SIZE = 100; diff --git a/packages/backend/package.json b/packages/backend/package.json index 80881190..82b9d860 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "NODE_ENV=development DOTENV_CONFIG_PATH=.env.local tsx watch src/index.ts", "build": "tsc", - "start": "node dist/index.js", + "start": "tsx src/index.ts", "test": "vitest", "test:run": "vitest run", "test:coverage": "vitest run --coverage", @@ -37,6 +37,7 @@ "graphql-yoga": "^5.18.0", "ioredis": "^5.4.1", "jose": "^4.15.9", + "tsx": "^4.21.0", "uuid": "^13.0.0", "ws": "^8.18.3", "zod": "^3.24.0" @@ -49,7 +50,6 @@ "@types/ws": "^8.18.1", "drizzle-kit": "^0.31.8", "postgres": "^3.4.7", - "tsx": "^4.21.0", "typescript": "^5.9.3", "vitest": "^4.0.16" } diff --git a/packages/backend/src/__tests__/climb-queries.test.ts b/packages/backend/src/__tests__/climb-queries.test.ts index b27987cb..7d1f3813 100644 --- a/packages/backend/src/__tests__/climb-queries.test.ts +++ b/packages/backend/src/__tests__/climb-queries.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; -import { searchClimbs, countClimbs, getClimbByUuid } from '../db/queries/climbs/index.js'; -import type { ParsedBoardRouteParameters, ClimbSearchParams } from '../db/queries/climbs/create-climb-filters.js'; -import { getSizeEdges } from '../db/queries/util/product-sizes-data.js'; +import { searchClimbs, countClimbs, getClimbByUuid } from '../db/queries/climbs/index'; +import type { ParsedBoardRouteParameters, ClimbSearchParams } from '../db/queries/climbs/create-climb-filters'; +import { getSizeEdges } from '../db/queries/util/product-sizes-data'; describe('Climb Query Functions', () => { const testParams: ParsedBoardRouteParameters = { diff --git a/packages/backend/src/__tests__/distributed-state.test.ts b/packages/backend/src/__tests__/distributed-state.test.ts index 99907e43..fa8b966b 100644 --- a/packages/backend/src/__tests__/distributed-state.test.ts +++ b/packages/backend/src/__tests__/distributed-state.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from 'vitest'; import Redis from 'ioredis'; -import { DistributedStateManager, forceResetDistributedState } from '../services/distributed-state.js'; +import { DistributedStateManager, forceResetDistributedState } from '../services/distributed-state'; // Integration tests require Redis to be running const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6380'; diff --git a/packages/backend/src/__tests__/graphql-resolvers.test.ts b/packages/backend/src/__tests__/graphql-resolvers.test.ts index 8a0c27f8..8607d6b6 100644 --- a/packages/backend/src/__tests__/graphql-resolvers.test.ts +++ b/packages/backend/src/__tests__/graphql-resolvers.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { createClient, Client } from 'graphql-ws'; import WebSocket from 'ws'; -import { startServer } from '../server.js'; +import { startServer } from '../server'; const TEST_PORT = 8084; // Different port to avoid conflicts diff --git a/packages/backend/src/__tests__/integration.test.ts b/packages/backend/src/__tests__/integration.test.ts index 9fe2b3eb..dcd0c5e6 100644 --- a/packages/backend/src/__tests__/integration.test.ts +++ b/packages/backend/src/__tests__/integration.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeAll, afterAll, afterEach } from 'vitest'; import { createClient, Client } from 'graphql-ws'; import WebSocket from 'ws'; -import { startServer } from '../server.js'; +import { startServer } from '../server'; import type { ClimbQueueItem } from '@boardsesh/shared-schema'; // Test fixtures diff --git a/packages/backend/src/__tests__/queue-sync-fixes.test.ts b/packages/backend/src/__tests__/queue-sync-fixes.test.ts index 960133d7..59267799 100644 --- a/packages/backend/src/__tests__/queue-sync-fixes.test.ts +++ b/packages/backend/src/__tests__/queue-sync-fixes.test.ts @@ -6,13 +6,13 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import Redis from 'ioredis'; import { v4 as uuidv4 } from 'uuid'; -import { roomManager, VersionConflictError } from '../services/room-manager.js'; -import { db } from '../db/client.js'; -import { boardSessions, boardSessionQueues } from '../db/schema.js'; +import { roomManager, VersionConflictError } from '../services/room-manager'; +import { db } from '../db/client'; +import { boardSessions, boardSessionQueues } from '../db/schema'; import { eq } from 'drizzle-orm'; import type { ClimbQueueItem } from '@boardsesh/shared-schema'; -import { queueMutations } from '../graphql/resolvers/queue/mutations.js'; -import { pubsub } from '../pubsub/index.js'; +import { queueMutations } from '../graphql/resolvers/queue/mutations'; +import { pubsub } from '../pubsub/index'; // Mock Redis for testing const createMockRedis = (): Redis & { _store: Map; _hashes: Map> } => { diff --git a/packages/backend/src/__tests__/redis-pubsub.test.ts b/packages/backend/src/__tests__/redis-pubsub.test.ts index 51a2b2cf..fb2ae7ad 100644 --- a/packages/backend/src/__tests__/redis-pubsub.test.ts +++ b/packages/backend/src/__tests__/redis-pubsub.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi } from 'vitest'; import Redis from 'ioredis'; -import { createRedisPubSubAdapter, type RedisPubSubAdapter } from '../pubsub/redis-adapter.js'; +import { createRedisPubSubAdapter, type RedisPubSubAdapter } from '../pubsub/redis-adapter'; import type { QueueEvent, SessionEvent } from '@boardsesh/shared-schema'; // Integration tests require Redis to be running diff --git a/packages/backend/src/__tests__/rest-parity.test.ts b/packages/backend/src/__tests__/rest-parity.test.ts index 4cf19b34..b0aeb847 100644 --- a/packages/backend/src/__tests__/rest-parity.test.ts +++ b/packages/backend/src/__tests__/rest-parity.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; -import { startServer } from '../server.js'; +import { startServer } from '../server'; const BACKEND_PORT = 8083; // Use different port to avoid conflicts with other tests const PUBLIC_API_BASE = 'https://www.boardsesh.com'; diff --git a/packages/backend/src/__tests__/session-persistence.test.ts b/packages/backend/src/__tests__/session-persistence.test.ts index 4ee4a8a1..14f42517 100644 --- a/packages/backend/src/__tests__/session-persistence.test.ts +++ b/packages/backend/src/__tests__/session-persistence.test.ts @@ -1,10 +1,10 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import Redis from 'ioredis'; import { v4 as uuidv4 } from 'uuid'; -import { roomManager } from '../services/room-manager.js'; -import { RedisSessionStore } from '../services/redis-session-store.js'; -import { db } from '../db/client.js'; -import { boardSessions, boardSessionQueues } from '../db/schema.js'; +import { roomManager } from '../services/room-manager'; +import { RedisSessionStore } from '../services/redis-session-store'; +import { db } from '../db/client'; +import { boardSessions, boardSessionQueues } from '../db/schema'; import { eq } from 'drizzle-orm'; import type { ClimbQueueItem } from '@boardsesh/shared-schema'; diff --git a/packages/backend/src/__tests__/setup.ts b/packages/backend/src/__tests__/setup.ts index 138aa28e..1239fe92 100644 --- a/packages/backend/src/__tests__/setup.ts +++ b/packages/backend/src/__tests__/setup.ts @@ -2,8 +2,8 @@ import { beforeAll, beforeEach, afterAll } from 'vitest'; import { drizzle } from 'drizzle-orm/postgres-js'; import postgres from 'postgres'; import { sql } from 'drizzle-orm'; -import * as schema from '../db/schema.js'; -import { roomManager } from '../services/room-manager.js'; +import * as schema from '../db/schema'; +import { roomManager } from '../services/room-manager'; const TEST_DB_NAME = 'boardsesh_backend_test'; const connectionString = diff --git a/packages/backend/src/__tests__/websocket-sync.test.ts b/packages/backend/src/__tests__/websocket-sync.test.ts index d0f5d669..c226027a 100644 --- a/packages/backend/src/__tests__/websocket-sync.test.ts +++ b/packages/backend/src/__tests__/websocket-sync.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { randomUUID } from 'crypto'; -import { roomManager } from '../services/room-manager.js'; -import { db } from '../db/client.js'; -import { sessions, sessionQueues } from '../db/schema.js'; +import { roomManager } from '../services/room-manager'; +import { db } from '../db/client'; +import { sessions, sessionQueues } from '../db/schema'; import type { ClimbQueueItem } from '@boardsesh/shared-schema'; // Generate unique session IDs to prevent conflicts with parallel tests diff --git a/packages/backend/src/db/queries/climbs/count-climbs.ts b/packages/backend/src/db/queries/climbs/count-climbs.ts index e62bc3e9..52c3e5be 100644 --- a/packages/backend/src/db/queries/climbs/count-climbs.ts +++ b/packages/backend/src/db/queries/climbs/count-climbs.ts @@ -1,8 +1,8 @@ import { sql, and } from 'drizzle-orm'; -import { db } from '../../client.js'; -import { getBoardTables } from '../util/table-select.js'; -import { createClimbFilters, type ClimbSearchParams, type ParsedBoardRouteParameters } from './create-climb-filters.js'; -import type { SizeEdges } from '../util/product-sizes-data.js'; +import { db } from '../../client'; +import { getBoardTables } from '../util/table-select'; +import { createClimbFilters, type ClimbSearchParams, type ParsedBoardRouteParameters } from './create-climb-filters'; +import type { SizeEdges } from '../util/product-sizes-data'; /** * Counts the total number of climbs matching the search criteria. diff --git a/packages/backend/src/db/queries/climbs/create-climb-filters.ts b/packages/backend/src/db/queries/climbs/create-climb-filters.ts index ecf539c5..0944930d 100644 --- a/packages/backend/src/db/queries/climbs/create-climb-filters.ts +++ b/packages/backend/src/db/queries/climbs/create-climb-filters.ts @@ -1,6 +1,6 @@ import { eq, gte, sql, like, notLike, inArray, SQL } from 'drizzle-orm'; -import { TableSet, getTableName, type BoardName } from '../util/table-select.js'; -import type { SizeEdges } from '../util/product-sizes-data.js'; +import { TableSet, getTableName, type BoardName } from '../util/table-select'; +import type { SizeEdges } from '../util/product-sizes-data'; export interface ClimbSearchParams { // Pagination diff --git a/packages/backend/src/db/queries/climbs/get-climb.ts b/packages/backend/src/db/queries/climbs/get-climb.ts index 21994190..e6b5972e 100644 --- a/packages/backend/src/db/queries/climbs/get-climb.ts +++ b/packages/backend/src/db/queries/climbs/get-climb.ts @@ -1,6 +1,6 @@ import { sql } from 'drizzle-orm'; -import { db } from '../../client.js'; -import { getBoardTables, type BoardName } from '../util/table-select.js'; +import { db } from '../../client'; +import { getBoardTables, type BoardName } from '../util/table-select'; import type { Climb, LitUpHoldsMap, HoldState } from '@boardsesh/shared-schema'; // Hold state mapping for converting frames string to lit up holds map diff --git a/packages/backend/src/db/queries/climbs/index.ts b/packages/backend/src/db/queries/climbs/index.ts index ff2dc4db..6a461481 100644 --- a/packages/backend/src/db/queries/climbs/index.ts +++ b/packages/backend/src/db/queries/climbs/index.ts @@ -1,4 +1,4 @@ -export { searchClimbs } from './search-climbs.js'; -export { countClimbs } from './count-climbs.js'; -export { getClimbByUuid } from './get-climb.js'; -export { createClimbFilters, type ClimbSearchParams, type ParsedBoardRouteParameters } from './create-climb-filters.js'; +export { searchClimbs } from './search-climbs'; +export { countClimbs } from './count-climbs'; +export { getClimbByUuid } from './get-climb'; +export { createClimbFilters, type ClimbSearchParams, type ParsedBoardRouteParameters } from './create-climb-filters'; diff --git a/packages/backend/src/db/queries/climbs/search-climbs.ts b/packages/backend/src/db/queries/climbs/search-climbs.ts index 8512713b..f6159480 100644 --- a/packages/backend/src/db/queries/climbs/search-climbs.ts +++ b/packages/backend/src/db/queries/climbs/search-climbs.ts @@ -1,8 +1,8 @@ import { eq, desc, sql, and } from 'drizzle-orm'; -import { db } from '../../client.js'; -import { getBoardTables, type BoardName } from '../util/table-select.js'; -import { createClimbFilters, type ClimbSearchParams, type ParsedBoardRouteParameters } from './create-climb-filters.js'; -import { getSizeEdges } from '../util/product-sizes-data.js'; +import { db } from '../../client'; +import { getBoardTables, type BoardName } from '../util/table-select'; +import { createClimbFilters, type ClimbSearchParams, type ParsedBoardRouteParameters } from './create-climb-filters'; +import { getSizeEdges } from '../util/product-sizes-data'; import type { Climb, ClimbSearchResult, LitUpHoldsMap, HoldState } from '@boardsesh/shared-schema'; // Hold state mapping for converting frames string to lit up holds map diff --git a/packages/backend/src/db/queries/util/product-sizes-data.ts b/packages/backend/src/db/queries/util/product-sizes-data.ts index b7b6aced..2fd4ab6f 100644 --- a/packages/backend/src/db/queries/util/product-sizes-data.ts +++ b/packages/backend/src/db/queries/util/product-sizes-data.ts @@ -4,7 +4,7 @@ * to eliminate database queries. */ -import type { BoardName } from './table-select.js'; +import type { BoardName } from './table-select'; export interface SizeEdges { edgeLeft: number; diff --git a/packages/backend/src/graphql/index.ts b/packages/backend/src/graphql/index.ts index e6c2c6e6..c35a2a3f 100644 --- a/packages/backend/src/graphql/index.ts +++ b/packages/backend/src/graphql/index.ts @@ -1,10 +1,10 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { typeDefs } from '@boardsesh/shared-schema'; -import { resolvers } from './resolvers/index.js'; +import { resolvers } from './resolvers/index'; // Create and export schema export const schema = makeExecutableSchema({ typeDefs, resolvers }); // Re-export Yoga instance creator and context utilities -export { createYogaInstance } from './yoga.js'; -export { createContext, updateContext, getContext } from './context.js'; +export { createYogaInstance } from './yoga'; +export { createContext, updateContext, getContext } from './context'; diff --git a/packages/backend/src/graphql/resolvers/board/queries.ts b/packages/backend/src/graphql/resolvers/board/queries.ts index eb97a5b2..cba1cc3c 100644 --- a/packages/backend/src/graphql/resolvers/board/queries.ts +++ b/packages/backend/src/graphql/resolvers/board/queries.ts @@ -1,9 +1,9 @@ import { eq, asc, sql } from 'drizzle-orm'; import type { Grade, Angle } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { validateInput } from '../shared/helpers.js'; -import { BoardNameSchema } from '../../../validation/schemas.js'; +import { validateInput } from '../shared/helpers'; +import { BoardNameSchema } from '../../../validation/schemas'; export const boardQueries = { /** diff --git a/packages/backend/src/graphql/resolvers/climbs/field-resolvers.ts b/packages/backend/src/graphql/resolvers/climbs/field-resolvers.ts index f1f43862..48c4c072 100644 --- a/packages/backend/src/graphql/resolvers/climbs/field-resolvers.ts +++ b/packages/backend/src/graphql/resolvers/climbs/field-resolvers.ts @@ -1,6 +1,6 @@ import type { Climb } from '@boardsesh/shared-schema'; -import { searchClimbs as searchClimbsQuery, countClimbs } from '../../../db/queries/climbs/index.js'; -import type { ClimbSearchContext } from '../shared/types.js'; +import { searchClimbs as searchClimbsQuery, countClimbs } from '../../../db/queries/climbs/index'; +import type { ClimbSearchContext } from '../shared/types'; /** * Field-level resolvers for ClimbSearchResult diff --git a/packages/backend/src/graphql/resolvers/climbs/queries.ts b/packages/backend/src/graphql/resolvers/climbs/queries.ts index 0394d2f5..d0967ccf 100644 --- a/packages/backend/src/graphql/resolvers/climbs/queries.ts +++ b/packages/backend/src/graphql/resolvers/climbs/queries.ts @@ -1,11 +1,11 @@ import type { ClimbSearchInput, ConnectionContext } from '@boardsesh/shared-schema'; -import type { ClimbSearchParams, ParsedBoardRouteParameters } from '../../../db/queries/climbs/index.js'; -import { getClimbByUuid } from '../../../db/queries/climbs/index.js'; -import { getSizeEdges } from '../../../db/queries/util/product-sizes-data.js'; -import { isValidBoardName } from '../../../db/queries/util/table-select.js'; -import { validateInput } from '../shared/helpers.js'; -import { ClimbSearchInputSchema, BoardNameSchema, ExternalUUIDSchema } from '../../../validation/schemas.js'; -import type { ClimbSearchContext } from '../shared/types.js'; +import type { ClimbSearchParams, ParsedBoardRouteParameters } from '../../../db/queries/climbs/index'; +import { getClimbByUuid } from '../../../db/queries/climbs/index'; +import { getSizeEdges } from '../../../db/queries/util/product-sizes-data'; +import { isValidBoardName } from '../../../db/queries/util/table-select'; +import { validateInput } from '../shared/helpers'; +import { ClimbSearchInputSchema, BoardNameSchema, ExternalUUIDSchema } from '../../../validation/schemas'; +import type { ClimbSearchContext } from '../shared/types'; // Debug logging flag - only log in development const DEBUG = process.env.NODE_ENV === 'development'; diff --git a/packages/backend/src/graphql/resolvers/favorites/mutations.ts b/packages/backend/src/graphql/resolvers/favorites/mutations.ts index 7be68604..e602b1a8 100644 --- a/packages/backend/src/graphql/resolvers/favorites/mutations.ts +++ b/packages/backend/src/graphql/resolvers/favorites/mutations.ts @@ -1,9 +1,9 @@ import { eq, and } from 'drizzle-orm'; import type { ConnectionContext, ToggleFavoriteInput, ToggleFavoriteResult } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { requireAuthenticated, validateInput } from '../shared/helpers.js'; -import { ToggleFavoriteInputSchema } from '../../../validation/schemas.js'; +import { requireAuthenticated, validateInput } from '../shared/helpers'; +import { ToggleFavoriteInputSchema } from '../../../validation/schemas'; export const favoriteMutations = { /** diff --git a/packages/backend/src/graphql/resolvers/favorites/queries.ts b/packages/backend/src/graphql/resolvers/favorites/queries.ts index d0446eb3..5c8705db 100644 --- a/packages/backend/src/graphql/resolvers/favorites/queries.ts +++ b/packages/backend/src/graphql/resolvers/favorites/queries.ts @@ -1,9 +1,9 @@ import { eq, and, inArray } from 'drizzle-orm'; import type { ConnectionContext } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { validateInput } from '../shared/helpers.js'; -import { BoardNameSchema } from '../../../validation/schemas.js'; +import { validateInput } from '../shared/helpers'; +import { BoardNameSchema } from '../../../validation/schemas'; export const favoriteQueries = { /** diff --git a/packages/backend/src/graphql/resolvers/index.ts b/packages/backend/src/graphql/resolvers/index.ts index cee0ca32..17dbb15c 100644 --- a/packages/backend/src/graphql/resolvers/index.ts +++ b/packages/backend/src/graphql/resolvers/index.ts @@ -1,24 +1,24 @@ import GraphQLJSON from 'graphql-type-json'; // Import domain resolvers -import { boardQueries } from './board/queries.js'; -import { tickQueries } from './ticks/queries.js'; -import { tickMutations } from './ticks/mutations.js'; -import { userQueries } from './users/queries.js'; -import { userMutations } from './users/mutations.js'; -import { climbQueries } from './climbs/queries.js'; -import { climbFieldResolvers } from './climbs/field-resolvers.js'; -import { favoriteQueries } from './favorites/queries.js'; -import { favoriteMutations } from './favorites/mutations.js'; -import { playlistQueries } from './playlists/queries.js'; -import { playlistMutations } from './playlists/mutations.js'; -import { sessionQueries } from './sessions/queries.js'; -import { sessionMutations } from './sessions/mutations.js'; -import { sessionSubscriptions } from './sessions/subscriptions.js'; -import { sessionEventResolver } from './sessions/type-resolvers.js'; -import { queueMutations } from './queue/mutations.js'; -import { queueSubscriptions } from './queue/subscriptions.js'; -import { queueEventResolver } from './queue/type-resolvers.js'; +import { boardQueries } from './board/queries'; +import { tickQueries } from './ticks/queries'; +import { tickMutations } from './ticks/mutations'; +import { userQueries } from './users/queries'; +import { userMutations } from './users/mutations'; +import { climbQueries } from './climbs/queries'; +import { climbFieldResolvers } from './climbs/field-resolvers'; +import { favoriteQueries } from './favorites/queries'; +import { favoriteMutations } from './favorites/mutations'; +import { playlistQueries } from './playlists/queries'; +import { playlistMutations } from './playlists/mutations'; +import { sessionQueries } from './sessions/queries'; +import { sessionMutations } from './sessions/mutations'; +import { sessionSubscriptions } from './sessions/subscriptions'; +import { sessionEventResolver } from './sessions/type-resolvers'; +import { queueMutations } from './queue/mutations'; +import { queueSubscriptions } from './queue/subscriptions'; +import { queueEventResolver } from './queue/type-resolvers'; export const resolvers = { // Scalar types diff --git a/packages/backend/src/graphql/resolvers/playlists/mutations.ts b/packages/backend/src/graphql/resolvers/playlists/mutations.ts index d33c2cdd..a2ccacad 100644 --- a/packages/backend/src/graphql/resolvers/playlists/mutations.ts +++ b/packages/backend/src/graphql/resolvers/playlists/mutations.ts @@ -1,15 +1,15 @@ import { eq, and, sql } from 'drizzle-orm'; import { v4 as uuidv4 } from 'uuid'; import type { ConnectionContext } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { requireAuthenticated, validateInput } from '../shared/helpers.js'; +import { requireAuthenticated, validateInput } from '../shared/helpers'; import { CreatePlaylistInputSchema, UpdatePlaylistInputSchema, AddClimbToPlaylistInputSchema, RemoveClimbFromPlaylistInputSchema, -} from '../../../validation/schemas.js'; +} from '../../../validation/schemas'; export const playlistMutations = { /** diff --git a/packages/backend/src/graphql/resolvers/playlists/queries.ts b/packages/backend/src/graphql/resolvers/playlists/queries.ts index 0bb0e393..d8c2fdd5 100644 --- a/packages/backend/src/graphql/resolvers/playlists/queries.ts +++ b/packages/backend/src/graphql/resolvers/playlists/queries.ts @@ -1,15 +1,15 @@ import { eq, and, inArray, desc, sql, or, isNull, asc } from 'drizzle-orm'; import type { ConnectionContext, Climb } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { requireAuthenticated, validateInput } from '../shared/helpers.js'; +import { requireAuthenticated, validateInput } from '../shared/helpers'; import { GetUserPlaylistsInputSchema, GetPlaylistsForClimbInputSchema, GetPlaylistClimbsInputSchema, -} from '../../../validation/schemas.js'; -import { getBoardTables, isValidBoardName } from '../../../db/queries/util/table-select.js'; -import { getSizeEdges } from '../../../db/queries/util/product-sizes-data.js'; +} from '../../../validation/schemas'; +import { getBoardTables, isValidBoardName } from '../../../db/queries/util/table-select'; +import { getSizeEdges } from '../../../db/queries/util/product-sizes-data'; import type { LitUpHoldsMap, HoldState } from '@boardsesh/shared-schema'; // Hold state mapping for converting frames string to lit up holds map diff --git a/packages/backend/src/graphql/resolvers/queue/mutations.ts b/packages/backend/src/graphql/resolvers/queue/mutations.ts index e1980ea1..9198d5c7 100644 --- a/packages/backend/src/graphql/resolvers/queue/mutations.ts +++ b/packages/backend/src/graphql/resolvers/queue/mutations.ts @@ -1,13 +1,13 @@ import type { ConnectionContext, ClimbQueueItem, QueueState } from '@boardsesh/shared-schema'; -import { roomManager, VersionConflictError } from '../../../services/room-manager.js'; -import { pubsub } from '../../../pubsub/index.js'; -import { requireSession, applyRateLimit, validateInput, MAX_RETRIES } from '../shared/helpers.js'; +import { roomManager, VersionConflictError } from '../../../services/room-manager'; +import { pubsub } from '../../../pubsub/index'; +import { requireSession, applyRateLimit, validateInput, MAX_RETRIES } from '../shared/helpers'; import { ClimbQueueItemSchema, QueueIndexSchema, QueueItemIdSchema, QueueArraySchema, -} from '../../../validation/schemas.js'; +} from '../../../validation/schemas'; // Debug logging flag - only log in development const DEBUG = process.env.NODE_ENV === 'development'; diff --git a/packages/backend/src/graphql/resolvers/queue/subscriptions.ts b/packages/backend/src/graphql/resolvers/queue/subscriptions.ts index aa5bf037..a122e4ba 100644 --- a/packages/backend/src/graphql/resolvers/queue/subscriptions.ts +++ b/packages/backend/src/graphql/resolvers/queue/subscriptions.ts @@ -1,8 +1,8 @@ import type { ConnectionContext, QueueEvent } from '@boardsesh/shared-schema'; -import { roomManager } from '../../../services/room-manager.js'; -import { pubsub } from '../../../pubsub/index.js'; -import { requireSessionMember } from '../shared/helpers.js'; -import { createEagerAsyncIterator } from '../shared/async-iterators.js'; +import { roomManager } from '../../../services/room-manager'; +import { pubsub } from '../../../pubsub/index'; +import { requireSessionMember } from '../shared/helpers'; +import { createEagerAsyncIterator } from '../shared/async-iterators'; export const queueSubscriptions = { /** diff --git a/packages/backend/src/graphql/resolvers/sessions/mutations.ts b/packages/backend/src/graphql/resolvers/sessions/mutations.ts index 309bf451..03247c8a 100644 --- a/packages/backend/src/graphql/resolvers/sessions/mutations.ts +++ b/packages/backend/src/graphql/resolvers/sessions/mutations.ts @@ -1,9 +1,9 @@ import { v4 as uuidv4 } from 'uuid'; import type { ConnectionContext, SessionEvent } from '@boardsesh/shared-schema'; -import { roomManager } from '../../../services/room-manager.js'; -import { pubsub } from '../../../pubsub/index.js'; -import { updateContext } from '../../context.js'; -import { requireAuthenticated, applyRateLimit, validateInput } from '../shared/helpers.js'; +import { roomManager } from '../../../services/room-manager'; +import { pubsub } from '../../../pubsub/index'; +import { updateContext } from '../../context'; +import { requireAuthenticated, applyRateLimit, validateInput } from '../shared/helpers'; import { SessionIdSchema, BoardPathSchema, @@ -13,9 +13,9 @@ import { CreateSessionInputSchema, ClimbQueueItemSchema, QueueArraySchema, -} from '../../../validation/schemas.js'; +} from '../../../validation/schemas'; import type { ClimbQueueItem } from '@boardsesh/shared-schema'; -import type { CreateSessionInput } from '../shared/types.js'; +import type { CreateSessionInput } from '../shared/types'; // Debug logging flag - only log in development const DEBUG = process.env.NODE_ENV === 'development'; diff --git a/packages/backend/src/graphql/resolvers/sessions/queries.ts b/packages/backend/src/graphql/resolvers/sessions/queries.ts index 59d80666..24cfdb13 100644 --- a/packages/backend/src/graphql/resolvers/sessions/queries.ts +++ b/packages/backend/src/graphql/resolvers/sessions/queries.ts @@ -1,8 +1,8 @@ import type { ConnectionContext, EventsReplayResponse } from '@boardsesh/shared-schema'; -import { roomManager, type DiscoverableSession } from '../../../services/room-manager.js'; -import { pubsub } from '../../../pubsub/index.js'; -import { validateInput, requireSessionMember } from '../shared/helpers.js'; -import { SessionIdSchema, LatitudeSchema, LongitudeSchema, RadiusMetersSchema } from '../../../validation/schemas.js'; +import { roomManager, type DiscoverableSession } from '../../../services/room-manager'; +import { pubsub } from '../../../pubsub/index'; +import { validateInput, requireSessionMember } from '../shared/helpers'; +import { SessionIdSchema, LatitudeSchema, LongitudeSchema, RadiusMetersSchema } from '../../../validation/schemas'; export const sessionQueries = { /** diff --git a/packages/backend/src/graphql/resolvers/sessions/subscriptions.ts b/packages/backend/src/graphql/resolvers/sessions/subscriptions.ts index 3b041df0..0909fdd4 100644 --- a/packages/backend/src/graphql/resolvers/sessions/subscriptions.ts +++ b/packages/backend/src/graphql/resolvers/sessions/subscriptions.ts @@ -1,7 +1,7 @@ import type { ConnectionContext, SessionEvent } from '@boardsesh/shared-schema'; -import { pubsub } from '../../../pubsub/index.js'; -import { requireSessionMember } from '../shared/helpers.js'; -import { createAsyncIterator } from '../shared/async-iterators.js'; +import { pubsub } from '../../../pubsub/index'; +import { requireSessionMember } from '../shared/helpers'; +import { createAsyncIterator } from '../shared/async-iterators'; export const sessionSubscriptions = { /** diff --git a/packages/backend/src/graphql/resolvers/shared/helpers.ts b/packages/backend/src/graphql/resolvers/shared/helpers.ts index 6580bc91..e89678ed 100644 --- a/packages/backend/src/graphql/resolvers/shared/helpers.ts +++ b/packages/backend/src/graphql/resolvers/shared/helpers.ts @@ -1,12 +1,12 @@ import type { ConnectionContext } from '@boardsesh/shared-schema'; -import { checkRateLimit } from '../../../utils/rate-limiter.js'; -import { getContext } from '../../context.js'; -import { getDistributedState } from '../../../services/distributed-state.js'; +import { checkRateLimit } from '../../../utils/rate-limiter'; +import { getContext } from '../../context'; +import { getDistributedState } from '../../../services/distributed-state'; // Re-export validateInput from validation schemas -export { validateInput } from '../../../validation/schemas.js'; +export { validateInput } from '../../../validation/schemas'; // Re-export MAX_RETRIES from types -export { MAX_RETRIES } from './types.js'; +export { MAX_RETRIES } from './types'; /** * Configuration for session membership retry behavior. diff --git a/packages/backend/src/graphql/resolvers/shared/types.ts b/packages/backend/src/graphql/resolvers/shared/types.ts index 4880042d..6a67cd67 100644 --- a/packages/backend/src/graphql/resolvers/shared/types.ts +++ b/packages/backend/src/graphql/resolvers/shared/types.ts @@ -1,6 +1,6 @@ import type { Climb } from '@boardsesh/shared-schema'; -import type { ParsedBoardRouteParameters, ClimbSearchParams } from '../../../db/queries/climbs/index.js'; -import type { SizeEdges } from '../../../db/queries/util/product-sizes-data.js'; +import type { ParsedBoardRouteParameters, ClimbSearchParams } from '../../../db/queries/climbs/index'; +import type { SizeEdges } from '../../../db/queries/util/product-sizes-data'; /** * Context object passed from searchClimbs query to ClimbSearchResult field resolvers. diff --git a/packages/backend/src/graphql/resolvers/ticks/mutations.ts b/packages/backend/src/graphql/resolvers/ticks/mutations.ts index 53b08c11..544ff9c9 100644 --- a/packages/backend/src/graphql/resolvers/ticks/mutations.ts +++ b/packages/backend/src/graphql/resolvers/ticks/mutations.ts @@ -1,9 +1,9 @@ import { v4 as uuidv4 } from 'uuid'; import type { ConnectionContext } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { requireAuthenticated, validateInput } from '../shared/helpers.js'; -import { SaveTickInputSchema } from '../../../validation/schemas.js'; +import { requireAuthenticated, validateInput } from '../shared/helpers'; +import { SaveTickInputSchema } from '../../../validation/schemas'; export const tickMutations = { /** diff --git a/packages/backend/src/graphql/resolvers/ticks/queries.ts b/packages/backend/src/graphql/resolvers/ticks/queries.ts index 5494b9a9..ab0ad624 100644 --- a/packages/backend/src/graphql/resolvers/ticks/queries.ts +++ b/packages/backend/src/graphql/resolvers/ticks/queries.ts @@ -1,9 +1,9 @@ import { eq, and, desc, inArray, sql, count } from 'drizzle-orm'; import type { ConnectionContext } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { requireAuthenticated, validateInput } from '../shared/helpers.js'; -import { GetTicksInputSchema, BoardNameSchema, AscentFeedInputSchema } from '../../../validation/schemas.js'; +import { requireAuthenticated, validateInput } from '../shared/helpers'; +import { GetTicksInputSchema, BoardNameSchema, AscentFeedInputSchema } from '../../../validation/schemas'; // Helper to get the climbs table based on board type const getClimbsTable = (boardType: string) => { diff --git a/packages/backend/src/graphql/resolvers/users/mutations.ts b/packages/backend/src/graphql/resolvers/users/mutations.ts index ee8f019b..063c2186 100644 --- a/packages/backend/src/graphql/resolvers/users/mutations.ts +++ b/packages/backend/src/graphql/resolvers/users/mutations.ts @@ -1,9 +1,9 @@ import { eq, and } from 'drizzle-orm'; import type { ConnectionContext, UserProfile, AuroraCredentialStatus } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { requireAuthenticated, validateInput } from '../shared/helpers.js'; -import { UpdateProfileInputSchema, SaveAuroraCredentialInputSchema, BoardNameSchema } from '../../../validation/schemas.js'; +import { requireAuthenticated, validateInput } from '../shared/helpers'; +import { UpdateProfileInputSchema, SaveAuroraCredentialInputSchema, BoardNameSchema } from '../../../validation/schemas'; import { encrypt } from '@boardsesh/crypto'; export const userMutations = { diff --git a/packages/backend/src/graphql/resolvers/users/queries.ts b/packages/backend/src/graphql/resolvers/users/queries.ts index 7b29182e..f672f2d7 100644 --- a/packages/backend/src/graphql/resolvers/users/queries.ts +++ b/packages/backend/src/graphql/resolvers/users/queries.ts @@ -1,9 +1,9 @@ import { eq, and } from 'drizzle-orm'; import type { ConnectionContext, UserProfile, AuroraCredentialStatus } from '@boardsesh/shared-schema'; -import { db } from '../../../db/client.js'; +import { db } from '../../../db/client'; import * as dbSchema from '@boardsesh/db/schema'; -import { validateInput } from '../shared/helpers.js'; -import { BoardNameSchema } from '../../../validation/schemas.js'; +import { validateInput } from '../shared/helpers'; +import { BoardNameSchema } from '../../../validation/schemas'; export const userQueries = { /** diff --git a/packages/backend/src/graphql/yoga.ts b/packages/backend/src/graphql/yoga.ts index 7e4cf3a8..754a45cc 100644 --- a/packages/backend/src/graphql/yoga.ts +++ b/packages/backend/src/graphql/yoga.ts @@ -1,8 +1,8 @@ import { createYoga } from 'graphql-yoga'; import type { IncomingMessage } from 'http'; -import { schema } from './index.js'; -import { validateNextAuthToken } from '../middleware/auth.js'; -import { createContext } from './context.js'; +import { schema } from './index'; +import { validateNextAuthToken } from '../middleware/auth'; +import { createContext } from './context'; import type { ConnectionContext } from '@boardsesh/shared-schema'; /** diff --git a/packages/backend/src/handlers/avatars.ts b/packages/backend/src/handlers/avatars.ts index 75cb523c..9557dc7f 100644 --- a/packages/backend/src/handlers/avatars.ts +++ b/packages/backend/src/handlers/avatars.ts @@ -2,9 +2,9 @@ import type { IncomingMessage, ServerResponse } from 'http'; import Busboy from 'busboy'; import path from 'path'; import { mkdir, writeFile, unlink, access } from 'fs/promises'; -import { applyCorsHeaders } from './cors.js'; -import { validateNextAuthToken } from '../middleware/auth.js'; -import { isS3Configured, uploadToS3, deleteUserAvatarsFromS3 } from '../storage/s3.js'; +import { applyCorsHeaders } from './cors'; +import { validateNextAuthToken } from '../middleware/auth'; +import { isS3Configured, uploadToS3, deleteUserAvatarsFromS3 } from '../storage/s3'; // Avatar upload configuration const AVATARS_DIR = './avatars'; diff --git a/packages/backend/src/handlers/health.ts b/packages/backend/src/handlers/health.ts index 913529b3..ea998cd1 100644 --- a/packages/backend/src/handlers/health.ts +++ b/packages/backend/src/handlers/health.ts @@ -1,6 +1,6 @@ import type { IncomingMessage, ServerResponse } from 'http'; -import { applyCorsHeaders } from './cors.js'; -import { pubsub } from '../pubsub/index.js'; +import { applyCorsHeaders } from './cors'; +import { pubsub } from '../pubsub/index'; /** * Health check endpoint handler diff --git a/packages/backend/src/handlers/join.ts b/packages/backend/src/handlers/join.ts index cab7490f..8b215d84 100644 --- a/packages/backend/src/handlers/join.ts +++ b/packages/backend/src/handlers/join.ts @@ -1,6 +1,6 @@ import type { IncomingMessage, ServerResponse } from 'http'; -import { applyCorsHeaders } from './cors.js'; -import { roomManager } from '../services/room-manager.js'; +import { applyCorsHeaders } from './cors'; +import { roomManager } from '../services/room-manager'; /** * Determine WebSocket protocol based on request headers and environment diff --git a/packages/backend/src/handlers/static.ts b/packages/backend/src/handlers/static.ts index 7862df68..f2073209 100644 --- a/packages/backend/src/handlers/static.ts +++ b/packages/backend/src/handlers/static.ts @@ -3,9 +3,9 @@ import { createReadStream } from 'fs'; import { stat } from 'fs/promises'; import { extname } from 'path'; import path from 'path'; -import { applyCorsHeaders } from './cors.js'; -import { getAvatarsDir } from './avatars.js'; -import { isS3Configured, getFromS3 } from '../storage/s3.js'; +import { applyCorsHeaders } from './cors'; +import { getAvatarsDir } from './avatars'; +import { isS3Configured, getFromS3 } from '../storage/s3'; const MIME_TYPES: Record = { '.jpg': 'image/jpeg', diff --git a/packages/backend/src/handlers/sync.ts b/packages/backend/src/handlers/sync.ts index ef3b6b25..4e8bd508 100644 --- a/packages/backend/src/handlers/sync.ts +++ b/packages/backend/src/handlers/sync.ts @@ -1,6 +1,6 @@ import type { IncomingMessage, ServerResponse } from 'http'; import { SyncRunner } from '@boardsesh/aurora-sync/runner'; -import { applyCorsHeaders } from './cors.js'; +import { applyCorsHeaders } from './cors'; const CRON_SECRET = process.env.CRON_SECRET; diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index dfa4bb6d..d945b237 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -1,6 +1,6 @@ import 'dotenv/config'; -import { startServer } from './server.js'; -import { redisClientManager } from './redis/client.js'; +import { startServer } from './server'; +import { redisClientManager } from './redis/client'; async function main() { // Start the server (initializes PubSub/Redis) diff --git a/packages/backend/src/pubsub/index.ts b/packages/backend/src/pubsub/index.ts index e44d4c75..78737378 100644 --- a/packages/backend/src/pubsub/index.ts +++ b/packages/backend/src/pubsub/index.ts @@ -1,6 +1,6 @@ import type { QueueEvent, SessionEvent } from '@boardsesh/shared-schema'; -import { redisClientManager } from '../redis/client.js'; -import { createRedisPubSubAdapter, type RedisPubSubAdapter } from './redis-adapter.js'; +import { redisClientManager } from '../redis/client'; +import { createRedisPubSubAdapter, type RedisPubSubAdapter } from './redis-adapter'; type QueueSubscriber = (event: QueueEvent) => void; type SessionSubscriber = (event: SessionEvent) => void; diff --git a/packages/backend/src/server.ts b/packages/backend/src/server.ts index 529386f0..55c25073 100644 --- a/packages/backend/src/server.ts +++ b/packages/backend/src/server.ts @@ -1,16 +1,16 @@ import { createServer, type IncomingMessage, type ServerResponse } from 'http'; import type { WebSocketServer } from 'ws'; -import { pubsub } from './pubsub/index.js'; -import { roomManager } from './services/room-manager.js'; -import { redisClientManager } from './redis/client.js'; -import { initCors, applyCorsHeaders } from './handlers/cors.js'; -import { handleHealthCheck } from './handlers/health.js'; -import { handleSessionJoin } from './handlers/join.js'; -import { handleAvatarUpload } from './handlers/avatars.js'; -import { handleStaticAvatar } from './handlers/static.js'; -import { handleSyncCron } from './handlers/sync.js'; -import { createYogaInstance } from './graphql/yoga.js'; -import { setupWebSocketServer } from './websocket/setup.js'; +import { pubsub } from './pubsub/index'; +import { roomManager } from './services/room-manager'; +import { redisClientManager } from './redis/client'; +import { initCors, applyCorsHeaders } from './handlers/cors'; +import { handleHealthCheck } from './handlers/health'; +import { handleSessionJoin } from './handlers/join'; +import { handleAvatarUpload } from './handlers/avatars'; +import { handleStaticAvatar } from './handlers/static'; +import { handleSyncCron } from './handlers/sync'; +import { createYogaInstance } from './graphql/yoga'; +import { setupWebSocketServer } from './websocket/setup'; /** * Start the Boardsesh Backend server diff --git a/packages/backend/src/services/room-manager.ts b/packages/backend/src/services/room-manager.ts index 7fc04e40..37561d34 100644 --- a/packages/backend/src/services/room-manager.ts +++ b/packages/backend/src/services/room-manager.ts @@ -1,18 +1,18 @@ import { v4 as uuidv4 } from 'uuid'; import type Redis from 'ioredis'; -import { db } from '../db/client.js'; -import { sessions, sessionClients, sessionQueues, type Session } from '../db/schema.js'; +import { db } from '../db/client'; +import { sessions, sessionClients, sessionQueues, type Session } from '../db/schema'; import { eq, and, sql, gt, gte, lte, ne } from 'drizzle-orm'; import type { ClimbQueueItem, SessionUser } from '@boardsesh/shared-schema'; -import { haversineDistance, getBoundingBox, DEFAULT_SEARCH_RADIUS_METERS } from '../utils/geo.js'; -import { RedisSessionStore } from './redis-session-store.js'; -import { computeQueueStateHash } from '../utils/hash.js'; +import { haversineDistance, getBoundingBox, DEFAULT_SEARCH_RADIUS_METERS } from '../utils/geo'; +import { RedisSessionStore } from './redis-session-store'; +import { computeQueueStateHash } from '../utils/hash'; import { DistributedStateManager, initializeDistributedState, getDistributedState, shutdownDistributedState, -} from './distributed-state.js'; +} from './distributed-state'; // Custom error for version conflicts export class VersionConflictError extends Error { diff --git a/packages/backend/src/websocket/setup.ts b/packages/backend/src/websocket/setup.ts index e14e332e..7e767bab 100644 --- a/packages/backend/src/websocket/setup.ts +++ b/packages/backend/src/websocket/setup.ts @@ -2,12 +2,12 @@ import { WebSocketServer, type WebSocket } from 'ws'; import type { Server as HttpServer, IncomingMessage } from 'http'; import { useServer, type Extra as WsExtra } from 'graphql-ws/use/ws'; import type { Context as GqlWsContext } from 'graphql-ws'; -import { schema } from '../graphql/index.js'; -import { createContext, removeContext, getContext } from '../graphql/context.js'; -import { roomManager } from '../services/room-manager.js'; -import { pubsub } from '../pubsub/index.js'; -import { validateNextAuthToken, extractAuthToken } from '../middleware/auth.js'; -import { isOriginAllowed } from '../handlers/cors.js'; +import { schema } from '../graphql/index'; +import { createContext, removeContext, getContext } from '../graphql/context'; +import { roomManager } from '../services/room-manager'; +import { pubsub } from '../pubsub/index'; +import { validateNextAuthToken, extractAuthToken } from '../middleware/auth'; +import { isOriginAllowed } from '../handlers/cors'; import type { ConnectionContext } from '@boardsesh/shared-schema'; // Extend Extra type with our custom context diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 52190733..c99771b6 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -3,13 +3,13 @@ "version": "1.0.0", "description": "Shared encryption utilities for Boardsesh", "type": "module", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "src/index.ts", + "types": "src/index.ts", "exports": { ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "default": "./dist/index.js" + "types": "./src/index.ts", + "import": "./src/index.ts", + "default": "./src/index.ts" } }, "scripts": { diff --git a/packages/crypto/src/crypto.ts b/packages/crypto/src/crypto.ts index 22c37052..81816e1f 100644 --- a/packages/crypto/src/crypto.ts +++ b/packages/crypto/src/crypto.ts @@ -1,6 +1,6 @@ import crypto from 'crypto'; -import { deriveKey } from './key-derivation.js'; -import { getEncryptionSecret } from './env.js'; +import { deriveKey } from './key-derivation'; +import { getEncryptionSecret } from './env'; const ALGORITHM = 'aes-256-gcm'; const IV_LENGTH = 16; diff --git a/packages/crypto/src/index.ts b/packages/crypto/src/index.ts index b00e9248..c169ba10 100644 --- a/packages/crypto/src/index.ts +++ b/packages/crypto/src/index.ts @@ -1,3 +1,3 @@ // Main exports for @boardsesh/crypto package -export { encrypt, decrypt, isEncrypted } from './crypto.js'; +export { encrypt, decrypt, isEncrypted } from './crypto'; diff --git a/packages/crypto/tsconfig.json b/packages/crypto/tsconfig.json index 26ba901a..3388a58e 100644 --- a/packages/crypto/tsconfig.json +++ b/packages/crypto/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", + "module": "ESNext", + "moduleResolution": "bundler", "declaration": true, "declarationMap": true, "sourceMap": true, diff --git a/packages/db/package.json b/packages/db/package.json index 242005d4..2154d1c2 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -3,43 +3,43 @@ "version": "1.0.0", "description": "Shared database schema and client for Boardsesh", "type": "module", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "src/index.ts", + "types": "src/index.ts", "exports": { ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "default": "./dist/index.js" + "types": "./src/index.ts", + "import": "./src/index.ts", + "default": "./src/index.ts" }, "./schema": { - "types": "./dist/schema/index.d.ts", - "import": "./dist/schema/index.js", - "default": "./dist/schema/index.js" + "types": "./src/schema/index.ts", + "import": "./src/schema/index.ts", + "default": "./src/schema/index.ts" }, "./schema/boards": { - "types": "./dist/schema/boards/index.d.ts", - "import": "./dist/schema/boards/index.js", - "default": "./dist/schema/boards/index.js" + "types": "./src/schema/boards/index.ts", + "import": "./src/schema/boards/index.ts", + "default": "./src/schema/boards/index.ts" }, "./schema/auth": { - "types": "./dist/schema/auth/index.d.ts", - "import": "./dist/schema/auth/index.js", - "default": "./dist/schema/auth/index.js" + "types": "./src/schema/auth/index.ts", + "import": "./src/schema/auth/index.ts", + "default": "./src/schema/auth/index.ts" }, "./schema/app": { - "types": "./dist/schema/app/index.d.ts", - "import": "./dist/schema/app/index.js", - "default": "./dist/schema/app/index.js" + "types": "./src/schema/app/index.ts", + "import": "./src/schema/app/index.ts", + "default": "./src/schema/app/index.ts" }, "./relations": { - "types": "./dist/relations/index.d.ts", - "import": "./dist/relations/index.js", - "default": "./dist/relations/index.js" + "types": "./src/relations/index.ts", + "import": "./src/relations/index.ts", + "default": "./src/relations/index.ts" }, "./client": { - "types": "./dist/client/index.d.ts", - "import": "./dist/client/index.js", - "default": "./dist/client/index.js" + "types": "./src/client/index.ts", + "import": "./src/client/index.ts", + "default": "./src/client/index.ts" } }, "scripts": { diff --git a/packages/db/src/client/index.ts b/packages/db/src/client/index.ts index cbe2dfd5..9f6e84a5 100644 --- a/packages/db/src/client/index.ts +++ b/packages/db/src/client/index.ts @@ -1,4 +1,4 @@ -export { createDb, createPool, createNeonHttp } from './neon.js'; -export type { DbInstance, PoolInstance } from './neon.js'; -export { getConnectionConfig, isLocalDevelopment, configureNeonForEnvironment } from './config.js'; -export type { ConnectionConfig } from './config.js'; +export { createDb, createPool, createNeonHttp } from './neon'; +export type { DbInstance, PoolInstance } from './neon'; +export { getConnectionConfig, isLocalDevelopment, configureNeonForEnvironment } from './config'; +export type { ConnectionConfig } from './config'; diff --git a/packages/db/src/client/neon.ts b/packages/db/src/client/neon.ts index 421d8faf..a7d8ef90 100644 --- a/packages/db/src/client/neon.ts +++ b/packages/db/src/client/neon.ts @@ -4,9 +4,9 @@ import { drizzle as drizzleServerless } from 'drizzle-orm/neon-serverless'; import { drizzle as drizzlePostgres } from 'drizzle-orm/postgres-js'; import postgres from 'postgres'; import ws from 'ws'; -import { getConnectionConfig, configureNeonForEnvironment, isTestEnvironment } from './config.js'; -import * as schema from '../schema/index.js'; -import * as relations from '../relations/index.js'; +import { getConnectionConfig, configureNeonForEnvironment, isTestEnvironment } from './config'; +import * as schema from '../schema/index'; +import * as relations from '../relations/index'; // Configure WebSocket constructor neonConfig.webSocketConstructor = ws; diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts index f9766556..2d9d4712 100644 --- a/packages/db/src/index.ts +++ b/packages/db/src/index.ts @@ -1,6 +1,6 @@ // Re-export schema and relations -export * from './schema/index.js'; -export * from './relations/index.js'; +export * from './schema/index'; +export * from './relations/index'; // Re-export client -export * from './client/index.js'; +export * from './client/index'; diff --git a/packages/db/src/relations/index.ts b/packages/db/src/relations/index.ts index b253feb1..147de0c6 100644 --- a/packages/db/src/relations/index.ts +++ b/packages/db/src/relations/index.ts @@ -1,3 +1,3 @@ -export * from './kilter-relations.js'; -export * from './tension-relations.js'; -export * from './session-relations.js'; +export * from './kilter-relations'; +export * from './tension-relations'; +export * from './session-relations'; diff --git a/packages/db/src/relations/kilter-relations.ts b/packages/db/src/relations/kilter-relations.ts index 08758a68..f1ebf3c2 100644 --- a/packages/db/src/relations/kilter-relations.ts +++ b/packages/db/src/relations/kilter-relations.ts @@ -19,7 +19,7 @@ import { kilterUserSyncs, kilterBetaLinks, kilterClimbStats, -} from '../schema/boards/kilter.js'; +} from '../schema/boards/kilter'; export const kilterClimbStatsRelations = relations(kilterClimbStats, ({ one }) => ({ climb: one(kilterClimbs, { diff --git a/packages/db/src/relations/session-relations.ts b/packages/db/src/relations/session-relations.ts index 47d943b1..bde14529 100644 --- a/packages/db/src/relations/session-relations.ts +++ b/packages/db/src/relations/session-relations.ts @@ -1,6 +1,6 @@ import { relations } from 'drizzle-orm/relations'; -import { boardSessions, boardSessionClients, boardSessionQueues } from '../schema/app/sessions.js'; -import { users } from '../schema/auth/users.js'; +import { boardSessions, boardSessionClients, boardSessionQueues } from '../schema/app/sessions'; +import { users } from '../schema/auth/users'; export const boardSessionsRelations = relations(boardSessions, ({ one, many }) => ({ createdByUser: one(users, { diff --git a/packages/db/src/relations/tension-relations.ts b/packages/db/src/relations/tension-relations.ts index fab89cf0..f8a9b2da 100644 --- a/packages/db/src/relations/tension-relations.ts +++ b/packages/db/src/relations/tension-relations.ts @@ -19,7 +19,7 @@ import { tensionUserSyncs, tensionBetaLinks, tensionClimbStats, -} from '../schema/boards/tension.js'; +} from '../schema/boards/tension'; export const tensionClimbStatsRelations = relations(tensionClimbStats, ({ one }) => ({ climb: one(tensionClimbs, { diff --git a/packages/db/src/schema/app/ascents.ts b/packages/db/src/schema/app/ascents.ts index 5926ef4b..d4399cc8 100644 --- a/packages/db/src/schema/app/ascents.ts +++ b/packages/db/src/schema/app/ascents.ts @@ -9,8 +9,8 @@ import { uniqueIndex, pgEnum, } from 'drizzle-orm/pg-core'; -import { users } from '../auth/users.js'; -import { boardSessions } from './sessions.js'; +import { users } from '../auth/users'; +import { boardSessions } from './sessions'; /** * Tick status enum diff --git a/packages/db/src/schema/app/favorites.ts b/packages/db/src/schema/app/favorites.ts index 0b8867ec..2e5c3205 100644 --- a/packages/db/src/schema/app/favorites.ts +++ b/packages/db/src/schema/app/favorites.ts @@ -7,7 +7,7 @@ import { index, uniqueIndex, } from 'drizzle-orm/pg-core'; -import { users } from '../auth/users.js'; +import { users } from '../auth/users'; // User favorites for saved/hearted climbs export const userFavorites = pgTable( diff --git a/packages/db/src/schema/app/index.ts b/packages/db/src/schema/app/index.ts index 367643b8..dd17ffd5 100644 --- a/packages/db/src/schema/app/index.ts +++ b/packages/db/src/schema/app/index.ts @@ -1,4 +1,4 @@ -export * from './sessions.js'; -export * from './favorites.js'; -export * from './ascents.js'; -export * from './playlists.js'; +export * from './sessions'; +export * from './favorites'; +export * from './ascents'; +export * from './playlists'; diff --git a/packages/db/src/schema/app/playlists.ts b/packages/db/src/schema/app/playlists.ts index 8c0a9293..d892c517 100644 --- a/packages/db/src/schema/app/playlists.ts +++ b/packages/db/src/schema/app/playlists.ts @@ -9,7 +9,7 @@ import { index, uniqueIndex, } from 'drizzle-orm/pg-core'; -import { users } from '../auth/users.js'; +import { users } from '../auth/users'; /** * Playlists - User-created collections of climbs diff --git a/packages/db/src/schema/app/sessions.ts b/packages/db/src/schema/app/sessions.ts index 36d5731e..d4b88cea 100644 --- a/packages/db/src/schema/app/sessions.ts +++ b/packages/db/src/schema/app/sessions.ts @@ -1,6 +1,6 @@ import { pgTable, text, timestamp, boolean, jsonb, integer, doublePrecision, index } from 'drizzle-orm/pg-core'; import type { ClimbQueueItem } from '@boardsesh/shared-schema'; -import { users } from '../auth/users.js'; +import { users } from '../auth/users'; // Board sessions for party mode (renamed from 'sessions' to avoid conflict with NextAuth sessions) export const boardSessions = pgTable('board_sessions', { diff --git a/packages/db/src/schema/auth/credentials.ts b/packages/db/src/schema/auth/credentials.ts index 1dbcdb51..e726c6d8 100644 --- a/packages/db/src/schema/auth/credentials.ts +++ b/packages/db/src/schema/auth/credentials.ts @@ -3,7 +3,7 @@ import { text, timestamp, } from 'drizzle-orm/pg-core'; -import { users } from './users.js'; +import { users } from './users'; // User credentials for email/password authentication // Kept separate from NextAuth users table to maintain adapter compatibility diff --git a/packages/db/src/schema/auth/index.ts b/packages/db/src/schema/auth/index.ts index f046e033..9f1d1555 100644 --- a/packages/db/src/schema/auth/index.ts +++ b/packages/db/src/schema/auth/index.ts @@ -1,3 +1,3 @@ -export * from './users.js'; -export * from './credentials.js'; -export * from './mappings.js'; +export * from './users'; +export * from './credentials'; +export * from './mappings'; diff --git a/packages/db/src/schema/auth/mappings.ts b/packages/db/src/schema/auth/mappings.ts index eaf2f33f..6e5a9f8e 100644 --- a/packages/db/src/schema/auth/mappings.ts +++ b/packages/db/src/schema/auth/mappings.ts @@ -7,7 +7,7 @@ import { index, uniqueIndex, } from 'drizzle-orm/pg-core'; -import { users } from './users.js'; +import { users } from './users'; // User board mappings table to link NextAuth users with Aurora board users export const userBoardMappings = pgTable( diff --git a/packages/db/src/schema/boards/index.ts b/packages/db/src/schema/boards/index.ts index 54945943..e03e41db 100644 --- a/packages/db/src/schema/boards/index.ts +++ b/packages/db/src/schema/boards/index.ts @@ -1,3 +1,3 @@ -export * from './kilter.js'; -export * from './tension.js'; -export * from './unified.js'; +export * from './kilter'; +export * from './tension'; +export * from './unified'; diff --git a/packages/db/src/schema/index.ts b/packages/db/src/schema/index.ts index 089db345..0078c9d7 100644 --- a/packages/db/src/schema/index.ts +++ b/packages/db/src/schema/index.ts @@ -1,4 +1,4 @@ // Re-export all schema modules -export * from './boards/index.js'; -export * from './auth/index.js'; -export * from './app/index.js'; +export * from './boards/index'; +export * from './auth/index'; +export * from './app/index'; diff --git a/packages/db/tsconfig.json b/packages/db/tsconfig.json index 26ba901a..3388a58e 100644 --- a/packages/db/tsconfig.json +++ b/packages/db/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", + "module": "ESNext", + "moduleResolution": "bundler", "declaration": true, "declarationMap": true, "sourceMap": true, diff --git a/packages/moonboard-ocr/package.json b/packages/moonboard-ocr/package.json index e28959e6..2468d24d 100644 --- a/packages/moonboard-ocr/package.json +++ b/packages/moonboard-ocr/package.json @@ -3,23 +3,23 @@ "version": "0.2.0", "description": "Extract MoonBoard climb data from screenshots - works in Node.js and browser", "type": "module", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", + "main": "./src/index.ts", + "types": "./src/index.ts", "exports": { ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "default": "./dist/index.js" + "types": "./src/index.ts", + "import": "./src/index.ts", + "default": "./src/index.ts" }, "./browser": { - "types": "./dist/browser.d.ts", - "import": "./dist/browser.js", - "default": "./dist/browser.js" + "types": "./src/browser.ts", + "import": "./src/browser.ts", + "default": "./src/browser.ts" } }, "browser": { - "./dist/index.js": "./dist/browser.js", - "./dist/image-processor/sharp-processor.js": false, + "./src/index.ts": "./src/browser.ts", + "./src/image-processor/sharp-processor.ts": false, "sharp": false }, "bin": { diff --git a/packages/moonboard-ocr/src/__tests__/fixtures/expected-results.ts b/packages/moonboard-ocr/src/__tests__/fixtures/expected-results.ts index dfd33ea2..0f52315f 100644 --- a/packages/moonboard-ocr/src/__tests__/fixtures/expected-results.ts +++ b/packages/moonboard-ocr/src/__tests__/fixtures/expected-results.ts @@ -3,7 +3,7 @@ * Used by both Sharp and Canvas test suites. */ -import type { GridCoordinate } from '../../types.js'; +import type { GridCoordinate } from '../../types'; export interface ExpectedClimbResult { /** Fixture filename */ diff --git a/packages/moonboard-ocr/src/__tests__/helpers/node-canvas-processor.ts b/packages/moonboard-ocr/src/__tests__/helpers/node-canvas-processor.ts index 73b3ba00..0f8b5ed3 100644 --- a/packages/moonboard-ocr/src/__tests__/helpers/node-canvas-processor.ts +++ b/packages/moonboard-ocr/src/__tests__/helpers/node-canvas-processor.ts @@ -11,7 +11,7 @@ import { RawPixelData, ImageMetadata, ImageRegion, -} from '../../image-processor/types.js'; +} from '../../image-processor/types'; /** * Node-canvas implementation of ImageProcessor for testing. diff --git a/packages/moonboard-ocr/src/__tests__/helpers/test-utils.ts b/packages/moonboard-ocr/src/__tests__/helpers/test-utils.ts index da510c52..cb62443c 100644 --- a/packages/moonboard-ocr/src/__tests__/helpers/test-utils.ts +++ b/packages/moonboard-ocr/src/__tests__/helpers/test-utils.ts @@ -3,8 +3,8 @@ */ import { expect } from 'vitest'; -import type { ParseResult } from '../../types.js'; -import type { ExpectedClimbResult } from '../fixtures/expected-results.js'; +import type { ParseResult } from '../../types'; +import type { ExpectedClimbResult } from '../fixtures/expected-results'; export interface ValidationOptions { /** Whether to validate OCR fields (name, setter, grades) */ diff --git a/packages/moonboard-ocr/src/__tests__/parser.canvas.test.ts b/packages/moonboard-ocr/src/__tests__/parser.canvas.test.ts index 3c390d54..6929ac73 100644 --- a/packages/moonboard-ocr/src/__tests__/parser.canvas.test.ts +++ b/packages/moonboard-ocr/src/__tests__/parser.canvas.test.ts @@ -11,10 +11,10 @@ import { describe, it } from 'vitest'; import path from 'path'; -import { NodeCanvasImageProcessor } from './helpers/node-canvas-processor.js'; -import { parseWithProcessor } from '../parser.js'; -import { EXPECTED_RESULTS } from './fixtures/expected-results.js'; -import { validateParseResult } from './helpers/test-utils.js'; +import { NodeCanvasImageProcessor } from './helpers/node-canvas-processor'; +import { parseWithProcessor } from '../parser'; +import { EXPECTED_RESULTS } from './fixtures/expected-results'; +import { validateParseResult } from './helpers/test-utils'; const FIXTURES_DIR = path.join(__dirname, 'fixtures'); diff --git a/packages/moonboard-ocr/src/__tests__/parser.test.ts b/packages/moonboard-ocr/src/__tests__/parser.test.ts index 4508a482..dcd67533 100644 --- a/packages/moonboard-ocr/src/__tests__/parser.test.ts +++ b/packages/moonboard-ocr/src/__tests__/parser.test.ts @@ -7,9 +7,9 @@ import { describe, it } from 'vitest'; import path from 'path'; -import { parseScreenshot } from '../parser.js'; -import { EXPECTED_RESULTS } from './fixtures/expected-results.js'; -import { validateParseResult } from './helpers/test-utils.js'; +import { parseScreenshot } from '../parser'; +import { EXPECTED_RESULTS } from './fixtures/expected-results'; +import { validateParseResult } from './helpers/test-utils'; const FIXTURES_DIR = path.join(__dirname, 'fixtures'); diff --git a/packages/moonboard-ocr/src/browser.ts b/packages/moonboard-ocr/src/browser.ts index 6c9a1390..9c1efbfb 100644 --- a/packages/moonboard-ocr/src/browser.ts +++ b/packages/moonboard-ocr/src/browser.ts @@ -20,9 +20,9 @@ * ``` */ -import { CanvasImageProcessor } from './image-processor/canvas-processor.js'; -import { parseWithProcessor, deduplicateClimbs } from './parser.js'; -import type { ParseResult, MoonBoardClimb, DetectedHold, GridCoordinate, HoldType } from './types.js'; +import { CanvasImageProcessor } from './image-processor/canvas-processor'; +import { parseWithProcessor, deduplicateClimbs } from './parser'; +import type { ParseResult, MoonBoardClimb, DetectedHold, GridCoordinate, HoldType } from './types'; // Re-export types for consumers export type { ParseResult, MoonBoardClimb, DetectedHold, GridCoordinate, HoldType }; @@ -78,6 +78,6 @@ export async function parseMultipleScreenshots( export { deduplicateClimbs }; // Re-export the CanvasImageProcessor for advanced use cases -export { CanvasImageProcessor } from './image-processor/canvas-processor.js'; -export { parseWithProcessor } from './parser.js'; -export type { ImageProcessor, RawPixelData, ImageMetadata, ImageRegion } from './image-processor/types.js'; +export { CanvasImageProcessor } from './image-processor/canvas-processor'; +export { parseWithProcessor } from './parser'; +export type { ImageProcessor, RawPixelData, ImageMetadata, ImageRegion } from './image-processor/types'; diff --git a/packages/moonboard-ocr/src/cli.ts b/packages/moonboard-ocr/src/cli.ts index 8e5c3e64..e13d971f 100644 --- a/packages/moonboard-ocr/src/cli.ts +++ b/packages/moonboard-ocr/src/cli.ts @@ -3,8 +3,8 @@ import { Command } from 'commander'; import fs from 'fs/promises'; import path from 'path'; -import { parseScreenshot, parseMultipleScreenshots, deduplicateClimbs } from './parser.js'; -import { MoonBoardClimb } from './types.js'; +import { parseScreenshot, parseMultipleScreenshots, deduplicateClimbs } from './parser'; +import { MoonBoardClimb } from './types'; /** * Check if a file is an image based on extension diff --git a/packages/moonboard-ocr/src/core/holds.ts b/packages/moonboard-ocr/src/core/holds.ts index 39b0fd94..6f5fc0e9 100644 --- a/packages/moonboard-ocr/src/core/holds.ts +++ b/packages/moonboard-ocr/src/core/holds.ts @@ -1,5 +1,5 @@ -import { HoldType, GridCoordinate, GRID_POSITIONS, DetectedHold } from '../types.js'; -import { RawPixelData, ImageRegion } from '../image-processor/types.js'; +import { HoldType, GridCoordinate, GRID_POSITIONS, DetectedHold } from '../types'; +import { RawPixelData, ImageRegion } from '../image-processor/types'; interface CircleCenter { x: number; diff --git a/packages/moonboard-ocr/src/core/index.ts b/packages/moonboard-ocr/src/core/index.ts index 5893614d..9b34c861 100644 --- a/packages/moonboard-ocr/src/core/index.ts +++ b/packages/moonboard-ocr/src/core/index.ts @@ -5,8 +5,8 @@ export { findNearestGridPosition, mapCirclesToHolds, detectHoldsFromPixelData, -} from './holds.js'; +} from './holds'; -export { runOCR, parseHeaderText, type OcrResult } from './ocr.js'; +export { runOCR, parseHeaderText, type OcrResult } from './ocr'; -export { calculateRegions, type ImageRegions } from './regions.js'; +export { calculateRegions, type ImageRegions } from './regions'; diff --git a/packages/moonboard-ocr/src/core/regions.ts b/packages/moonboard-ocr/src/core/regions.ts index 3c4880eb..e937b6af 100644 --- a/packages/moonboard-ocr/src/core/regions.ts +++ b/packages/moonboard-ocr/src/core/regions.ts @@ -1,4 +1,4 @@ -import { ImageRegion } from '../image-processor/types.js'; +import { ImageRegion } from '../image-processor/types'; export interface ImageRegions { header: ImageRegion; diff --git a/packages/moonboard-ocr/src/image-processor/canvas-processor.ts b/packages/moonboard-ocr/src/image-processor/canvas-processor.ts index 62719d7a..6c8c7b8b 100644 --- a/packages/moonboard-ocr/src/image-processor/canvas-processor.ts +++ b/packages/moonboard-ocr/src/image-processor/canvas-processor.ts @@ -4,7 +4,7 @@ import { ImageMetadata, ImageRegion, BrowserImageSource, -} from './types.js'; +} from './types'; /** * Canvas-based image processor for browser environment. diff --git a/packages/moonboard-ocr/src/image-processor/index.ts b/packages/moonboard-ocr/src/image-processor/index.ts index af651ffd..78a093f7 100644 --- a/packages/moonboard-ocr/src/image-processor/index.ts +++ b/packages/moonboard-ocr/src/image-processor/index.ts @@ -6,7 +6,7 @@ export type { ImageSource, NodeImageSource, BrowserImageSource, -} from './types.js'; +} from './types'; -export { SharpImageProcessor } from './sharp-processor.js'; -export { CanvasImageProcessor } from './canvas-processor.js'; +export { SharpImageProcessor } from './sharp-processor'; +export { CanvasImageProcessor } from './canvas-processor'; diff --git a/packages/moonboard-ocr/src/image-processor/sharp-processor.ts b/packages/moonboard-ocr/src/image-processor/sharp-processor.ts index 9009a620..a3368687 100644 --- a/packages/moonboard-ocr/src/image-processor/sharp-processor.ts +++ b/packages/moonboard-ocr/src/image-processor/sharp-processor.ts @@ -6,7 +6,7 @@ import { ImageMetadata, ImageRegion, NodeImageSource, -} from './types.js'; +} from './types'; /** * Sharp-based image processor for Node.js environment. diff --git a/packages/moonboard-ocr/src/index.ts b/packages/moonboard-ocr/src/index.ts index 1ba0d8a5..f59fff32 100644 --- a/packages/moonboard-ocr/src/index.ts +++ b/packages/moonboard-ocr/src/index.ts @@ -21,17 +21,17 @@ export { parseMultipleScreenshots, parseWithProcessor, deduplicateClimbs, -} from './parser.js'; +} from './parser'; // Image processor for advanced use cases -export { SharpImageProcessor } from './image-processor/sharp-processor.js'; +export { SharpImageProcessor } from './image-processor/sharp-processor'; export type { ImageProcessor, RawPixelData, ImageMetadata, ImageRegion, NodeImageSource, -} from './image-processor/types.js'; +} from './image-processor/types'; // Core algorithms (for advanced use cases) export { @@ -40,9 +40,9 @@ export { detectHoldsFromPixelData, classifyPixelColor, findNearestGridPosition, -} from './core/holds.js'; -export { runOCR, parseHeaderText } from './core/ocr.js'; -export { calculateRegions } from './core/regions.js'; +} from './core/holds'; +export { runOCR, parseHeaderText } from './core/ocr'; +export { calculateRegions } from './core/regions'; // Types export type { @@ -55,7 +55,7 @@ export type { Row, BoardRegion, HeaderRegion, -} from './types.js'; +} from './types'; // Constants -export { GRID_POSITIONS, GRID_CONFIG, HOLD_COLORS } from './types.js'; +export { GRID_POSITIONS, GRID_CONFIG, HOLD_COLORS } from './types'; diff --git a/packages/moonboard-ocr/src/parser.ts b/packages/moonboard-ocr/src/parser.ts index 32f9aa1f..55579816 100644 --- a/packages/moonboard-ocr/src/parser.ts +++ b/packages/moonboard-ocr/src/parser.ts @@ -1,10 +1,10 @@ import path from 'path'; -import { ImageProcessor } from './image-processor/types.js'; -import { SharpImageProcessor } from './image-processor/sharp-processor.js'; -import { runOCR } from './core/ocr.js'; -import { detectHoldsFromPixelData } from './core/holds.js'; -import { calculateRegions } from './core/regions.js'; -import { MoonBoardClimb, ParseResult, GridCoordinate } from './types.js'; +import { ImageProcessor } from './image-processor/types'; +import { SharpImageProcessor } from './image-processor/sharp-processor'; +import { runOCR } from './core/ocr'; +import { detectHoldsFromPixelData } from './core/holds'; +import { calculateRegions } from './core/regions'; +import { MoonBoardClimb, ParseResult, GridCoordinate } from './types'; /** * Parse a MoonBoard screenshot using the provided ImageProcessor. diff --git a/packages/moonboard-ocr/tsconfig.json b/packages/moonboard-ocr/tsconfig.json index d8200fdb..b47edaa1 100644 --- a/packages/moonboard-ocr/tsconfig.json +++ b/packages/moonboard-ocr/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", + "module": "ESNext", + "moduleResolution": "bundler", "outDir": "./dist", "rootDir": "./src", "strict": true, diff --git a/packages/shared-schema/package.json b/packages/shared-schema/package.json index 0813f17f..ccbf0f4d 100644 --- a/packages/shared-schema/package.json +++ b/packages/shared-schema/package.json @@ -3,28 +3,28 @@ "version": "1.0.0", "description": "Shared GraphQL schema and types for Boardsesh", "type": "module", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "main": "src/index.ts", + "types": "src/index.ts", "exports": { ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js", - "default": "./dist/index.js" + "types": "./src/index.ts", + "import": "./src/index.ts", + "default": "./src/index.ts" }, "./types": { - "types": "./dist/types.d.ts", - "import": "./dist/types.js", - "default": "./dist/types.js" + "types": "./src/types.ts", + "import": "./src/types.ts", + "default": "./src/types.ts" }, "./schema": { - "types": "./dist/schema.d.ts", - "import": "./dist/schema.js", - "default": "./dist/schema.js" + "types": "./src/schema.ts", + "import": "./src/schema.ts", + "default": "./src/schema.ts" }, "./operations": { - "types": "./dist/operations.d.ts", - "import": "./dist/operations.js", - "default": "./dist/operations.js" + "types": "./src/operations.ts", + "import": "./src/operations.ts", + "default": "./src/operations.ts" } }, "scripts": { diff --git a/packages/shared-schema/src/index.ts b/packages/shared-schema/src/index.ts index 23eb40fa..4dbc31ae 100644 --- a/packages/shared-schema/src/index.ts +++ b/packages/shared-schema/src/index.ts @@ -1,6 +1,6 @@ // Main entry point for @boardsesh/shared-schema // This package will contain shared GraphQL schema and TypeScript types -export * from './types.js'; -export * from './schema.js'; -export * from './operations.js'; +export * from './types'; +export * from './schema'; +export * from './operations'; diff --git a/packages/shared-schema/tsconfig.json b/packages/shared-schema/tsconfig.json index 26ba901a..3388a58e 100644 --- a/packages/shared-schema/tsconfig.json +++ b/packages/shared-schema/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", + "module": "ESNext", + "moduleResolution": "bundler", "declaration": true, "declarationMap": true, "sourceMap": true, diff --git a/packages/web/next.config.mjs b/packages/web/next.config.mjs index f77038c7..a0bd5755 100644 --- a/packages/web/next.config.mjs +++ b/packages/web/next.config.mjs @@ -5,8 +5,16 @@ const nextConfig = { typescript: { // ignoreBuildErrors: true, }, - // Transpile shared-schema package since we import TypeScript source directly - transpilePackages: ['@boardsesh/shared-schema'], + // Transpile internal monorepo packages from TypeScript source + // This eliminates the need to pre-build packages before running the web app + transpilePackages: [ + '@boardsesh/shared-schema', + '@boardsesh/db', + '@boardsesh/crypto', + '@boardsesh/moonboard-ocr', + ], + // Empty turbopack config to silence warning about webpack config + turbopack: {}, }; export default nextConfig; diff --git a/vercel.json b/vercel.json index 211b0b7b..8136bb7d 100644 --- a/vercel.json +++ b/vercel.json @@ -1,6 +1,6 @@ { "installCommand": "npm ci --legacy-peer-deps --omit=optional", - "buildCommand": "npm run build:shared && npm run build --workspace=@boardsesh/crypto && npm run build:db && npm run build --workspace=@boardsesh/moonboard-ocr && if [ \"$VERCEL_ENV\" != \"preview\" ]; then npm run db:migrate; fi && cd packages/web && npm run build", + "buildCommand": "if [ \"$VERCEL_ENV\" != \"preview\" ]; then npm run db:migrate; fi && npm run build --workspace=@boardsesh/web", "outputDirectory": "packages/web/.next", "framework": "nextjs", "crons": [