Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/supabase-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"scripts": {
"build": "npm run build:main && npm run build:module && npm run build:esm && npm run build:umd",
"build:main": "tsc -p tsconfig.json",
"build:module": "tsc -p tsconfig.module.json",
"build:module": "tsc -p tsconfig.module.json && node scripts/fix-esm-extensions.cjs",
"build:esm": "node scripts/copy-wrapper.cjs",
"build:umd": "webpack --env mode=production",
"test": "npm run test:types && npm run test:run",
Expand Down
37 changes: 37 additions & 0 deletions packages/core/supabase-js/scripts/fix-esm-extensions.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Post-build script to add .js extensions to relative imports in ESM output.
*
* Node.js ESM requires explicit file extensions for relative imports.
* TypeScript doesn't add these by default, so we add them after compilation.
*
* This fixes:
* - Node.js direct ESM imports (import { createClient } from '@supabase/supabase-js')
* - jsDelivr CDN ESM imports (when bundled with the module build)
*/
const fs = require('fs')
const path = require('path')

function addJsExtensions(dir) {
const files = fs.readdirSync(dir, { withFileTypes: true })
for (const file of files) {
const fullPath = path.join(dir, file.name)
if (file.isDirectory()) {
addJsExtensions(fullPath)
} else if (file.name.endsWith('.js')) {
let content = fs.readFileSync(fullPath, 'utf8')
// Add .js to relative imports that don't already have an extension
// Matches: from './foo' or from '../foo/bar' but not from './foo.js'
content = content.replace(/(from\s+['"])(\.\.?\/[^'"]+)(?<!\.js)(['"])/g, '$1$2.js$3')
fs.writeFileSync(fullPath, content)
}
}
}

const targetDir = path.resolve(__dirname, '../dist/module')
if (fs.existsSync(targetDir)) {
addJsExtensions(targetDir)
console.log('✓ Added .js extensions to ESM imports in dist/module/')
} else {
console.error('Error: dist/module directory not found')
process.exit(1)
}
102 changes: 87 additions & 15 deletions packages/core/supabase-js/wrapper.mjs
Original file line number Diff line number Diff line change
@@ -1,22 +1,94 @@
// Direct package re-exports - these work correctly in:
// - Node.js (resolves via node_modules)
// - jsDelivr (bundles with named exports)
// - esm.sh (bundles correctly)
// - Bundlers (webpack, vite, etc.)
export * from '@supabase/auth-js'
export { PostgrestError } from '@supabase/postgrest-js'
export {
import * as index from '../module/index.js'
const {
PostgrestError,
FunctionsHttpError,
FunctionsFetchError,
FunctionsRelayError,
FunctionsError,
FunctionRegion,
} from '@supabase/functions-js'
export * from '@supabase/realtime-js'
SupabaseClient,
createClient,
GoTrueAdminApi,
GoTrueClient,
AuthAdminApi,
AuthClient,
navigatorLock,
NavigatorLockAcquireTimeoutError,
lockInternals,
processLock,
SIGN_OUT_SCOPES,
AuthError,
AuthApiError,
AuthUnknownError,
CustomAuthError,
AuthSessionMissingError,
AuthInvalidTokenResponseError,
AuthInvalidCredentialsError,
AuthImplicitGrantRedirectError,
AuthPKCEGrantCodeExchangeError,
AuthRetryableFetchError,
AuthWeakPasswordError,
AuthInvalidJwtError,
isAuthError,
isAuthApiError,
isAuthSessionMissingError,
isAuthImplicitGrantRedirectError,
isAuthRetryableFetchError,
isAuthWeakPasswordError,
RealtimePresence,
RealtimeChannel,
RealtimeClient,
REALTIME_LISTEN_TYPES,
REALTIME_POSTGRES_CHANGES_LISTEN_EVENT,
REALTIME_PRESENCE_LISTEN_EVENTS,
REALTIME_SUBSCRIBE_STATES,
REALTIME_CHANNEL_STATES,
} = index.default || index

// Local exports from CJS build (Node.js can import CJS from ESM)
import main from '../main/index.js'
export const { SupabaseClient, createClient } = main
export {
PostgrestError,
FunctionsHttpError,
FunctionsFetchError,
FunctionsRelayError,
FunctionsError,
FunctionRegion,
SupabaseClient,
createClient,
GoTrueAdminApi,
GoTrueClient,
AuthAdminApi,
AuthClient,
navigatorLock,
NavigatorLockAcquireTimeoutError,
lockInternals,
processLock,
SIGN_OUT_SCOPES,
AuthError,
AuthApiError,
AuthUnknownError,
CustomAuthError,
AuthSessionMissingError,
AuthInvalidTokenResponseError,
AuthInvalidCredentialsError,
AuthImplicitGrantRedirectError,
AuthPKCEGrantCodeExchangeError,
AuthRetryableFetchError,
AuthWeakPasswordError,
AuthInvalidJwtError,
isAuthError,
isAuthApiError,
isAuthSessionMissingError,
isAuthImplicitGrantRedirectError,
isAuthRetryableFetchError,
isAuthWeakPasswordError,
RealtimePresence,
RealtimeChannel,
RealtimeClient,
REALTIME_LISTEN_TYPES,
REALTIME_POSTGRES_CHANGES_LISTEN_EVENT,
REALTIME_PRESENCE_LISTEN_EVENTS,
REALTIME_SUBSCRIBE_STATES,
REALTIME_CHANNEL_STATES,
}

// Default export
export default main
export default index.default || index
Loading