fix: use robust instance-level monkey patch for Appwrite clients to survive Turbopack/Next.js module duplication and npm installs

This commit is contained in:
Carlos (Almeira) 2026-07-09 23:57:43 -05:00
parent cd6a91ba9a
commit 7113ba706b
2 changed files with 46 additions and 38 deletions

View File

@ -1,29 +1,30 @@
import { Client, Account, Databases } from 'node-appwrite';
import { cookies } from 'next/headers';
// Patch console.warn to suppress Appwrite version mismatch warning
if (typeof console !== 'undefined' && !(console as any)._appwritePatchedServer) {
const originalWarn = console.warn;
console.warn = (...args) => {
if (args[0] && typeof args[0] === 'string' && args[0].includes('The current SDK is built for Appwrite')) {
return;
}
originalWarn(...args);
};
// Monkey-patch Client.prototype.call to always return plain objects
const originalCall = Client.prototype.call;
if (originalCall) {
Client.prototype.call = async function (this: any, ...args: any[]) {
const res = await originalCall.apply(this, args);
// Robust instance-level patch for Appwrite Next.js Server Components
function patchClientInstance(client: any) {
if (client._isPatched) return client;
const originalCall = client.call.bind(client);
client.call = async function (...args: any[]) {
// Suppress Appwrite version mismatch warnings during this call
const oldWarn = console.warn;
console.warn = (...warnArgs: any[]) => {
if (warnArgs[0] && typeof warnArgs[0] === 'string' && warnArgs[0].includes('built for Appwrite')) return;
oldWarn(...warnArgs);
};
try {
const res = await originalCall(...args);
// Ensure all objects are fully plain JSON (strips getters/prototypes that break Server -> Client transitions)
if (res && typeof res === 'object') {
return JSON.parse(JSON.stringify(res));
}
return res;
};
}
(console as any)._appwritePatchedServer = true;
} finally {
console.warn = oldWarn;
}
};
client._isPatched = true;
return client;
}
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
@ -50,6 +51,8 @@ export async function createSessionClient() {
client.setSession(sessionCookie.value);
}
patchClientInstance(client);
return {
get account() {
return new Account(client);
@ -66,6 +69,8 @@ export async function createAdminClient() {
.setProject(PROJECT_ID)
.setKey(process.env.APPWRITE_API_KEY || '');
patchClientInstance(client);
return {
get account() {
return new Account(client);

View File

@ -1,28 +1,29 @@
import { Client, Databases, Storage, Query, Account } from 'appwrite';
// Patch console.warn to suppress Appwrite version mismatch warning
if (typeof console !== 'undefined' && !(console as any)._appwritePatchedClient) {
const originalWarn = console.warn;
console.warn = (...args) => {
if (args[0] && typeof args[0] === 'string' && args[0].includes('The current SDK is built for Appwrite')) {
return;
}
originalWarn(...args);
};
// Monkey-patch Client.prototype.call to always return plain objects
const originalCall = Client.prototype.call;
if (originalCall) {
Client.prototype.call = async function (this: any, ...args: any[]) {
const res = await originalCall.apply(this, args);
// Robust instance-level patch for Appwrite Client
function patchClientInstance(clientInstance: any) {
if (clientInstance._isPatched) return clientInstance;
const originalCall = clientInstance.call.bind(clientInstance);
clientInstance.call = async function (...args: any[]) {
// Suppress Appwrite version mismatch warnings during this call
const oldWarn = console.warn;
console.warn = (...warnArgs: any[]) => {
if (warnArgs[0] && typeof warnArgs[0] === 'string' && warnArgs[0].includes('built for Appwrite')) return;
oldWarn(...warnArgs);
};
try {
const res = await originalCall(...args);
// Ensure all objects are fully plain JSON (strips getters/prototypes that break Server -> Client transitions)
if (res && typeof res === 'object') {
return JSON.parse(JSON.stringify(res));
}
return res;
};
}
(console as any)._appwritePatchedClient = true;
} finally {
console.warn = oldWarn;
}
};
clientInstance._isPatched = true;
return clientInstance;
}
const client = new Client();
@ -35,6 +36,8 @@ client
.setEndpoint(endpoint)
.setProject(projectId);
patchClientInstance(client);
export const databases = new Databases(client);
export const storage = new Storage(client);
export const account = new Account(client);