From b61f929cf7b44f4dbc8245aaeb8565c8b022ca37 Mon Sep 17 00:00:00 2001 From: byGalax Date: Fri, 15 May 2026 01:52:14 +0200 Subject: [PATCH] fix(shared): drop .js extensions from relative imports for Metro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit packages/shared/src/index.ts and all sub-modules used .js extensions on relative imports (e.g. './admin/index.js') pointing at .ts source files. TypeScript with moduleResolution: "Bundler" doesn't need them, and Metro's eager exporter (used for preview / production builds) reads them literally and fails — only the dev-server Metro fell back to .ts. Workspace typecheck remains 8/8 green; Vite and TS Bundler resolution already accept both styles, so desktop is unaffected. --- packages/shared/src/admin/index.ts | 6 +++--- packages/shared/src/auth/device.ts | 18 ++++++++--------- packages/shared/src/auth/index.ts | 6 +++--- packages/shared/src/auth/magic-link.ts | 10 +++++----- packages/shared/src/auth/profile.ts | 10 +++++----- packages/shared/src/chat/attachments.ts | 12 ++++++------ packages/shared/src/chat/convKeys.ts | 24 +++++++++++------------ packages/shared/src/chat/conversations.ts | 8 ++++---- packages/shared/src/chat/groups.ts | 8 ++++---- packages/shared/src/chat/index.ts | 14 ++++++------- packages/shared/src/chat/messages.ts | 14 ++++++------- packages/shared/src/chat/types.ts | 6 +++--- packages/shared/src/crypto/box.ts | 2 +- packages/shared/src/crypto/index.ts | 8 ++++---- packages/shared/src/crypto/keys.ts | 2 +- packages/shared/src/crypto/sessionKeys.ts | 6 +++--- packages/shared/src/friends/index.ts | 6 +++--- packages/shared/src/i18n/detect.ts | 2 +- packages/shared/src/i18n/index.ts | 14 ++++++------- packages/shared/src/i18n/resources.ts | 4 ++-- packages/shared/src/index.ts | 16 +++++++-------- packages/shared/src/rtc/index.ts | 4 ++-- packages/shared/src/rtc/token.ts | 4 ++-- packages/shared/src/supabase/client.ts | 6 +++--- packages/shared/src/supabase/index.ts | 6 +++--- 25 files changed, 108 insertions(+), 108 deletions(-) diff --git a/packages/shared/src/admin/index.ts b/packages/shared/src/admin/index.ts index 3953cbc..f3ba016 100644 --- a/packages/shared/src/admin/index.ts +++ b/packages/shared/src/admin/index.ts @@ -1,8 +1,8 @@ -// Admin-only helpers. Every call is RLS-gated server-side via the +// Admin-only helpers. Every call is RLS-gated server-side via the // `current_user_is_admin()` helper + admin-specific policies. Non-admins // trying to call these still get clean PostgREST 403/empty-result responses. -import type { AppSupabaseClient } from '../supabase/client.js'; +import type { AppSupabaseClient } from '../supabase/client'; // --- Admin settings ------------------------------------------------------- @@ -189,7 +189,7 @@ export async function setUserFlag( } // --------------------------------------------------------------------------- -// Conversations (admin view — reads all regardless of membership) +// Conversations (admin view — reads all regardless of membership) // --------------------------------------------------------------------------- export interface AdminConversationRow { diff --git a/packages/shared/src/auth/device.ts b/packages/shared/src/auth/device.ts index a2449ea..dc6ca3e 100644 --- a/packages/shared/src/auth/device.ts +++ b/packages/shared/src/auth/device.ts @@ -1,8 +1,8 @@ -import { fromBase64, generateX25519KeyPair, toBase64, wipe } from '../crypto/index.js'; -import { bytesToPgHex, pgHexToBytes } from '../supabase/bytea.js'; -import type { AppSupabaseClient } from '../supabase/client.js'; -import type { DevicePlatform } from '../supabase/types.js'; -import type { SecretStore } from './secure-storage.js'; +import { fromBase64, generateX25519KeyPair, toBase64, wipe } from '../crypto/index'; +import { bytesToPgHex, pgHexToBytes } from '../supabase/bytea'; +import type { AppSupabaseClient } from '../supabase/client'; +import type { DevicePlatform } from '../supabase/types'; +import type { SecretStore } from './secure-storage'; export interface RegisterDeviceParams { name: string; // user-facing, e.g. "Dennis Laptop" @@ -153,7 +153,7 @@ export async function saveDevicePrivateKey( } // Restores a device record from a backup by re-seeding the local private key -// store for an EXISTING server-side device row. Does NOT insert a new row — +// store for an EXISTING server-side device row. Does NOT insert a new row — // the original row is kept intact so conversation-key bundles stay valid. // Throws when the server-side device was removed (the backup is then unusable; // user must provision a fresh device and get conv-keys shared from another @@ -169,7 +169,7 @@ export async function restoreDeviceFromServerRecord(params: { if (!session.user) throw new Error('not authenticated'); if (session.user.id !== params.userId) { throw new Error( - 'Backup is for a different account — sign in as the owner before restoring.', + 'Backup is for a different account — sign in as the owner before restoring.', ); } @@ -182,7 +182,7 @@ export async function restoreDeviceFromServerRecord(params: { if (error) throw error; if (!row) { throw new Error( - 'Device record not found on server — it was removed. Backup is no longer valid; register a new device instead.', + 'Device record not found on server — it was removed. Backup is no longer valid; register a new device instead.', ); } @@ -211,5 +211,5 @@ export function deviceIdStorageKey(userId: string): string { } // Intentional re-exports so app layers only need @chat-app/shared/auth. -export type { SecretStore } from './secure-storage.js'; +export type { SecretStore } from './secure-storage'; export { toBase64 as base64FromBytes, fromBase64 as bytesFromBase64 }; diff --git a/packages/shared/src/auth/index.ts b/packages/shared/src/auth/index.ts index 7544d76..b9d6b6c 100644 --- a/packages/shared/src/auth/index.ts +++ b/packages/shared/src/auth/index.ts @@ -1,3 +1,3 @@ -export * from './device.js'; -export * from './magic-link.js'; -export * from './profile.js'; +export * from './device'; +export * from './magic-link'; +export * from './profile'; diff --git a/packages/shared/src/auth/magic-link.ts b/packages/shared/src/auth/magic-link.ts index 2a6bb1f..a4a369b 100644 --- a/packages/shared/src/auth/magic-link.ts +++ b/packages/shared/src/auth/magic-link.ts @@ -1,5 +1,5 @@ -import type { SupportedLocale } from '../i18n/types.js'; -import type { AppSupabaseClient } from '../supabase/client.js'; +import type { SupportedLocale } from '../i18n/types'; +import type { AppSupabaseClient } from '../supabase/client'; export interface SignupParams { email: string; @@ -58,7 +58,7 @@ export async function loginWithMagicLink( } // Parse a callback URL produced by the magic-link email and establish a session. -// Works for both PKCE (`?code=…`) and legacy token-hash (`#access_token=…`). +// Works for both PKCE (`?code=…`) and legacy token-hash (`#access_token=…`). export async function completeSessionFromUrl( client: AppSupabaseClient, url: string, @@ -91,14 +91,14 @@ export async function completeSessionFromUrl( export async function signOut(client: AppSupabaseClient): Promise { // `scope: 'local'` only ends the session in THIS client. Without it Supabase // defaults to 'global', which invalidates the user's refresh tokens - // everywhere — meaning a logout in the browser would also kick the desktop + // everywhere — meaning a logout in the browser would also kick the desktop // app (and vice versa) the next time it tries to refresh its token. const { error } = await client.auth.signOut({ scope: 'local' }); if (error) throw error; } // Verify a 6-digit OTP that arrived via magic-link email. Establishes a -// session in the CURRENT webview — no browser redirect involved. Used by the +// session in the CURRENT webview — no browser redirect involved. Used by the // desktop/mobile apps where cross-origin redirects don't carry the session // back to the native webview. export async function verifyMagicLinkOtp( diff --git a/packages/shared/src/auth/profile.ts b/packages/shared/src/auth/profile.ts index 1a18743..ad6664b 100644 --- a/packages/shared/src/auth/profile.ts +++ b/packages/shared/src/auth/profile.ts @@ -1,6 +1,6 @@ -import type { SupportedLocale } from '../i18n/types.js'; -import type { AppSupabaseClient } from '../supabase/client.js'; -import type { Database, PresenceState } from '../supabase/types.js'; +import type { SupportedLocale } from '../i18n/types'; +import type { AppSupabaseClient } from '../supabase/client'; +import type { Database, PresenceState } from '../supabase/types'; type ProfileUpdate = Database['public']['Tables']['profiles']['Update']; @@ -75,7 +75,7 @@ export async function getProfileByUsername( const { data, error } = await client .from('profiles') .select(PROFILE_COLS) - // citext column compares CI server-side — send raw input, don't force case. + // citext column compares CI server-side — send raw input, don't force case. .eq('username', username.trim()) .maybeSingle(); if (error) throw error; @@ -89,7 +89,7 @@ export async function isUsernameAvailable( const { count, error } = await client .from('profiles') .select('user_id', { count: 'exact', head: true }) - // citext compares CI — no manual normalization needed. + // citext compares CI — no manual normalization needed. .eq('username', username.trim()); if (error) throw error; return (count ?? 0) === 0; diff --git a/packages/shared/src/chat/attachments.ts b/packages/shared/src/chat/attachments.ts index f0c1917..164334d 100644 --- a/packages/shared/src/chat/attachments.ts +++ b/packages/shared/src/chat/attachments.ts @@ -1,4 +1,4 @@ -// Encrypted attachment upload / download. +// Encrypted attachment upload / download. // // Per-message symmetric key + nonce encrypts the raw blob (XSalsa20-Poly1305 // via secretbox). The encrypted blob is uploaded to Supabase Storage under @@ -6,8 +6,8 @@ // travel inside the per-device message envelope as JSON, so the server never // sees the decryption material. -import { fromBase64, getCryptoBackend, toBase64 } from '../crypto/index.js'; -import type { AppSupabaseClient } from '../supabase/client.js'; +import { fromBase64, getCryptoBackend, toBase64 } from '../crypto/index'; +import type { AppSupabaseClient } from '../supabase/client'; export const ATTACHMENT_BUCKET = 'chat-attachments'; export const MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024; // 10 MB @@ -22,7 +22,7 @@ export interface AttachmentHandle { sizeBytes: number; width?: number; height?: number; - // base64-encoded — only readable via per-device envelope decrypt. + // base64-encoded — only readable via per-device envelope decrypt. keyB64: string; nonceB64: string; } @@ -166,11 +166,11 @@ function ensureUuid(): string { export interface EncryptedAttachmentResult { handle: AttachmentHandle; - key: Uint8Array; // raw bytes — caller is responsible for wiping + key: Uint8Array; // raw bytes — caller is responsible for wiping nonce: Uint8Array; } -// Encrypt + upload a blob. Does NOT insert the message_attachments row — +// Encrypt + upload a blob. Does NOT insert the message_attachments row — // the caller combines this with a message insert so everything commits // atomically at the application layer. export async function encryptAndUploadAttachment(params: { diff --git a/packages/shared/src/chat/convKeys.ts b/packages/shared/src/chat/convKeys.ts index 8b2b01b..ceed23c 100644 --- a/packages/shared/src/chat/convKeys.ts +++ b/packages/shared/src/chat/convKeys.ts @@ -1,12 +1,12 @@ -import { +import { decryptWithConvKey, encryptWithConvKey, generateConvKey, unwrapConvKey, wrapConvKeyForRecipient, -} from '../crypto/sessionKeys.js'; -import { bytesToPgHex, pgHexToBytes } from '../supabase/bytea.js'; -import type { AppSupabaseClient } from '../supabase/client.js'; +} from '../crypto/sessionKeys'; +import { bytesToPgHex, pgHexToBytes } from '../supabase/bytea'; +import type { AppSupabaseClient } from '../supabase/client'; // db-types in this monorepo is a static snapshot generated against the older // schema. The new `conversation_keys` table + `active_key_version` column on @@ -135,7 +135,7 @@ function hexNoPrefix(bytes: Uint8Array): string { // Bootstraps a brand-new conv-key, wrapping it for every member device that // currently exists (including the caller's own devices). Used the first time // a conversation needs a key, or when rotation is requested. All inserts go -// through `share_conv_keys` (SECURITY DEFINER) — silently skips invalid +// through `share_conv_keys` (SECURITY DEFINER) — silently skips invalid // recipients, no per-row 403 console spam. export async function bootstrapConvKey( client: AppSupabaseClient, @@ -146,7 +146,7 @@ export async function bootstrapConvKey( const convKey = generateConvKey(); const recipients = await listDeviceKeys(client, conversationId); if (recipients.length === 0) { - throw new Error('cannot bootstrap conv key — no recipient devices'); + throw new Error('cannot bootstrap conv key — no recipient devices'); } const bundles: Array<{ recipient_device_id: string; encrypted_key: string; nonce: string }> = []; @@ -176,9 +176,9 @@ export async function bootstrapConvKey( // Resolves the current conv-key for `conversationId`. Order: // 1) cache hit -// 2) DB row for own device → unwrap +// 2) DB row for own device → unwrap // 3) bootstrap a brand-new key (only valid path if NO existing keys exist -// for any device — i.e. this is the conversation's very first message) +// for any device — i.e. this is the conversation's very first message) export async function getOrCreateConvKey( client: AppSupabaseClient, conversationId: string, @@ -202,8 +202,8 @@ export async function getOrCreateConvKey( } // No bundle yet for THIS device. Two cases: - // - I'm the first ever sender → bootstrap. - // - Conversation already has keys but my device wasn't included yet → I + // - I'm the first ever sender → bootstrap. + // - Conversation already has keys but my device wasn't included yet → I // have to wait until an existing device wraps the key for me. const { count, error: cntErr } = await rawFrom(client, 'conversation_keys') .select('recipient_device_id', { count: 'exact', head: true }) @@ -213,7 +213,7 @@ export async function getOrCreateConvKey( if ((count ?? 0) > 0) { throw new Error( - 'Awaiting conversation key — another device must share it with this device.', + 'Awaiting conversation key — another device must share it with this device.', ); } return bootstrapConvKey(client, conversationId, own, version); @@ -259,7 +259,7 @@ export async function shareConvKeyToDevice( cache.get(cacheKey(conversationId, version)) ?? (await tryGetConvKey(client, conversationId, own.deviceId, own.privateKey, version)); if (!handle) { - throw new Error('cannot share conv key — own device does not have it yet'); + throw new Error('cannot share conv key — own device does not have it yet'); } const wrapped = await wrapConvKeyForRecipient( diff --git a/packages/shared/src/chat/conversations.ts b/packages/shared/src/chat/conversations.ts index 66a13a1..73730dc 100644 --- a/packages/shared/src/chat/conversations.ts +++ b/packages/shared/src/chat/conversations.ts @@ -1,6 +1,6 @@ -import type { ProfileBrief } from '../friends/index.js'; -import type { AppSupabaseClient } from '../supabase/client.js'; -import type { ConversationSummary } from './types.js'; +import type { ProfileBrief } from '../friends/index'; +import type { AppSupabaseClient } from '../supabase/client'; +import type { ConversationSummary } from './types'; const PROFILE_BRIEF_COLS = 'user_id, username, display_name, avatar_url, banner_url'; @@ -63,7 +63,7 @@ export async function listConversations(client: AppSupabaseClient): Promise m.user_id))); const profileMap = new Map(); diff --git a/packages/shared/src/chat/groups.ts b/packages/shared/src/chat/groups.ts index 2209e90..db766da 100644 --- a/packages/shared/src/chat/groups.ts +++ b/packages/shared/src/chat/groups.ts @@ -1,5 +1,5 @@ -import type { AppSupabaseClient } from '../supabase/client.js'; -import type { MemberRole } from '../supabase/types.js'; +import type { AppSupabaseClient } from '../supabase/client'; +import type { MemberRole } from '../supabase/types'; async function currentUserId(client: AppSupabaseClient): Promise { const { data, error } = await client.auth.getUser(); @@ -14,7 +14,7 @@ export interface CreateGroupParams { memberUserIds: string[]; } -// Client-side 3-step create: conversation → self as admin → peers as members. +// Client-side 3-step create: conversation → self as admin → peers as members. // On any peer-insert failure the conversation still survives (partial group is // still usable, admin can retry). On self-insert failure we delete the empty // conversation to avoid orphans. @@ -24,7 +24,7 @@ export async function createGroup(params: CreateGroupParams): Promise { if (trimmed.length === 0) throw new Error('group name required'); // Generate the uuid client-side so we don't need a post-insert SELECT on - // conversations — the SELECT policy requires membership, which only exists + // conversations — the SELECT policy requires membership, which only exists // AFTER we insert the creator's member row in step 2. const conversationId = crypto.randomUUID(); diff --git a/packages/shared/src/chat/index.ts b/packages/shared/src/chat/index.ts index b93434f..5f8bce2 100644 --- a/packages/shared/src/chat/index.ts +++ b/packages/shared/src/chat/index.ts @@ -1,11 +1,11 @@ -import type { AppSupabaseClient } from '../supabase/client.js'; +import type { AppSupabaseClient } from '../supabase/client'; -export * from './attachments.js'; -export * from './conversations.js'; -export * from './convKeys.js'; -export * from './groups.js'; -export * from './messages.js'; -export * from './types.js'; +export * from './attachments'; +export * from './conversations'; +export * from './convKeys'; +export * from './groups'; +export * from './messages'; +export * from './types'; // ----- RPC wrappers --------------------------------------------------------- diff --git a/packages/shared/src/chat/messages.ts b/packages/shared/src/chat/messages.ts index a6621e3..b3fb516 100644 --- a/packages/shared/src/chat/messages.ts +++ b/packages/shared/src/chat/messages.ts @@ -1,14 +1,14 @@ -import { bytesToUtf8, utf8ToBytes } from '../crypto/index.js'; -import { bytesToPgHex, pgHexToBytes } from '../supabase/bytea.js'; -import type { AppSupabaseClient } from '../supabase/client.js'; +import { bytesToUtf8, utf8ToBytes } from '../crypto/index'; +import { bytesToPgHex, pgHexToBytes } from '../supabase/bytea'; +import type { AppSupabaseClient } from '../supabase/client'; import { decryptWithConvKey, encryptWithConvKey, getOrCreateConvKey, type OwnDeviceCtx, tryGetConvKey, -} from './convKeys.js'; -import type { ChatMessage, DecryptedMessage } from './types.js'; +} from './convKeys'; +import type { ChatMessage, DecryptedMessage } from './types'; const MESSAGE_COLS = 'id, conversation_id, sender_id, sender_device_id, reply_to_id, edited_at, deleted_at, created_at, ciphertext, nonce, key_version'; @@ -92,7 +92,7 @@ export interface SendMessageParams { senderDeviceId: string; senderPrivateKey: Uint8Array; replyToId?: string; - // Optional encrypted attachments — their handles are already materialised + // Optional encrypted attachments — their handles are already materialised // via `encryptAndUploadAttachment`. The caller is responsible for creating // the corresponding message_attachments rows (see insertAttachmentRow) once // the returned message id is known. @@ -246,7 +246,7 @@ export async function listPeerReadsForMessages( } // Group variant: returns reads from ALL users (other than `excludeUserId`, -// typically caller themselves) keyed by message id → user id → timestamp. +// typically caller themselves) keyed by message id → user id → timestamp. // RLS already filters out users whose receipts are off. export async function listGroupReadsForMessages( client: AppSupabaseClient, diff --git a/packages/shared/src/chat/types.ts b/packages/shared/src/chat/types.ts index 2d7612f..ada3f07 100644 --- a/packages/shared/src/chat/types.ts +++ b/packages/shared/src/chat/types.ts @@ -1,5 +1,5 @@ -import type { ProfileBrief } from '../friends/index.js'; -import type { ConversationType, MemberRole } from '../supabase/types.js'; +import type { ProfileBrief } from '../friends/index'; +import type { ConversationType, MemberRole } from '../supabase/types'; export interface ConversationMember { userId: string; @@ -26,7 +26,7 @@ export interface ConversationSummary { // Caller's per-member preferences. archived: boolean; // ISO timestamp. null = not muted. Past timestamp = expired mute (treat as - // not muted — the server row is kept for history until the next toggle). + // not muted — the server row is kept for history until the next toggle). mutedUntil: string | null; } diff --git a/packages/shared/src/crypto/box.ts b/packages/shared/src/crypto/box.ts index 2857dcc..95c6f75 100644 --- a/packages/shared/src/crypto/box.ts +++ b/packages/shared/src/crypto/box.ts @@ -1,4 +1,4 @@ -import { getCryptoBackend } from './backend.js'; +import { getCryptoBackend } from './backend'; // Authenticated encryption using XSalsa20-Poly1305 + X25519 (Curve25519). // Delegates to the active CryptoBackend (libsodium on desktop, libsodium-rn diff --git a/packages/shared/src/crypto/index.ts b/packages/shared/src/crypto/index.ts index 93f228c..b9e87fb 100644 --- a/packages/shared/src/crypto/index.ts +++ b/packages/shared/src/crypto/index.ts @@ -1,4 +1,4 @@ -export * from './backend.js'; -export * from './box.js'; -export * from './keys.js'; -export * from './sessionKeys.js'; +export * from './backend'; +export * from './box'; +export * from './keys'; +export * from './sessionKeys'; diff --git a/packages/shared/src/crypto/keys.ts b/packages/shared/src/crypto/keys.ts index 70bb5d7..0954952 100644 --- a/packages/shared/src/crypto/keys.ts +++ b/packages/shared/src/crypto/keys.ts @@ -1,4 +1,4 @@ -import { getCryptoBackend } from './backend.js'; +import { getCryptoBackend } from './backend'; export interface X25519KeyPair { publicKey: Uint8Array; // 32 bytes diff --git a/packages/shared/src/crypto/sessionKeys.ts b/packages/shared/src/crypto/sessionKeys.ts index cf1bab0..e8e14b4 100644 --- a/packages/shared/src/crypto/sessionKeys.ts +++ b/packages/shared/src/crypto/sessionKeys.ts @@ -1,7 +1,7 @@ -import { getCryptoBackend } from './backend.js'; -import { decryptFrom, encryptFor, type EncryptedEnvelope } from './box.js'; +import { getCryptoBackend } from './backend'; +import { decryptFrom, encryptFor, type EncryptedEnvelope } from './box'; -// Sender-Key (Signal-style) helpers — one symmetric XSalsa20-Poly1305 key per +// Sender-Key (Signal-style) helpers — one symmetric XSalsa20-Poly1305 key per // conversation, wrapped with `crypto_box` for each recipient device's pubkey. // // Flow: diff --git a/packages/shared/src/friends/index.ts b/packages/shared/src/friends/index.ts index adee7f9..d191e0c 100644 --- a/packages/shared/src/friends/index.ts +++ b/packages/shared/src/friends/index.ts @@ -1,5 +1,5 @@ -import type { AppSupabaseClient } from '../supabase/client.js'; -import type { FriendshipStatus } from '../supabase/types.js'; +import type { AppSupabaseClient } from '../supabase/client'; +import type { FriendshipStatus } from '../supabase/types'; export interface ProfileBrief { userId: string; @@ -147,7 +147,7 @@ export async function acceptFriendRequest( if (error) throw error; } -// Used for both "decline incoming" and "cancel outgoing" — semantically a +// Used for both "decline incoming" and "cancel outgoing" — semantically a // bilateral break. export async function removeFriendship( client: AppSupabaseClient, diff --git a/packages/shared/src/i18n/detect.ts b/packages/shared/src/i18n/detect.ts index 14bf420..a47753a 100644 --- a/packages/shared/src/i18n/detect.ts +++ b/packages/shared/src/i18n/detect.ts @@ -1,4 +1,4 @@ -import { DEFAULT_LOCALE, SUPPORTED_LOCALES, type SupportedLocale } from './types.js'; +import { DEFAULT_LOCALE, SUPPORTED_LOCALES, type SupportedLocale } from './types'; export function isSupportedLocale(value: string | null | undefined): value is SupportedLocale { return ( diff --git a/packages/shared/src/i18n/index.ts b/packages/shared/src/i18n/index.ts index 3c957e0..0808e45 100644 --- a/packages/shared/src/i18n/index.ts +++ b/packages/shared/src/i18n/index.ts @@ -1,12 +1,12 @@ -import i18next, { type i18n as I18nInstance, type Resource } from 'i18next'; +import i18next, { type i18n as I18nInstance, type Resource } from 'i18next'; import { initReactI18next } from 'react-i18next'; -import { resources } from './resources.js'; -import { DEFAULT_LOCALE, type SupportedLocale } from './types.js'; +import { resources } from './resources'; +import { DEFAULT_LOCALE, type SupportedLocale } from './types'; -export * from './detect.js'; -export * from './error-map.js'; -export * from './types.js'; +export * from './detect'; +export * from './error-map'; +export * from './types'; export interface InitI18nOptions { initialLocale: SupportedLocale; @@ -14,7 +14,7 @@ export interface InitI18nOptions { onLanguageChanged?: (locale: SupportedLocale) => void; } -// Idempotent init — safe to call from multiple entry points. +// Idempotent init — safe to call from multiple entry points. // Returns the configured i18next instance. export function initI18n(options: InitI18nOptions): I18nInstance { if (!i18next.isInitialized) { diff --git a/packages/shared/src/i18n/resources.ts b/packages/shared/src/i18n/resources.ts index 3a0e409..7d32a67 100644 --- a/packages/shared/src/i18n/resources.ts +++ b/packages/shared/src/i18n/resources.ts @@ -1,4 +1,4 @@ -import deApp from './locales/de/app.json'; +import deApp from './locales/de/app.json'; import deAuth from './locales/de/auth.json'; import deCommon from './locales/de/common.json'; import deErrors from './locales/de/errors.json'; @@ -6,7 +6,7 @@ import enApp from './locales/en/app.json'; import enAuth from './locales/en/auth.json'; import enCommon from './locales/en/common.json'; import enErrors from './locales/en/errors.json'; -import type { Resources, SupportedLocale } from './types.js'; +import type { Resources, SupportedLocale } from './types'; export const resources: Record = { en: { common: enCommon, auth: enAuth, errors: enErrors, app: enApp }, diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 3367ad5..2d238cb 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -1,8 +1,8 @@ -export * as admin from './admin/index.js'; -export * as auth from './auth/index.js'; -export * as chat from './chat/index.js'; -export * as crypto from './crypto/index.js'; -export * as friends from './friends/index.js'; -export * as i18n from './i18n/index.js'; -export * as rtc from './rtc/index.js'; -export * as supabase from './supabase/index.js'; +export * as admin from './admin/index'; +export * as auth from './auth/index'; +export * as chat from './chat/index'; +export * as crypto from './crypto/index'; +export * as friends from './friends/index'; +export * as i18n from './i18n/index'; +export * as rtc from './rtc/index'; +export * as supabase from './supabase/index'; diff --git a/packages/shared/src/rtc/index.ts b/packages/shared/src/rtc/index.ts index 3114a8b..22c8010 100644 --- a/packages/shared/src/rtc/index.ts +++ b/packages/shared/src/rtc/index.ts @@ -1,2 +1,2 @@ -export * from './token.js'; -export * from './types.js'; +export * from './token'; +export * from './types'; diff --git a/packages/shared/src/rtc/token.ts b/packages/shared/src/rtc/token.ts index bbad7fe..359f086 100644 --- a/packages/shared/src/rtc/token.ts +++ b/packages/shared/src/rtc/token.ts @@ -1,5 +1,5 @@ -import type { AppSupabaseClient } from '../supabase/client.js'; -import type { LivekitToken } from './types.js'; +import type { AppSupabaseClient } from '../supabase/client'; +import type { LivekitToken } from './types'; // Fetch a short-lived LiveKit access token via the mint-livekit-token // edge function. The server-side RLS check lives inside that function. diff --git a/packages/shared/src/supabase/client.ts b/packages/shared/src/supabase/client.ts index c315426..9806ad9 100644 --- a/packages/shared/src/supabase/client.ts +++ b/packages/shared/src/supabase/client.ts @@ -1,11 +1,11 @@ -import { createClient as createSupabaseClient, type SupabaseClient } from '@supabase/supabase-js'; +import { createClient as createSupabaseClient, type SupabaseClient } from '@supabase/supabase-js'; -import type { Database, SupabaseConfig } from './types.js'; +import type { Database, SupabaseConfig } from './types'; // Typed client alias used throughout the app. export type AppSupabaseClient = SupabaseClient; -// Inline serial lock — replaces Supabase's default `navigator.locks` based +// Inline serial lock — replaces Supabase's default `navigator.locks` based // lock that occasionally throws "Lock was stolen by another request" when // the same origin opens multiple tabs / Tauri windows / HMR-reloaded // modules. We only have one client instance per process so a simple promise diff --git a/packages/shared/src/supabase/index.ts b/packages/shared/src/supabase/index.ts index 6c681a8..b817d2a 100644 --- a/packages/shared/src/supabase/index.ts +++ b/packages/shared/src/supabase/index.ts @@ -1,3 +1,3 @@ -export * from './bytea.js'; -export * from './client.js'; -export * from './types.js'; +export * from './bytea'; +export * from './client'; +export * from './types';