haardik | LearnWeb3
haardik | LearnWeb3
TtRPC
Created by haardik | LearnWeb3 on 1/2/2024 in #❓-help
Including multi-tenant config into tRPC context
For anyone who stumbles upon this later, my fix for now is to do this:
export async function createContext(
ctx: CreateWSSContextFnOptions | CreateNextContextOptions,
): Promise<{
session: Session | null;
req: IncomingMessage | NextApiRequest;
res: ws | NextApiResponse;
prisma: ExtendedPrismaClient;
tenant: string | null;
}> {
const { req, res } = ctx;

const rewriteHeader = req.headers['x-nextjs-rewrite'] as string | undefined;
const tenant = rewriteHeader?.split('tenant=')[1] ?? null;

let session: Session | null;
try {
// @ts-expect-error -- This will fail if called client side
session = await getServerSession(req, res, getAuthOptions(req));
} catch (error) {
session = await getSession(ctx);
}

const contextInner = await createContextInner();

return {
...contextInner,
session,
req,
res,
tenant: tenant ?? contextInner.tenant,
};
}

/** Use this helper for:
* - trpc's `createSSGHelpers` where we don't have req/res
* */
export async function createContextInner(opts?: CreateInnerContextOptions) {
if (!opts) {
return {
session: null,
prisma,
tenant: null,
};
}

if (opts.ctx) {
const rewriteHeader = opts.ctx.req.headers['x-nextjs-rewrite'] as
| string
| undefined;
const tenant = rewriteHeader?.split('tenant=')[1] ?? null;

let session: Session | null;
try {
session = await getServerSession(
opts.ctx.req,
opts.ctx.res,
// @ts-expect-error -- This will fail if called client side
getAuthOptions(opts.ctx.req),
);
} catch (error) {
session = await getSession(opts.ctx);
}

return {
session,
prisma,
tenant,
};
}

return {
session: null,
prisma,
tenant: null,
};
}
export async function createContext(
ctx: CreateWSSContextFnOptions | CreateNextContextOptions,
): Promise<{
session: Session | null;
req: IncomingMessage | NextApiRequest;
res: ws | NextApiResponse;
prisma: ExtendedPrismaClient;
tenant: string | null;
}> {
const { req, res } = ctx;

const rewriteHeader = req.headers['x-nextjs-rewrite'] as string | undefined;
const tenant = rewriteHeader?.split('tenant=')[1] ?? null;

let session: Session | null;
try {
// @ts-expect-error -- This will fail if called client side
session = await getServerSession(req, res, getAuthOptions(req));
} catch (error) {
session = await getSession(ctx);
}

const contextInner = await createContextInner();

return {
...contextInner,
session,
req,
res,
tenant: tenant ?? contextInner.tenant,
};
}

/** Use this helper for:
* - trpc's `createSSGHelpers` where we don't have req/res
* */
export async function createContextInner(opts?: CreateInnerContextOptions) {
if (!opts) {
return {
session: null,
prisma,
tenant: null,
};
}

if (opts.ctx) {
const rewriteHeader = opts.ctx.req.headers['x-nextjs-rewrite'] as
| string
| undefined;
const tenant = rewriteHeader?.split('tenant=')[1] ?? null;

let session: Session | null;
try {
session = await getServerSession(
opts.ctx.req,
opts.ctx.res,
// @ts-expect-error -- This will fail if called client side
getAuthOptions(opts.ctx.req),
);
} catch (error) {
session = await getSession(opts.ctx);
}

return {
session,
prisma,
tenant,
};
}

return {
session: null,
prisma,
tenant: null,
};
}
6 replies
TtRPC
Created by Mechse on 10/2/2023 in #❓-help
Wrapper Component: Unable to retrieve application context.
youre right - i was able to reproduce this as well. not sure why that happens.
7 replies
TtRPC
Created by Mechse on 10/2/2023 in #❓-help
Wrapper Component: Unable to retrieve application context.
this seems like an astro issue not trpc
7 replies
TtRPC
Created by bingcoke on 10/2/2023 in #❓-help
it sound like handle upload/download file need build new http server or endpoint?
not sure what you're using for file storage. we use S3 Buckets on our project and we have our tRPC endpoitn generate a pre-signed URL for S3 Uploads that gets sent to the frontend, and the file is uploaded directly from client to S3 downloads work similarly where we can generate presigned url's if the bucket is not public, or just give them the public link if it is
7 replies
TtRPC
Created by Albastru on 7/4/2023 in #❓-help
eventemitter not having any listeners on websocket
hmmm that makes sense. is there a way to share context between the two without 100% switching over to WS Links and without using Redis? Redis feels a bit overkill for my needs and I'd love to simply be able to share an event emitter instance between the two routes i have (one mutation and one subscription)
11 replies
TtRPC
Created by haardik | LearnWeb3 on 9/28/2023 in #❓-help
Unable to get mutation to trigger subscription because EventEmitter not being shared
I also tested with creating a simple subscription route that just sets an interval and emits random data to the frontend - this works just fine The problem is simply that two different instances of the event emitter seem to be used in the mutation vs the subscription, causing the mutation route to believe there’s no attached listeners when there are And I have no idea why there are two different instances :/
6 replies
TtRPC
Created by haardik | LearnWeb3 on 9/28/2023 in #❓-help
Unable to get mutation to trigger subscription because EventEmitter not being shared
Sorry to tag but cc @Alex / KATT 🐱 - another person mentioned this issue in another thread with no response and I feel like I’ve tried everything short of digging into Trpc codebase and trying to figure out what’s going on Edit - the other issue is https://discord.com/channels/867764511159091230/1125838439393271958
6 replies
TtRPC
Created by Albastru on 7/4/2023 in #❓-help
eventemitter not having any listeners on websocket
Mmm okay thank you
11 replies
TtRPC
Created by haardik | LearnWeb3 on 9/28/2023 in #❓-help
Unable to get mutation to trigger subscription because EventEmitter not being shared
FWIW - i cloned the example websockets repo and that works just fine. so something somewhere is wrong, but i have absolutely no idea what. any hints would be great. my tRPC is initialized as such:
function getBaseUrl() {
if (typeof window !== 'undefined') return '';
return `${process.env.NEXT_PUBLIC_APP_URL}`;
}

function getEndingLink() {
const url =
process.env.NODE_ENV !== 'production'
? 'ws://localhost:3001'
: process.env.NEXT_PUBLIC_WS_URL || 'ws://localhost:3001';

const client = createWSClient({
url,
});

return wsLink<AppRouter>({
client,
});
}

export const trpc = createTRPCNext<AppRouter>({
config({ ctx }) {
if (typeof window !== 'undefined') {
return {
transformer: SuperJSON,
links: [
splitLink({
condition: (op) => op.type === 'subscription',
true: getEndingLink(),
false: splitLink({
condition: (op) => op.context.skipBatch === true,
true: httpLink({
url: '/api/trpc',
}),
false: httpBatchLink({
url: '/api/trpc',
}),
}),
}),
],
};
}
return {
transformer: SuperJSON,
links: [
splitLink({
condition(op) {
return op.context.skipBatch === true;
},
true: httpLink({
url: `${getBaseUrl()}/api/trpc`,
headers() {
if (!ctx?.req?.headers) {
return {};
}
const {
// If you're using Node 18 before 18.15.0, omit the "connection" header
// eslint-disable-next-line @typescript-eslint/naming-convention, unused-imports/no-unused-vars
connection: _connection,
...headers
} = ctx.req.headers;
return headers;
},
}),
false: httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
headers() {
if (!ctx?.req?.headers) {
return {};
}
const {
// If you're using Node 18 before 18.15.0, omit the "connection" header
// eslint-disable-next-line @typescript-eslint/naming-convention, unused-imports/no-unused-vars
connection: _connection,
...headers
} = ctx.req.headers;
return headers;
},
}),
}),
],
};
},
ssr: true,
abortOnUnmount: true,
});
function getBaseUrl() {
if (typeof window !== 'undefined') return '';
return `${process.env.NEXT_PUBLIC_APP_URL}`;
}

function getEndingLink() {
const url =
process.env.NODE_ENV !== 'production'
? 'ws://localhost:3001'
: process.env.NEXT_PUBLIC_WS_URL || 'ws://localhost:3001';

const client = createWSClient({
url,
});

return wsLink<AppRouter>({
client,
});
}

export const trpc = createTRPCNext<AppRouter>({
config({ ctx }) {
if (typeof window !== 'undefined') {
return {
transformer: SuperJSON,
links: [
splitLink({
condition: (op) => op.type === 'subscription',
true: getEndingLink(),
false: splitLink({
condition: (op) => op.context.skipBatch === true,
true: httpLink({
url: '/api/trpc',
}),
false: httpBatchLink({
url: '/api/trpc',
}),
}),
}),
],
};
}
return {
transformer: SuperJSON,
links: [
splitLink({
condition(op) {
return op.context.skipBatch === true;
},
true: httpLink({
url: `${getBaseUrl()}/api/trpc`,
headers() {
if (!ctx?.req?.headers) {
return {};
}
const {
// If you're using Node 18 before 18.15.0, omit the "connection" header
// eslint-disable-next-line @typescript-eslint/naming-convention, unused-imports/no-unused-vars
connection: _connection,
...headers
} = ctx.req.headers;
return headers;
},
}),
false: httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
headers() {
if (!ctx?.req?.headers) {
return {};
}
const {
// If you're using Node 18 before 18.15.0, omit the "connection" header
// eslint-disable-next-line @typescript-eslint/naming-convention, unused-imports/no-unused-vars
connection: _connection,
...headers
} = ctx.req.headers;
return headers;
},
}),
}),
],
};
},
ssr: true,
abortOnUnmount: true,
});
6 replies
TtRPC
Created by Albastru on 7/4/2023 in #❓-help
eventemitter not having any listeners on websocket
@Albastru were you able to fix this? going through the same right now.
11 replies
TtRPC
Created by haardik | LearnWeb3 on 9/28/2023 in #❓-help
Unable to get mutation to trigger subscription because EventEmitter not being shared
No description
6 replies
TtRPC
Created by haardik | LearnWeb3 on 5/9/2023 in #❓-help
How to infer type of a nested object from app router output?
It simply doesn't want to do that. It says comments is not a key in OuterType['innerKey']
8 replies