Replace Logger with getLogger and update next version
This commit replaces the use of Logger with getLogger in various parts of the code to handle logging. The Logger has been replaced with getLogger, which assists in getting logs in an asynchronous manner. In addition to this, it updates the next version in pnpm-lock.yaml from next@14.2.0-canary.61 to next@14.2.0-canary.62 and various other dependencies. Also made minor annotations and comments to the function 'isBrowser' and 'formatCurrency' in the 'utils.ts' file.
This commit is contained in:
@@ -5,7 +5,7 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
import { getProductPlanPair } from '@kit/billing';
|
import { getProductPlanPair } from '@kit/billing';
|
||||||
import { getBillingGatewayProvider } from '@kit/billing-gateway';
|
import { getBillingGatewayProvider } from '@kit/billing-gateway';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
import { requireUser } from '@kit/supabase/require-user';
|
import { requireUser } from '@kit/supabase/require-user';
|
||||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||||
@@ -51,8 +51,9 @@ export class UserBillingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { plan } = getProductPlanPair(billingConfig, planId);
|
const { plan } = getProductPlanPair(billingConfig, planId);
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: `billing.personal-account`,
|
name: `billing.personal-account`,
|
||||||
planId,
|
planId,
|
||||||
@@ -73,7 +74,7 @@ export class UserBillingService {
|
|||||||
variantQuantities: [],
|
variantQuantities: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
},
|
},
|
||||||
@@ -86,7 +87,7 @@ export class UserBillingService {
|
|||||||
checkoutToken,
|
checkoutToken,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: `billing.personal-account`,
|
name: `billing.personal-account`,
|
||||||
planId,
|
planId,
|
||||||
@@ -118,7 +119,9 @@ export class UserBillingService {
|
|||||||
throw new Error('Customer not found');
|
throw new Error('Customer not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
name: `billing.personal-account`,
|
name: `billing.personal-account`,
|
||||||
customerId,
|
customerId,
|
||||||
@@ -137,7 +140,7 @@ export class UserBillingService {
|
|||||||
|
|
||||||
url = session.url;
|
url = session.url;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
error,
|
error,
|
||||||
customerId,
|
customerId,
|
||||||
@@ -151,7 +154,7 @@ export class UserBillingService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: `billing.personal-account`,
|
name: `billing.personal-account`,
|
||||||
customerId,
|
customerId,
|
||||||
@@ -167,6 +170,14 @@ export class UserBillingService {
|
|||||||
|
|
||||||
async function getCustomerIdFromAccountId(accountId: string) {
|
async function getCustomerIdFromAccountId(accountId: string) {
|
||||||
const client = getSupabaseServerActionClient();
|
const client = getSupabaseServerActionClient();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
{
|
||||||
|
accountId,
|
||||||
|
},
|
||||||
|
`Getting customer ID for account ${accountId}...`,
|
||||||
|
);
|
||||||
|
|
||||||
const { data, error } = await client
|
const { data, error } = await client
|
||||||
.from('billing_customers')
|
.from('billing_customers')
|
||||||
@@ -175,6 +186,14 @@ async function getCustomerIdFromAccountId(accountId: string) {
|
|||||||
.maybeSingle();
|
.maybeSingle();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
|
logger.error(
|
||||||
|
{
|
||||||
|
accountId,
|
||||||
|
error,
|
||||||
|
},
|
||||||
|
`Failed to get customer ID`,
|
||||||
|
);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
import { LineItemSchema } from '@kit/billing';
|
import { LineItemSchema } from '@kit/billing';
|
||||||
import { getBillingGatewayProvider } from '@kit/billing-gateway';
|
import { getBillingGatewayProvider } from '@kit/billing-gateway';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
import { requireUser } from '@kit/supabase/require-user';
|
import { requireUser } from '@kit/supabase/require-user';
|
||||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||||
@@ -35,8 +35,9 @@ export class TeamBillingService {
|
|||||||
|
|
||||||
const userId = user.id;
|
const userId = user.id;
|
||||||
const accountId = params.accountId;
|
const accountId = params.accountId;
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -54,7 +55,7 @@ export class TeamBillingService {
|
|||||||
// if the user does not have permission to manage billing for the account
|
// if the user does not have permission to manage billing for the account
|
||||||
// then we should not proceed
|
// then we should not proceed
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
Logger.warn(
|
logger.warn(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -90,7 +91,7 @@ export class TeamBillingService {
|
|||||||
accountId,
|
accountId,
|
||||||
);
|
);
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -117,7 +118,7 @@ export class TeamBillingService {
|
|||||||
checkoutToken,
|
checkoutToken,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
error,
|
error,
|
||||||
@@ -145,8 +146,9 @@ export class TeamBillingService {
|
|||||||
slug: string;
|
slug: string;
|
||||||
}) {
|
}) {
|
||||||
const client = getSupabaseServerActionClient();
|
const client = getSupabaseServerActionClient();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
accountId,
|
accountId,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
@@ -171,7 +173,7 @@ export class TeamBillingService {
|
|||||||
// if the user does not have permission to manage billing for the account
|
// if the user does not have permission to manage billing for the account
|
||||||
// then we should not proceed
|
// then we should not proceed
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
Logger.warn(
|
logger.warn(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -190,7 +192,7 @@ export class TeamBillingService {
|
|||||||
throw new Error('Customer not found');
|
throw new Error('Customer not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
customerId,
|
customerId,
|
||||||
@@ -211,7 +213,7 @@ export class TeamBillingService {
|
|||||||
// redirect the user to the billing portal
|
// redirect the user to the billing portal
|
||||||
return url;
|
return url;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
customerId,
|
customerId,
|
||||||
@@ -260,7 +262,9 @@ export class TeamBillingService {
|
|||||||
.eq('account_id', accountId);
|
.eq('account_id', accountId);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.error(
|
||||||
{
|
{
|
||||||
accountId,
|
accountId,
|
||||||
error,
|
error,
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ async function ReturnCheckoutSessionPage({ searchParams }: SessionPageProps) {
|
|||||||
|
|
||||||
export default withI18n(ReturnCheckoutSessionPage);
|
export default withI18n(ReturnCheckoutSessionPage);
|
||||||
|
|
||||||
export async function loadCheckoutSession(sessionId: string) {
|
async function loadCheckoutSession(sessionId: string) {
|
||||||
const client = getSupabaseServerComponentClient();
|
const client = getSupabaseServerComponentClient();
|
||||||
const { error } = await requireUser(client);
|
const { error } = await requireUser(client);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export default function AccountPage() {
|
||||||
|
return <div></div>;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { getBillingEventHandlerService } from '@kit/billing-gateway';
|
import { getBillingEventHandlerService } from '@kit/billing-gateway';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { getSupabaseRouteHandlerClient } from '@kit/supabase/route-handler-client';
|
import { getSupabaseRouteHandlerClient } from '@kit/supabase/route-handler-client';
|
||||||
|
|
||||||
import billingConfig from '~/config/billing.config';
|
import billingConfig from '~/config/billing.config';
|
||||||
@@ -9,8 +9,9 @@ import billingConfig from '~/config/billing.config';
|
|||||||
*/
|
*/
|
||||||
export async function POST(request: Request) {
|
export async function POST(request: Request) {
|
||||||
const provider = billingConfig.provider;
|
const provider = billingConfig.provider;
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.webhook',
|
name: 'billing.webhook',
|
||||||
provider,
|
provider,
|
||||||
@@ -30,7 +31,7 @@ export async function POST(request: Request) {
|
|||||||
try {
|
try {
|
||||||
await service.handleWebhookEvent(request);
|
await service.handleWebhookEvent(request);
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.webhook',
|
name: 'billing.webhook',
|
||||||
},
|
},
|
||||||
@@ -39,7 +40,7 @@ export async function POST(request: Request) {
|
|||||||
|
|
||||||
return new Response('OK', { status: 200 });
|
return new Response('OK', { status: 200 });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing',
|
name: 'billing',
|
||||||
error: e,
|
error: e,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
import type { NextRequest } from 'next/server';
|
import type { NextRequest } from 'next/server';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { getSupabaseRouteHandlerClient } from '@kit/supabase/route-handler-client';
|
import { getSupabaseRouteHandlerClient } from '@kit/supabase/route-handler-client';
|
||||||
|
|
||||||
import pathsConfig from '~/config/paths.config';
|
import pathsConfig from '~/config/paths.config';
|
||||||
@@ -38,9 +38,12 @@ export async function GET(request: NextRequest) {
|
|||||||
return onError({ error: error.message });
|
return onError({ error: error.message });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.error(
|
||||||
{
|
{
|
||||||
error,
|
error,
|
||||||
|
name: `auth.callback`,
|
||||||
},
|
},
|
||||||
`An error occurred while exchanging code for session`,
|
`An error occurred while exchanging code for session`,
|
||||||
);
|
);
|
||||||
@@ -58,12 +61,14 @@ export async function GET(request: NextRequest) {
|
|||||||
return redirect(nextUrl);
|
return redirect(nextUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onError({ error }: { error: string }) {
|
async function onError({ error }: { error: string }) {
|
||||||
const errorMessage = getAuthErrorMessage(error);
|
const errorMessage = getAuthErrorMessage(error);
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
error,
|
error,
|
||||||
|
name: `auth.callback`,
|
||||||
},
|
},
|
||||||
`An error occurred while signing user in`,
|
`An error occurred while signing user in`,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -63,9 +63,10 @@ async function JoinTeamAccountPage({ searchParams }: Context) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (isInAccount) {
|
if (isInAccount) {
|
||||||
const { Logger } = await import('@kit/shared/logger');
|
const { getLogger } = await import('@kit/shared/logger');
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.warn(
|
logger.warn(
|
||||||
{
|
{
|
||||||
name: 'join-team-account',
|
name: 'join-team-account',
|
||||||
accountId: invitation.account.id,
|
accountId: invitation.account.id,
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { registerInstrumentation } from '@kit/monitoring';
|
/**
|
||||||
|
* This file is used to register monitoring instrumentation
|
||||||
|
* for your Next.js application.
|
||||||
|
*/
|
||||||
|
export async function register() {
|
||||||
|
// only run in nodejs runtime
|
||||||
|
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
||||||
|
const { registerInstrumentation } = await import('@kit/monitoring');
|
||||||
|
|
||||||
export function register() {
|
|
||||||
if (process.env.NEXT_RUNTIME !== 'nodejs') {
|
|
||||||
// Register monitoring instrumentation based on the
|
// Register monitoring instrumentation based on the
|
||||||
// MONITORING_INSTRUMENTATION_PROVIDER environment variable.
|
// MONITORING_INSTRUMENTATION_PROVIDER environment variable.
|
||||||
return registerInstrumentation();
|
return registerInstrumentation();
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
"i18next": "^23.10.1",
|
"i18next": "^23.10.1",
|
||||||
"i18next-resources-to-backend": "^1.2.0",
|
"i18next-resources-to-backend": "^1.2.0",
|
||||||
"lucide-react": "^0.363.0",
|
"lucide-react": "^0.363.0",
|
||||||
"next": "14.2.0-canary.61",
|
"next": "14.2.0-canary.62",
|
||||||
"next-sitemap": "^4.2.3",
|
"next-sitemap": "^4.2.3",
|
||||||
"next-themes": "0.3.0",
|
"next-themes": "0.3.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { SupabaseClient } from '@supabase/supabase-js';
|
import { SupabaseClient } from '@supabase/supabase-js';
|
||||||
|
|
||||||
import { BillingWebhookHandlerService } from '@kit/billing';
|
import { BillingWebhookHandlerService } from '@kit/billing';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
export class BillingEventHandlerService {
|
export class BillingEventHandlerService {
|
||||||
@@ -22,10 +22,11 @@ export class BillingEventHandlerService {
|
|||||||
return this.strategy.handleWebhookEvent(event, {
|
return this.strategy.handleWebhookEvent(event, {
|
||||||
onSubscriptionDeleted: async (subscriptionId: string) => {
|
onSubscriptionDeleted: async (subscriptionId: string) => {
|
||||||
const client = this.clientProvider();
|
const client = this.clientProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
// Handle the subscription deleted event
|
// Handle the subscription deleted event
|
||||||
// here we delete the subscription from the database
|
// here we delete the subscription from the database
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
@@ -42,7 +43,7 @@ export class BillingEventHandlerService {
|
|||||||
throw new Error('Failed to delete subscription');
|
throw new Error('Failed to delete subscription');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
@@ -52,6 +53,7 @@ export class BillingEventHandlerService {
|
|||||||
},
|
},
|
||||||
onSubscriptionUpdated: async (subscription) => {
|
onSubscriptionUpdated: async (subscription) => {
|
||||||
const client = this.clientProvider();
|
const client = this.clientProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
@@ -61,14 +63,14 @@ export class BillingEventHandlerService {
|
|||||||
customerId: subscription.target_customer_id,
|
customerId: subscription.target_customer_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.info(ctx, 'Processing subscription updated event');
|
logger.info(ctx, 'Processing subscription updated event');
|
||||||
|
|
||||||
// Handle the subscription updated event
|
// Handle the subscription updated event
|
||||||
// here we update the subscription in the database
|
// here we update the subscription in the database
|
||||||
const { error } = await client.rpc('upsert_subscription', subscription);
|
const { error } = await client.rpc('upsert_subscription', subscription);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
error,
|
error,
|
||||||
...ctx,
|
...ctx,
|
||||||
@@ -79,12 +81,13 @@ export class BillingEventHandlerService {
|
|||||||
throw new Error('Failed to update subscription');
|
throw new Error('Failed to update subscription');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(ctx, 'Successfully updated subscription');
|
logger.info(ctx, 'Successfully updated subscription');
|
||||||
},
|
},
|
||||||
onCheckoutSessionCompleted: async (payload) => {
|
onCheckoutSessionCompleted: async (payload) => {
|
||||||
// Handle the checkout session completed event
|
// Handle the checkout session completed event
|
||||||
// here we add the subscription to the database
|
// here we add the subscription to the database
|
||||||
const client = this.clientProvider();
|
const client = this.clientProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
// Check if the payload contains an order_id
|
// Check if the payload contains an order_id
|
||||||
// if it does, we add an order, otherwise we add a subscription
|
// if it does, we add an order, otherwise we add a subscription
|
||||||
@@ -97,17 +100,17 @@ export class BillingEventHandlerService {
|
|||||||
customerId: payload.target_customer_id,
|
customerId: payload.target_customer_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.info(ctx, 'Processing order completed event...');
|
logger.info(ctx, 'Processing order completed event...');
|
||||||
|
|
||||||
const { error } = await client.rpc('upsert_order', payload);
|
const { error } = await client.rpc('upsert_order', payload);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error({ ...ctx, error }, 'Failed to add order');
|
logger.error({ ...ctx, error }, 'Failed to add order');
|
||||||
|
|
||||||
throw new Error('Failed to add order');
|
throw new Error('Failed to add order');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(ctx, 'Successfully added order');
|
logger.info(ctx, 'Successfully added order');
|
||||||
} else {
|
} else {
|
||||||
const ctx = {
|
const ctx = {
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
@@ -117,25 +120,26 @@ export class BillingEventHandlerService {
|
|||||||
customerId: payload.target_customer_id,
|
customerId: payload.target_customer_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.info(ctx, 'Processing checkout session completed event...');
|
logger.info(ctx, 'Processing checkout session completed event...');
|
||||||
|
|
||||||
const { error } = await client.rpc('upsert_subscription', payload);
|
const { error } = await client.rpc('upsert_subscription', payload);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error({ ...ctx, error }, 'Failed to add subscription');
|
logger.error({ ...ctx, error }, 'Failed to add subscription');
|
||||||
|
|
||||||
throw new Error('Failed to add subscription');
|
throw new Error('Failed to add subscription');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(ctx, 'Successfully added subscription');
|
logger.info(ctx, 'Successfully added subscription');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onPaymentSucceeded: async (sessionId: string) => {
|
onPaymentSucceeded: async (sessionId: string) => {
|
||||||
const client = this.clientProvider();
|
const client = this.clientProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
// Handle the payment succeeded event
|
// Handle the payment succeeded event
|
||||||
// here we update the payment status in the database
|
// here we update the payment status in the database
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
sessionId,
|
sessionId,
|
||||||
@@ -152,7 +156,7 @@ export class BillingEventHandlerService {
|
|||||||
throw new Error('Failed to update payment status');
|
throw new Error('Failed to update payment status');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
sessionId,
|
sessionId,
|
||||||
@@ -162,10 +166,11 @@ export class BillingEventHandlerService {
|
|||||||
},
|
},
|
||||||
onPaymentFailed: async (sessionId: string) => {
|
onPaymentFailed: async (sessionId: string) => {
|
||||||
const client = this.clientProvider();
|
const client = this.clientProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
// Handle the payment failed event
|
// Handle the payment failed event
|
||||||
// here we update the payment status in the database
|
// here we update the payment status in the database
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
sessionId,
|
sessionId,
|
||||||
@@ -182,7 +187,7 @@ export class BillingEventHandlerService {
|
|||||||
throw new Error('Failed to update payment status');
|
throw new Error('Failed to update payment status');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
sessionId,
|
sessionId,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
RetrieveCheckoutSessionSchema,
|
RetrieveCheckoutSessionSchema,
|
||||||
UpdateSubscriptionParamsSchema,
|
UpdateSubscriptionParamsSchema,
|
||||||
} from '@kit/billing/schema';
|
} from '@kit/billing/schema';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
|
|
||||||
import { createLemonSqueezyBillingPortalSession } from './create-lemon-squeezy-billing-portal-session';
|
import { createLemonSqueezyBillingPortalSession } from './create-lemon-squeezy-billing-portal-session';
|
||||||
import { createLemonSqueezyCheckout } from './create-lemon-squeezy-checkout';
|
import { createLemonSqueezyCheckout } from './create-lemon-squeezy-checkout';
|
||||||
@@ -27,13 +27,12 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
async createCheckoutSession(
|
async createCheckoutSession(
|
||||||
params: z.infer<typeof CreateBillingCheckoutSchema>,
|
params: z.infer<typeof CreateBillingCheckoutSchema>,
|
||||||
) {
|
) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
customerId: params.customerId,
|
...params,
|
||||||
accountId: params.accountId,
|
|
||||||
returnUrl: params.returnUrl,
|
|
||||||
trialDays: params.trialDays,
|
|
||||||
},
|
},
|
||||||
'Creating checkout session...',
|
'Creating checkout session...',
|
||||||
);
|
);
|
||||||
@@ -43,7 +42,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
if (error ?? !response?.data.id) {
|
if (error ?? !response?.data.id) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -56,7 +55,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
throw new Error('Failed to create checkout session');
|
throw new Error('Failed to create checkout session');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -73,7 +72,9 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
async createBillingPortalSession(
|
async createBillingPortalSession(
|
||||||
params: z.infer<typeof CreateBillingPortalSessionSchema>,
|
params: z.infer<typeof CreateBillingPortalSessionSchema>,
|
||||||
) {
|
) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -85,7 +86,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
await createLemonSqueezyBillingPortalSession(params);
|
await createLemonSqueezyBillingPortalSession(params);
|
||||||
|
|
||||||
if (error ?? !data) {
|
if (error ?? !data) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -97,7 +98,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
throw new Error('Failed to create billing portal session');
|
throw new Error('Failed to create billing portal session');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -111,7 +112,9 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
async cancelSubscription(
|
async cancelSubscription(
|
||||||
params: z.infer<typeof CancelSubscriptionParamsSchema>,
|
params: z.infer<typeof CancelSubscriptionParamsSchema>,
|
||||||
) {
|
) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
subscriptionId: params.subscriptionId,
|
subscriptionId: params.subscriptionId,
|
||||||
@@ -123,7 +126,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
const { error } = await cancelSubscription(params.subscriptionId);
|
const { error } = await cancelSubscription(params.subscriptionId);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
subscriptionId: params.subscriptionId,
|
subscriptionId: params.subscriptionId,
|
||||||
@@ -135,7 +138,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
subscriptionId: params.subscriptionId,
|
subscriptionId: params.subscriptionId,
|
||||||
@@ -145,7 +148,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
subscriptionId: params.subscriptionId,
|
subscriptionId: params.subscriptionId,
|
||||||
@@ -161,7 +164,9 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
async retrieveCheckoutSession(
|
async retrieveCheckoutSession(
|
||||||
params: z.infer<typeof RetrieveCheckoutSessionSchema>,
|
params: z.infer<typeof RetrieveCheckoutSessionSchema>,
|
||||||
) {
|
) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
@@ -172,7 +177,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
const { data: session, error } = await getCheckout(params.sessionId);
|
const { data: session, error } = await getCheckout(params.sessionId);
|
||||||
|
|
||||||
if (error ?? !session?.data) {
|
if (error ?? !session?.data) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
@@ -184,7 +189,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
throw new Error('Failed to retrieve checkout session');
|
throw new Error('Failed to retrieve checkout session');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
@@ -205,7 +210,9 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
}
|
}
|
||||||
|
|
||||||
async reportUsage(params: z.infer<typeof ReportBillingUsageSchema>) {
|
async reportUsage(params: z.infer<typeof ReportBillingUsageSchema>) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
subscriptionItemId: params.subscriptionItemId,
|
subscriptionItemId: params.subscriptionItemId,
|
||||||
@@ -220,11 +227,11 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
subscriptionItemId: params.subscriptionItemId,
|
subscriptionItemId: params.subscriptionItemId,
|
||||||
error: error.message,
|
error,
|
||||||
},
|
},
|
||||||
'Failed to report usage',
|
'Failed to report usage',
|
||||||
);
|
);
|
||||||
@@ -232,7 +239,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
throw new Error('Failed to report usage');
|
throw new Error('Failed to report usage');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
subscriptionItemId: params.subscriptionItemId,
|
subscriptionItemId: params.subscriptionItemId,
|
||||||
@@ -246,19 +253,21 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
async updateSubscription(
|
async updateSubscription(
|
||||||
params: z.infer<typeof UpdateSubscriptionParamsSchema>,
|
params: z.infer<typeof UpdateSubscriptionParamsSchema>,
|
||||||
) {
|
) {
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
name: 'billing.lemon-squeezy',
|
name: 'billing.lemon-squeezy',
|
||||||
...params,
|
...params,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.info(ctx, 'Updating subscription...');
|
logger.info(ctx, 'Updating subscription...');
|
||||||
|
|
||||||
const { error } = await updateSubscriptionItem(params.subscriptionItemId, {
|
const { error } = await updateSubscriptionItem(params.subscriptionItemId, {
|
||||||
quantity: params.quantity,
|
quantity: params.quantity,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
...ctx,
|
...ctx,
|
||||||
error,
|
error,
|
||||||
@@ -269,7 +278,7 @@ export class LemonSqueezyBillingStrategyService
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(ctx, 'Subscription updated successfully');
|
logger.info(ctx, 'Subscription updated successfully');
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'server-only';
|
import 'server-only';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
|
|
||||||
import { getLemonSqueezyEnv } from '../schema/lemon-squeezy-server-env.schema';
|
import { getLemonSqueezyEnv } from '../schema/lemon-squeezy-server-env.schema';
|
||||||
|
|
||||||
@@ -10,11 +10,12 @@ import { getLemonSqueezyEnv } from '../schema/lemon-squeezy-server-env.schema';
|
|||||||
export async function initializeLemonSqueezyClient() {
|
export async function initializeLemonSqueezyClient() {
|
||||||
const { lemonSqueezySetup } = await import('@lemonsqueezy/lemonsqueezy.js');
|
const { lemonSqueezySetup } = await import('@lemonsqueezy/lemonsqueezy.js');
|
||||||
const env = getLemonSqueezyEnv();
|
const env = getLemonSqueezyEnv();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
lemonSqueezySetup({
|
lemonSqueezySetup({
|
||||||
apiKey: env.secretKey,
|
apiKey: env.secretKey,
|
||||||
onError(error) {
|
onError(error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: `billing.lemon-squeezy`,
|
name: `billing.lemon-squeezy`,
|
||||||
error: error.message,
|
error: error.message,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
BillingWebhookHandlerService,
|
BillingWebhookHandlerService,
|
||||||
getLineItemTypeById,
|
getLineItemTypeById,
|
||||||
} from '@kit/billing';
|
} from '@kit/billing';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
import { getLemonSqueezyEnv } from '../schema/lemon-squeezy-server-env.schema';
|
import { getLemonSqueezyEnv } from '../schema/lemon-squeezy-server-env.schema';
|
||||||
@@ -45,6 +45,9 @@ export class LemonSqueezyWebhookHandlerService
|
|||||||
* @description Verifies the webhook signature - should throw an error if the signature is invalid
|
* @description Verifies the webhook signature - should throw an error if the signature is invalid
|
||||||
*/
|
*/
|
||||||
async verifyWebhookSignature(request: Request) {
|
async verifyWebhookSignature(request: Request) {
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
// get the event name and signature from the headers
|
||||||
const eventName = request.headers.get('x-event-name');
|
const eventName = request.headers.get('x-event-name');
|
||||||
const signature = request.headers.get('x-signature') as string;
|
const signature = request.headers.get('x-signature') as string;
|
||||||
|
|
||||||
@@ -53,8 +56,9 @@ export class LemonSqueezyWebhookHandlerService
|
|||||||
const body = (await request.json()) as SubscriptionWebhook | OrderWebhook;
|
const body = (await request.json()) as SubscriptionWebhook | OrderWebhook;
|
||||||
const rawBody = await reqClone.text();
|
const rawBody = await reqClone.text();
|
||||||
|
|
||||||
|
// if no signature is found, throw an error
|
||||||
if (!signature) {
|
if (!signature) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
eventName,
|
eventName,
|
||||||
},
|
},
|
||||||
@@ -64,8 +68,9 @@ export class LemonSqueezyWebhookHandlerService
|
|||||||
throw new Error('Signature header not found');
|
throw new Error('Signature header not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the signature is invalid, throw an error
|
||||||
if (!isSigningSecretValid(Buffer.from(rawBody), signature)) {
|
if (!isSigningSecretValid(Buffer.from(rawBody), signature)) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
eventName,
|
eventName,
|
||||||
},
|
},
|
||||||
@@ -124,7 +129,9 @@ export class LemonSqueezyWebhookHandlerService
|
|||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
eventType: eventName,
|
eventType: eventName,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
@@ -211,7 +218,9 @@ export class LemonSqueezyWebhookHandlerService
|
|||||||
const { data: order, error } = await getOrder(orderId);
|
const { data: order, error } = await getOrder(orderId);
|
||||||
|
|
||||||
if (error ?? !order) {
|
if (error ?? !order) {
|
||||||
Logger.error(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.error(
|
||||||
{
|
{
|
||||||
orderId,
|
orderId,
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
RetrieveCheckoutSessionSchema,
|
RetrieveCheckoutSessionSchema,
|
||||||
UpdateSubscriptionParamsSchema,
|
UpdateSubscriptionParamsSchema,
|
||||||
} from '@kit/billing/schema';
|
} from '@kit/billing/schema';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
|
|
||||||
import { createStripeBillingPortalSession } from './create-stripe-billing-portal-session';
|
import { createStripeBillingPortalSession } from './create-stripe-billing-portal-session';
|
||||||
import { createStripeCheckout } from './create-stripe-checkout';
|
import { createStripeCheckout } from './create-stripe-checkout';
|
||||||
@@ -24,8 +24,9 @@ export class StripeBillingStrategyService
|
|||||||
params: z.infer<typeof CreateBillingCheckoutSchema>,
|
params: z.infer<typeof CreateBillingCheckoutSchema>,
|
||||||
) {
|
) {
|
||||||
const stripe = await this.stripeProvider();
|
const stripe = await this.stripeProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -37,7 +38,7 @@ export class StripeBillingStrategyService
|
|||||||
const { client_secret } = await createStripeCheckout(stripe, params);
|
const { client_secret } = await createStripeCheckout(stripe, params);
|
||||||
|
|
||||||
if (!client_secret) {
|
if (!client_secret) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -49,7 +50,7 @@ export class StripeBillingStrategyService
|
|||||||
throw new Error('Failed to create checkout session');
|
throw new Error('Failed to create checkout session');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -65,8 +66,9 @@ export class StripeBillingStrategyService
|
|||||||
params: z.infer<typeof CreateBillingPortalSessionSchema>,
|
params: z.infer<typeof CreateBillingPortalSessionSchema>,
|
||||||
) {
|
) {
|
||||||
const stripe = await this.stripeProvider();
|
const stripe = await this.stripeProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -77,7 +79,7 @@ export class StripeBillingStrategyService
|
|||||||
const session = await createStripeBillingPortalSession(stripe, params);
|
const session = await createStripeBillingPortalSession(stripe, params);
|
||||||
|
|
||||||
if (!session?.url) {
|
if (!session?.url) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -85,7 +87,7 @@ export class StripeBillingStrategyService
|
|||||||
'Failed to create billing portal session',
|
'Failed to create billing portal session',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
customerId: params.customerId,
|
customerId: params.customerId,
|
||||||
@@ -101,8 +103,9 @@ export class StripeBillingStrategyService
|
|||||||
params: z.infer<typeof CancelSubscriptionParamsSchema>,
|
params: z.infer<typeof CancelSubscriptionParamsSchema>,
|
||||||
) {
|
) {
|
||||||
const stripe = await this.stripeProvider();
|
const stripe = await this.stripeProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
subscriptionId: params.subscriptionId,
|
subscriptionId: params.subscriptionId,
|
||||||
@@ -115,7 +118,7 @@ export class StripeBillingStrategyService
|
|||||||
invoice_now: params.invoiceNow ?? true,
|
invoice_now: params.invoiceNow ?? true,
|
||||||
});
|
});
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
subscriptionId: params.subscriptionId,
|
subscriptionId: params.subscriptionId,
|
||||||
@@ -125,7 +128,7 @@ export class StripeBillingStrategyService
|
|||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
subscriptionId: params.subscriptionId,
|
subscriptionId: params.subscriptionId,
|
||||||
@@ -142,8 +145,9 @@ export class StripeBillingStrategyService
|
|||||||
params: z.infer<typeof RetrieveCheckoutSessionSchema>,
|
params: z.infer<typeof RetrieveCheckoutSessionSchema>,
|
||||||
) {
|
) {
|
||||||
const stripe = await this.stripeProvider();
|
const stripe = await this.stripeProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
@@ -155,7 +159,7 @@ export class StripeBillingStrategyService
|
|||||||
const session = await stripe.checkout.sessions.retrieve(params.sessionId);
|
const session = await stripe.checkout.sessions.retrieve(params.sessionId);
|
||||||
const isSessionOpen = session.status === 'open';
|
const isSessionOpen = session.status === 'open';
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
@@ -172,7 +176,7 @@ export class StripeBillingStrategyService
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
sessionId: params.sessionId,
|
sessionId: params.sessionId,
|
||||||
@@ -203,8 +207,9 @@ export class StripeBillingStrategyService
|
|||||||
params: z.infer<typeof UpdateSubscriptionParamsSchema>,
|
params: z.infer<typeof UpdateSubscriptionParamsSchema>,
|
||||||
) {
|
) {
|
||||||
const stripe = await this.stripeProvider();
|
const stripe = await this.stripeProvider();
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
...params,
|
...params,
|
||||||
@@ -222,7 +227,7 @@ export class StripeBillingStrategyService
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
...params,
|
...params,
|
||||||
@@ -232,7 +237,7 @@ export class StripeBillingStrategyService
|
|||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: 'billing.stripe',
|
name: 'billing.stripe',
|
||||||
...params,
|
...params,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
BillingWebhookHandlerService,
|
BillingWebhookHandlerService,
|
||||||
getLineItemTypeById,
|
getLineItemTypeById,
|
||||||
} from '@kit/billing';
|
} from '@kit/billing';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
import { StripeServerEnvSchema } from '../schema/stripe-server-env.schema';
|
import { StripeServerEnvSchema } from '../schema/stripe-server-env.schema';
|
||||||
@@ -113,6 +113,8 @@ export class StripeWebhookHandlerService
|
|||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
|
const Logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
Logger.info(
|
||||||
{
|
{
|
||||||
eventType: event.type,
|
eventType: event.type,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'server-only';
|
import 'server-only';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { getSupabaseRouteHandlerClient } from '@kit/supabase/route-handler-client';
|
import { getSupabaseRouteHandlerClient } from '@kit/supabase/route-handler-client';
|
||||||
|
|
||||||
import { RecordChange, Tables } from '../record-change.type';
|
import { RecordChange, Tables } from '../record-change.type';
|
||||||
@@ -10,10 +10,12 @@ export class DatabaseWebhookHandlerService {
|
|||||||
private readonly namespace = 'database-webhook-handler';
|
private readonly namespace = 'database-webhook-handler';
|
||||||
|
|
||||||
async handleWebhook(request: Request, webhooksSecret: string) {
|
async handleWebhook(request: Request, webhooksSecret: string) {
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
const json = await request.clone().json();
|
const json = await request.clone().json();
|
||||||
const { table, type } = json as RecordChange<keyof Tables>;
|
const { table, type } = json as RecordChange<keyof Tables>;
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
table,
|
table,
|
||||||
@@ -40,7 +42,7 @@ export class DatabaseWebhookHandlerService {
|
|||||||
// handle the webhook event based on the table
|
// handle the webhook event based on the table
|
||||||
await service.handleWebhook(json);
|
await service.handleWebhook(json);
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
table,
|
table,
|
||||||
@@ -49,7 +51,7 @@ export class DatabaseWebhookHandlerService {
|
|||||||
'Webhook processed successfully',
|
'Webhook processed successfully',
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
table,
|
table,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { SupabaseClient } from '@supabase/supabase-js';
|
import { SupabaseClient } from '@supabase/supabase-js';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
import { RecordChange, Tables } from '../record-change.type';
|
import { RecordChange, Tables } from '../record-change.type';
|
||||||
@@ -8,7 +8,7 @@ import { RecordChange, Tables } from '../record-change.type';
|
|||||||
export class DatabaseWebhookRouterService {
|
export class DatabaseWebhookRouterService {
|
||||||
constructor(private readonly adminClient: SupabaseClient<Database>) {}
|
constructor(private readonly adminClient: SupabaseClient<Database>) {}
|
||||||
|
|
||||||
handleWebhook(body: RecordChange<keyof Tables>) {
|
async handleWebhook(body: RecordChange<keyof Tables>) {
|
||||||
switch (body.table) {
|
switch (body.table) {
|
||||||
case 'invitations': {
|
case 'invitations': {
|
||||||
const payload = body as RecordChange<typeof body.table>;
|
const payload = body as RecordChange<typeof body.table>;
|
||||||
@@ -23,7 +23,9 @@ export class DatabaseWebhookRouterService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
Logger.warn(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.warn(
|
||||||
{
|
{
|
||||||
table: body.table,
|
table: body.table,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { RedirectType, redirect } from 'next/navigation';
|
|||||||
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { requireUser } from '@kit/supabase/require-user';
|
import { requireUser } from '@kit/supabase/require-user';
|
||||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||||
|
|
||||||
@@ -31,7 +31,8 @@ export async function deletePersonalAccountAction(formData: FormData) {
|
|||||||
const auth = await requireUser(client);
|
const auth = await requireUser(client);
|
||||||
|
|
||||||
if (auth.error) {
|
if (auth.error) {
|
||||||
Logger.error(`User is not authenticated. Redirecting to login page`);
|
const logger = await getLogger();
|
||||||
|
logger.error(`User is not authenticated. Redirecting to login page`);
|
||||||
|
|
||||||
redirect(auth.redirectTo);
|
redirect(auth.redirectTo);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { SupabaseClient } from '@supabase/supabase-js';
|
import { SupabaseClient } from '@supabase/supabase-js';
|
||||||
|
|
||||||
import { Mailer } from '@kit/mailers';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Logger } from '@kit/shared/logger';
|
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,8 +34,9 @@ export class DeletePersonalAccountService {
|
|||||||
};
|
};
|
||||||
}) {
|
}) {
|
||||||
const userId = params.userId;
|
const userId = params.userId;
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{ name: this.namespace, userId },
|
{ name: this.namespace, userId },
|
||||||
'User requested deletion. Processing...',
|
'User requested deletion. Processing...',
|
||||||
);
|
);
|
||||||
@@ -45,7 +45,7 @@ export class DeletePersonalAccountService {
|
|||||||
try {
|
try {
|
||||||
await params.adminClient.auth.admin.deleteUser(userId);
|
await params.adminClient.auth.admin.deleteUser(userId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
userId,
|
userId,
|
||||||
@@ -60,7 +60,7 @@ export class DeletePersonalAccountService {
|
|||||||
// Send account deletion email
|
// Send account deletion email
|
||||||
if (params.userEmail) {
|
if (params.userEmail) {
|
||||||
try {
|
try {
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
userId,
|
userId,
|
||||||
@@ -74,8 +74,16 @@ export class DeletePersonalAccountService {
|
|||||||
userDisplayName: params.userEmail,
|
userDisplayName: params.userEmail,
|
||||||
userEmail: params.userEmail,
|
userEmail: params.userEmail,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
{
|
||||||
|
name: this.namespace,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
`Account deletion email sent`,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
userId,
|
userId,
|
||||||
@@ -94,13 +102,15 @@ export class DeletePersonalAccountService {
|
|||||||
productName: string;
|
productName: string;
|
||||||
}) {
|
}) {
|
||||||
const { renderAccountDeleteEmail } = await import('@kit/email-templates');
|
const { renderAccountDeleteEmail } = await import('@kit/email-templates');
|
||||||
|
const { getMailer } = await import('@kit/mailers');
|
||||||
|
const mailer = await getMailer();
|
||||||
|
|
||||||
const html = renderAccountDeleteEmail({
|
const html = renderAccountDeleteEmail({
|
||||||
userDisplayName: params.userDisplayName,
|
userDisplayName: params.userDisplayName,
|
||||||
productName: params.productName,
|
productName: params.productName,
|
||||||
});
|
});
|
||||||
|
|
||||||
await Mailer.sendEmail({
|
return mailer.sendEmail({
|
||||||
to: params.userEmail,
|
to: params.userEmail,
|
||||||
from: params.fromEmail,
|
from: params.fromEmail,
|
||||||
subject: 'Account Deletion Request',
|
subject: 'Account Deletion Request',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { redirect } from 'next/navigation';
|
|||||||
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { requireUser } from '@kit/supabase/require-user';
|
import { requireUser } from '@kit/supabase/require-user';
|
||||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||||
|
|
||||||
@@ -31,6 +31,7 @@ export async function createOrganizationAccountAction(
|
|||||||
redirect(auth.redirectTo);
|
redirect(auth.redirectTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logger = await getLogger();
|
||||||
const userId = auth.data.id;
|
const userId = auth.data.id;
|
||||||
|
|
||||||
const createAccountResponse = await service.createNewOrganizationAccount({
|
const createAccountResponse = await service.createNewOrganizationAccount({
|
||||||
@@ -39,7 +40,7 @@ export async function createOrganizationAccountAction(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (createAccountResponse.error) {
|
if (createAccountResponse.error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
error: createAccountResponse.error,
|
error: createAccountResponse.error,
|
||||||
@@ -51,6 +52,15 @@ export async function createOrganizationAccountAction(
|
|||||||
throw new Error('Error creating team account');
|
throw new Error('Error creating team account');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
accountName,
|
||||||
|
name: 'accounts',
|
||||||
|
},
|
||||||
|
`Team account created successfully`,
|
||||||
|
);
|
||||||
|
|
||||||
const accountHomePath =
|
const accountHomePath =
|
||||||
TEAM_ACCOUNTS_HOME_PATH + '/' + createAccountResponse.data.slug;
|
TEAM_ACCOUNTS_HOME_PATH + '/' + createAccountResponse.data.slug;
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import { SupabaseClient } from '@supabase/supabase-js';
|
|||||||
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { Mailer } from '@kit/mailers';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Logger } from '@kit/shared/logger';
|
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
type Invitation = Database['public']['Tables']['invitations']['Row'];
|
type Invitation = Database['public']['Tables']['invitations']['Row'];
|
||||||
@@ -57,8 +56,12 @@ export class AccountInvitationsWebhookService {
|
|||||||
throw team.error;
|
throw team.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { renderInviteEmail } = await import('@kit/email-templates');
|
const { renderInviteEmail } = await import('@kit/email-templates');
|
||||||
|
const { getMailer } = await import('@kit/mailers');
|
||||||
|
const mailer = await getMailer();
|
||||||
|
|
||||||
const html = renderInviteEmail({
|
const html = renderInviteEmail({
|
||||||
link: this.getInvitationLink(invitation.invite_token),
|
link: this.getInvitationLink(invitation.invite_token),
|
||||||
@@ -68,26 +71,34 @@ export class AccountInvitationsWebhookService {
|
|||||||
teamName: team.data.name,
|
teamName: team.data.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
await Mailer.sendEmail({
|
await mailer
|
||||||
from: env.emailSender,
|
.sendEmail({
|
||||||
to: invitation.email,
|
from: env.emailSender,
|
||||||
subject: 'You have been invited to join a team',
|
to: invitation.email,
|
||||||
html,
|
subject: 'You have been invited to join a team',
|
||||||
});
|
html,
|
||||||
|
})
|
||||||
Logger.info('Invitation email sent', {
|
.then(() => {
|
||||||
email: invitation.email,
|
logger.info('Invitation email sent', {
|
||||||
account: invitation.account_id,
|
email: invitation.email,
|
||||||
name: this.namespace,
|
account: invitation.account_id,
|
||||||
});
|
name: this.namespace,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
logger.warn(
|
||||||
|
{ error, name: this.namespace },
|
||||||
|
'Failed to send invitation email',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.warn(
|
logger.warn(
|
||||||
{ error, name: this.namespace },
|
{ error, name: this.namespace },
|
||||||
'Failed to send invitation email',
|
'Failed to invite user to team',
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { addDays, formatISO } from 'date-fns';
|
|||||||
import 'server-only';
|
import 'server-only';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
|
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
|
||||||
@@ -17,7 +17,9 @@ export class AccountInvitationsService {
|
|||||||
constructor(private readonly client: SupabaseClient<Database>) {}
|
constructor(private readonly client: SupabaseClient<Database>) {}
|
||||||
|
|
||||||
async deleteInvitation(params: z.infer<typeof DeleteInvitationSchema>) {
|
async deleteInvitation(params: z.infer<typeof DeleteInvitationSchema>) {
|
||||||
Logger.info('Removing invitation', {
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info('Removing invitation', {
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
...params,
|
...params,
|
||||||
});
|
});
|
||||||
@@ -33,7 +35,7 @@ export class AccountInvitationsService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info('Invitation successfully removed', {
|
logger.info('Invitation successfully removed', {
|
||||||
...params,
|
...params,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
});
|
});
|
||||||
@@ -42,7 +44,9 @@ export class AccountInvitationsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateInvitation(params: z.infer<typeof UpdateInvitationSchema>) {
|
async updateInvitation(params: z.infer<typeof UpdateInvitationSchema>) {
|
||||||
Logger.info('Updating invitation', {
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info('Updating invitation', {
|
||||||
...params,
|
...params,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
});
|
});
|
||||||
@@ -60,7 +64,7 @@ export class AccountInvitationsService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info('Invitation successfully updated', {
|
logger.info('Invitation successfully updated', {
|
||||||
...params,
|
...params,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
});
|
});
|
||||||
@@ -75,7 +79,9 @@ export class AccountInvitationsService {
|
|||||||
invitations: z.infer<typeof InviteMembersSchema>['invitations'];
|
invitations: z.infer<typeof InviteMembersSchema>['invitations'];
|
||||||
accountSlug: string;
|
accountSlug: string;
|
||||||
}) {
|
}) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
account: accountSlug,
|
account: accountSlug,
|
||||||
invitations,
|
invitations,
|
||||||
@@ -91,7 +97,7 @@ export class AccountInvitationsService {
|
|||||||
.single();
|
.single();
|
||||||
|
|
||||||
if (!accountResponse.data) {
|
if (!accountResponse.data) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
accountSlug,
|
accountSlug,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
@@ -108,7 +114,7 @@ export class AccountInvitationsService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
accountSlug,
|
accountSlug,
|
||||||
error: response.error,
|
error: response.error,
|
||||||
@@ -124,7 +130,7 @@ export class AccountInvitationsService {
|
|||||||
? response.data
|
? response.data
|
||||||
: [response.data];
|
: [response.data];
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
account: accountSlug,
|
account: accountSlug,
|
||||||
count: responseInvitations.length,
|
count: responseInvitations.length,
|
||||||
@@ -157,7 +163,9 @@ export class AccountInvitationsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async renewInvitation(invitationId: number) {
|
async renewInvitation(invitationId: number) {
|
||||||
Logger.info('Renewing invitation', {
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info('Renewing invitation', {
|
||||||
invitationId,
|
invitationId,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
});
|
});
|
||||||
@@ -177,7 +185,7 @@ export class AccountInvitationsService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info('Invitation successfully renewed', {
|
logger.info('Invitation successfully renewed', {
|
||||||
invitationId,
|
invitationId,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { SupabaseClient } from '@supabase/supabase-js';
|
|||||||
import 'server-only';
|
import 'server-only';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
import { RemoveMemberSchema } from '../../schema/remove-member.schema';
|
import { RemoveMemberSchema } from '../../schema/remove-member.schema';
|
||||||
@@ -17,12 +17,14 @@ export class AccountMembersService {
|
|||||||
constructor(private readonly client: SupabaseClient<Database>) {}
|
constructor(private readonly client: SupabaseClient<Database>) {}
|
||||||
|
|
||||||
async removeMemberFromAccount(params: z.infer<typeof RemoveMemberSchema>) {
|
async removeMemberFromAccount(params: z.infer<typeof RemoveMemberSchema>) {
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
...params,
|
...params,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.info(ctx, `Removing member from account...`);
|
logger.info(ctx, `Removing member from account...`);
|
||||||
|
|
||||||
const { data, error } = await this.client
|
const { data, error } = await this.client
|
||||||
.from('accounts_memberships')
|
.from('accounts_memberships')
|
||||||
@@ -33,7 +35,7 @@ export class AccountMembersService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
...ctx,
|
...ctx,
|
||||||
error,
|
error,
|
||||||
@@ -44,7 +46,7 @@ export class AccountMembersService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
ctx,
|
ctx,
|
||||||
`Successfully removed member from account. Verifying seat count...`,
|
`Successfully removed member from account. Verifying seat count...`,
|
||||||
);
|
);
|
||||||
@@ -57,12 +59,14 @@ export class AccountMembersService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateMemberRole(params: z.infer<typeof UpdateMemberRoleSchema>) {
|
async updateMemberRole(params: z.infer<typeof UpdateMemberRoleSchema>) {
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
...params,
|
...params,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.info(ctx, `Updating member role...`);
|
logger.info(ctx, `Updating member role...`);
|
||||||
|
|
||||||
const { data, error } = await this.client
|
const { data, error } = await this.client
|
||||||
.from('accounts_memberships')
|
.from('accounts_memberships')
|
||||||
@@ -75,7 +79,7 @@ export class AccountMembersService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
...ctx,
|
...ctx,
|
||||||
error,
|
error,
|
||||||
@@ -86,7 +90,7 @@ export class AccountMembersService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(ctx, `Successfully updated member role`);
|
logger.info(ctx, `Successfully updated member role`);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@@ -94,12 +98,14 @@ export class AccountMembersService {
|
|||||||
async transferOwnership(
|
async transferOwnership(
|
||||||
params: z.infer<typeof TransferOwnershipConfirmationSchema>,
|
params: z.infer<typeof TransferOwnershipConfirmationSchema>,
|
||||||
) {
|
) {
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
namespace: this.namespace,
|
namespace: this.namespace,
|
||||||
...params,
|
...params,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.info(ctx, `Transferring ownership of account...`);
|
logger.info(ctx, `Transferring ownership of account...`);
|
||||||
|
|
||||||
const { data, error } = await this.client.rpc(
|
const { data, error } = await this.client.rpc(
|
||||||
'transfer_team_account_ownership',
|
'transfer_team_account_ownership',
|
||||||
@@ -110,7 +116,7 @@ export class AccountMembersService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{ ...ctx, error },
|
{ ...ctx, error },
|
||||||
`Failed to transfer ownership of account`,
|
`Failed to transfer ownership of account`,
|
||||||
);
|
);
|
||||||
@@ -118,7 +124,7 @@ export class AccountMembersService {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(ctx, `Successfully transferred ownership of account`);
|
logger.info(ctx, `Successfully transferred ownership of account`);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { SupabaseClient } from '@supabase/supabase-js';
|
import { SupabaseClient } from '@supabase/supabase-js';
|
||||||
|
|
||||||
import { BillingGatewayService } from '@kit/billing-gateway';
|
import { BillingGatewayService } from '@kit/billing-gateway';
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
export class AccountPerSeatBillingService {
|
export class AccountPerSeatBillingService {
|
||||||
@@ -10,7 +10,9 @@ export class AccountPerSeatBillingService {
|
|||||||
constructor(private readonly client: SupabaseClient<Database>) {}
|
constructor(private readonly client: SupabaseClient<Database>) {}
|
||||||
|
|
||||||
async getPerSeatSubscriptionItem(accountId: string) {
|
async getPerSeatSubscriptionItem(accountId: string) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -36,7 +38,7 @@ export class AccountPerSeatBillingService {
|
|||||||
.maybeSingle();
|
.maybeSingle();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.info(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -49,7 +51,7 @@ export class AccountPerSeatBillingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!data?.subscription_items) {
|
if (!data?.subscription_items) {
|
||||||
Logger.info(
|
logger.info(
|
||||||
{ name: this.namespace, accountId },
|
{ name: this.namespace, accountId },
|
||||||
`No per-seat subscription item found for account ${accountId}. Exiting...`,
|
`No per-seat subscription item found for account ${accountId}. Exiting...`,
|
||||||
);
|
);
|
||||||
@@ -57,7 +59,7 @@ export class AccountPerSeatBillingService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -69,6 +71,7 @@ export class AccountPerSeatBillingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async increaseSeats(accountId: string) {
|
async increaseSeats(accountId: string) {
|
||||||
|
const logger = await getLogger();
|
||||||
const subscription = await this.getPerSeatSubscriptionItem(accountId);
|
const subscription = await this.getPerSeatSubscriptionItem(accountId);
|
||||||
|
|
||||||
if (!subscription) {
|
if (!subscription) {
|
||||||
@@ -85,7 +88,7 @@ export class AccountPerSeatBillingService {
|
|||||||
|
|
||||||
const billingGateway = new BillingGatewayService(subscription.provider);
|
const billingGateway = new BillingGatewayService(subscription.provider);
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -96,7 +99,7 @@ export class AccountPerSeatBillingService {
|
|||||||
|
|
||||||
const promises = subscriptionItems.map(async (item) => {
|
const promises = subscriptionItems.map(async (item) => {
|
||||||
try {
|
try {
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -112,7 +115,7 @@ export class AccountPerSeatBillingService {
|
|||||||
quantity: item.quantity + 1,
|
quantity: item.quantity + 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -122,7 +125,7 @@ export class AccountPerSeatBillingService {
|
|||||||
`Subscription item updated successfully`,
|
`Subscription item updated successfully`,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -137,6 +140,7 @@ export class AccountPerSeatBillingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async decreaseSeats(accountId: string) {
|
async decreaseSeats(accountId: string) {
|
||||||
|
const logger = await getLogger();
|
||||||
const subscription = await this.getPerSeatSubscriptionItem(accountId);
|
const subscription = await this.getPerSeatSubscriptionItem(accountId);
|
||||||
|
|
||||||
if (!subscription) {
|
if (!subscription) {
|
||||||
@@ -151,7 +155,7 @@ export class AccountPerSeatBillingService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -164,7 +168,7 @@ export class AccountPerSeatBillingService {
|
|||||||
|
|
||||||
const promises = subscriptionItems.map(async (item) => {
|
const promises = subscriptionItems.map(async (item) => {
|
||||||
try {
|
try {
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -180,7 +184,7 @@ export class AccountPerSeatBillingService {
|
|||||||
quantity: item.quantity - 1,
|
quantity: item.quantity - 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
@@ -190,7 +194,7 @@ export class AccountPerSeatBillingService {
|
|||||||
`Subscription item updated successfully`,
|
`Subscription item updated successfully`,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId,
|
accountId,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { SupabaseClient } from '@supabase/supabase-js';
|
import { SupabaseClient } from '@supabase/supabase-js';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
export class CreateTeamAccountService {
|
export class CreateTeamAccountService {
|
||||||
@@ -8,13 +8,15 @@ export class CreateTeamAccountService {
|
|||||||
|
|
||||||
constructor(private readonly client: SupabaseClient<Database>) {}
|
constructor(private readonly client: SupabaseClient<Database>) {}
|
||||||
|
|
||||||
createNewOrganizationAccount(params: { name: string; userId: string }) {
|
async createNewOrganizationAccount(params: { name: string; userId: string }) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{ ...params, namespace: this.namespace },
|
{ ...params, namespace: this.namespace },
|
||||||
`Creating new team account...`,
|
`Creating new team account...`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.client.rpc('create_account', {
|
return await this.client.rpc('create_account', {
|
||||||
account_name: params.name,
|
account_name: params.name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { SupabaseClient } from '@supabase/supabase-js';
|
|||||||
|
|
||||||
import 'server-only';
|
import 'server-only';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
export class DeleteTeamAccountService {
|
export class DeleteTeamAccountService {
|
||||||
@@ -24,7 +24,9 @@ export class DeleteTeamAccountService {
|
|||||||
userId: string;
|
userId: string;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
Logger.info(
|
const logger = await getLogger();
|
||||||
|
|
||||||
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId: params.accountId,
|
accountId: params.accountId,
|
||||||
@@ -40,7 +42,7 @@ export class DeleteTeamAccountService {
|
|||||||
.eq('id', params.accountId);
|
.eq('id', params.accountId);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error(
|
logger.error(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId: params.accountId,
|
accountId: params.accountId,
|
||||||
@@ -53,7 +55,7 @@ export class DeleteTeamAccountService {
|
|||||||
throw new Error('Failed to delete team account');
|
throw new Error('Failed to delete team account');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(
|
logger.info(
|
||||||
{
|
{
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
accountId: params.accountId,
|
accountId: params.accountId,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { SupabaseClient } from '@supabase/supabase-js';
|
|||||||
import 'server-only';
|
import 'server-only';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { Logger } from '@kit/shared/logger';
|
import { getLogger } from '@kit/shared/logger';
|
||||||
import { Database } from '@kit/supabase/database';
|
import { Database } from '@kit/supabase/database';
|
||||||
|
|
||||||
const Schema = z.object({
|
const Schema = z.object({
|
||||||
@@ -17,12 +17,14 @@ export class LeaveTeamAccountService {
|
|||||||
constructor(private readonly adminClient: SupabaseClient<Database>) {}
|
constructor(private readonly adminClient: SupabaseClient<Database>) {}
|
||||||
|
|
||||||
async leaveTeamAccount(params: z.infer<typeof Schema>) {
|
async leaveTeamAccount(params: z.infer<typeof Schema>) {
|
||||||
|
const logger = await getLogger();
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
...params,
|
...params,
|
||||||
name: this.namespace,
|
name: this.namespace,
|
||||||
};
|
};
|
||||||
|
|
||||||
Logger.info(ctx, 'Leaving team account');
|
logger.info(ctx, 'Leaving team account...');
|
||||||
|
|
||||||
const { accountId, userId } = Schema.parse(params);
|
const { accountId, userId } = Schema.parse(params);
|
||||||
|
|
||||||
@@ -35,11 +37,11 @@ export class LeaveTeamAccountService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error({ ...ctx, error }, 'Failed to leave team account');
|
logger.error({ ...ctx, error }, 'Failed to leave team account');
|
||||||
|
|
||||||
throw new Error('Failed to leave team account');
|
throw new Error('Failed to leave team account');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info(ctx, 'Successfully left team account');
|
logger.info(ctx, 'Successfully left team account');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,17 @@ MAILER_PROVIDER=cloudflare
|
|||||||
|
|
||||||
### Send an email
|
### Send an email
|
||||||
|
|
||||||
```javascript
|
```tsx
|
||||||
import { Mailer } from '@kit/mailers';
|
import { getMailer } from '@kit/mailers';
|
||||||
|
|
||||||
Mailer.sendEmail({
|
async function sendEmail() {
|
||||||
|
const mailer = await getMailer();
|
||||||
|
|
||||||
|
return mailer.sendEmail({
|
||||||
to: '',
|
to: '',
|
||||||
from: '',
|
from: '',
|
||||||
subject: 'Hello',
|
subject: 'Hello',
|
||||||
text: 'Hello, World!'
|
text: 'Hello, World!'
|
||||||
});
|
});
|
||||||
|
}
|
||||||
```
|
```
|
||||||
@@ -5,28 +5,10 @@ const MAILER_PROVIDER = z
|
|||||||
.default('nodemailer')
|
.default('nodemailer')
|
||||||
.parse(process.env.MAILER_PROVIDER);
|
.parse(process.env.MAILER_PROVIDER);
|
||||||
|
|
||||||
/**
|
|
||||||
* @description A mailer interface that can be implemented by any mailer.
|
|
||||||
* We export a single mailer implementation using Nodemailer. You can add more mailers or replace the existing one.
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* import { Mailer } from '@kit/mailers';
|
|
||||||
*
|
|
||||||
* const mailer = new Mailer();
|
|
||||||
*
|
|
||||||
* mailer.sendEmail({
|
|
||||||
* from: '',
|
|
||||||
* to: '',
|
|
||||||
* subject: 'Hello',
|
|
||||||
* text: 'Hello, World!'
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export const Mailer = await getMailer();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Get the mailer based on the environment variable.
|
* @description Get the mailer based on the environment variable.
|
||||||
*/
|
*/
|
||||||
async function getMailer() {
|
export async function getMailer() {
|
||||||
switch (MAILER_PROVIDER) {
|
switch (MAILER_PROVIDER) {
|
||||||
case 'nodemailer': {
|
case 'nodemailer': {
|
||||||
const { Nodemailer } = await import('./impl/nodemailer');
|
const { Nodemailer } = await import('./impl/nodemailer');
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ const DEFAULT_INSTRUMENTATION_PROVIDER = process.env
|
|||||||
* Please set the MONITORING_INSTRUMENTATION_PROVIDER environment variable to register the monitoring instrumentation provider.
|
* Please set the MONITORING_INSTRUMENTATION_PROVIDER environment variable to register the monitoring instrumentation provider.
|
||||||
*/
|
*/
|
||||||
export async function registerInstrumentation() {
|
export async function registerInstrumentation() {
|
||||||
if (
|
if (!DEFAULT_INSTRUMENTATION_PROVIDER) {
|
||||||
process.env.NEXT_RUNTIME !== 'nodejs' ||
|
console.info(`No instrumentation provider specified. Skipping...`);
|
||||||
!DEFAULT_INSTRUMENTATION_PROVIDER
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,4 @@ async function getLogger(): Promise<LoggerInstance> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Logger = await getLogger();
|
export { getLogger };
|
||||||
|
|
||||||
export { Logger };
|
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Check if the code is running in a browser environment.
|
||||||
|
*/
|
||||||
export function isBrowser() {
|
export function isBrowser() {
|
||||||
return typeof window !== 'undefined';
|
return typeof window !== 'undefined';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@name formatCurrency
|
||||||
|
* @description Format the currency based on the currency code
|
||||||
|
*/
|
||||||
export function formatCurrency(currencyCode: string, value: string | number) {
|
export function formatCurrency(currencyCode: string, value: string | number) {
|
||||||
return new Intl.NumberFormat('en-US', {
|
return new Intl.NumberFormat('en-US', {
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
|
|||||||
86
pnpm-lock.yaml
generated
86
pnpm-lock.yaml
generated
@@ -103,7 +103,7 @@ importers:
|
|||||||
version: 5.28.6(react@18.2.0)
|
version: 5.28.6(react@18.2.0)
|
||||||
'@tanstack/react-query-next-experimental':
|
'@tanstack/react-query-next-experimental':
|
||||||
specifier: ^5.28.14
|
specifier: ^5.28.14
|
||||||
version: 5.28.14(@tanstack/react-query@5.28.6)(next@14.2.0-canary.61)(react@18.2.0)
|
version: 5.28.14(@tanstack/react-query@5.28.6)(next@14.2.0-canary.62)(react@18.2.0)
|
||||||
'@tanstack/react-table':
|
'@tanstack/react-table':
|
||||||
specifier: ^8.15.3
|
specifier: ^8.15.3
|
||||||
version: 8.15.3(react-dom@18.2.0)(react@18.2.0)
|
version: 8.15.3(react-dom@18.2.0)(react@18.2.0)
|
||||||
@@ -112,7 +112,7 @@ importers:
|
|||||||
version: 3.6.0
|
version: 3.6.0
|
||||||
edge-csrf:
|
edge-csrf:
|
||||||
specifier: ^1.0.9
|
specifier: ^1.0.9
|
||||||
version: 1.0.9(next@14.2.0-canary.61)
|
version: 1.0.9(next@14.2.0-canary.62)
|
||||||
i18next:
|
i18next:
|
||||||
specifier: ^23.10.1
|
specifier: ^23.10.1
|
||||||
version: 23.10.1
|
version: 23.10.1
|
||||||
@@ -123,11 +123,11 @@ importers:
|
|||||||
specifier: ^0.363.0
|
specifier: ^0.363.0
|
||||||
version: 0.363.0(react@18.2.0)
|
version: 0.363.0(react@18.2.0)
|
||||||
next:
|
next:
|
||||||
specifier: 14.2.0-canary.61
|
specifier: 14.2.0-canary.62
|
||||||
version: 14.2.0-canary.61(react-dom@18.2.0)(react@18.2.0)
|
version: 14.2.0-canary.62(react-dom@18.2.0)(react@18.2.0)
|
||||||
next-sitemap:
|
next-sitemap:
|
||||||
specifier: ^4.2.3
|
specifier: ^4.2.3
|
||||||
version: 4.2.3(next@14.2.0-canary.61)
|
version: 4.2.3(next@14.2.0-canary.62)
|
||||||
next-themes:
|
next-themes:
|
||||||
specifier: 0.3.0
|
specifier: 0.3.0
|
||||||
version: 0.3.0(react-dom@18.2.0)(react@18.2.0)
|
version: 0.3.0(react-dom@18.2.0)(react@18.2.0)
|
||||||
@@ -2302,8 +2302,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==}
|
resolution: {integrity: sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@next/env@14.2.0-canary.61:
|
/@next/env@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-Ueqse8kdwaoebGrpSo60M4/cjFaMJEE7BMsKZufYwZDTlE0qXw7N4GsdVpUZzJG00sXf6CoTnCU1lCTPrUMC4g==}
|
resolution: {integrity: sha512-K5lmKK/TalagQELw3W0hKDXmNGGXY3Zxw3yH27y9DOT7evhiJvK2Ywq5uN4lEjYHkeW+QbyC/OjUIcK3RUSHbQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@next/eslint-plugin-next@14.1.4:
|
/@next/eslint-plugin-next@14.1.4:
|
||||||
@@ -2330,8 +2330,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-darwin-arm64@14.2.0-canary.61:
|
/@next/swc-darwin-arm64@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-mMlp2/hvtaBbCY5qYhuvAqX9Z/aFC+Rgme4FjFSxq2C3TC/mL3G4fVG/TVl7bqjikKCxSvJgiWXRwvhIaqGktw==}
|
resolution: {integrity: sha512-Cm53nqD/u7I1wo4xeULBZ6YjThK7Mk+ThaoYJu69varPPHsahpzbf/rM3ZkW3UB5Cgl5I7N3mNIb+Z9U/JZemw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
@@ -2357,8 +2357,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-darwin-x64@14.2.0-canary.61:
|
/@next/swc-darwin-x64@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-4bEjO0WK6keRi972eAY1AfvTXOQRHnM59klNqnUh5zfalbi7VkEdluhYAZOop2NycCHjF+m8p+ytYtrF1uCO1Q==}
|
resolution: {integrity: sha512-2cSC0EOiJHe9kQad5TR/tXJuIc85JLBUeRl4x20jdsa0oIuOdsvksPA9TAROWLebuIkysPAsfmrbCwlKZk5yDw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
@@ -2384,8 +2384,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-linux-arm64-gnu@14.2.0-canary.61:
|
/@next/swc-linux-arm64-gnu@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-wIXc3EdxrETlL2XwlGlLQkMU9godhNSMAXxiJotd/mhN3K4iKajPahAStvFxY2Zwc/on2IBa0NpUGpzDONNt9A==}
|
resolution: {integrity: sha512-Iow3tpn05nK2hW1nBzk1rCEVgbwakvlPViFZMxYg4FxEEoIcxcsxTMnG7sjJGmgrzCW7vfCVc+AM3Gy6bZXxqg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@@ -2411,8 +2411,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-linux-arm64-musl@14.2.0-canary.61:
|
/@next/swc-linux-arm64-musl@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-95aMF55sq2N6+5iLEqxCfz7ccYMBURQ8D0KYmcq+rMJTE5z/qvxEToSJWAbV4jGyd2Eq/vXjPdR1rFytv2FnOw==}
|
resolution: {integrity: sha512-dTugxbWEi95dNFn59C7RYuNTJ2jOVbDgD9lJmFtAJO46XPtN8IySJSe/5zB9YECA1apK2xWf5XaSbpuh5vWT8Q==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@@ -2438,8 +2438,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-linux-x64-gnu@14.2.0-canary.61:
|
/@next/swc-linux-x64-gnu@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-LWG5OC9hNSCYtDb+7MQcIjE1PO70Sho+ZJkqJnmLxJ08Atp/nJQBo9nAMjORdcO5Nz+hPNVY5vmrY+5Fl5kadw==}
|
resolution: {integrity: sha512-yGKHq4PfPgQO+IVWVOxbdv5pdIib/jwr62NsPKbY+t16gDB6RNTPhOcuhkQTvDBYlh+VF3vmhenlM5Ci0W5QQQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@@ -2465,8 +2465,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-linux-x64-musl@14.2.0-canary.61:
|
/@next/swc-linux-x64-musl@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-EjOXbSmDTPVi8xkOix4/WYJM6OUert+lfBtdUJBRba+oGiRw/mheih8FliFZKFOmQbPYj67A9z/QCus2ZDnfSw==}
|
resolution: {integrity: sha512-Nw/l0Z4jzAL5VP1Z2mjNAMF7n+9aOTZgFJCtJ6C0aBf5rvZY3BrVDXblK57v6q1bWqU6FRGYmDava3h4B2i0hQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@@ -2492,8 +2492,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-win32-arm64-msvc@14.2.0-canary.61:
|
/@next/swc-win32-arm64-msvc@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-TK8oV4ozzUGWAwvZp/0SBsNgAUhrUFLWCMSXsFHz+YMRjHg7nT0KdK8BYh2Ln4Qt0jjDTUHbI1jaQKxmSMEMmA==}
|
resolution: {integrity: sha512-FgS+pzblgiGe1iA2zvIxH5FTz/NVkXknhVgE3g0A5pIQeIfHn5hbki501fCBKvYujhsP094pSGePI9Hi35KFYA==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@@ -2519,8 +2519,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-win32-ia32-msvc@14.2.0-canary.61:
|
/@next/swc-win32-ia32-msvc@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-i0iWCehuLKDOfVbQ6MEKG9v0lfcJU0DPWkYINFSi6p3fkFobI/+7DVT3KvYH5VVng/+opx+pA6cesV5eyQnBtw==}
|
resolution: {integrity: sha512-1cns8tyYICpspnhVC6FoRmd2Nal7uSXLPW4l1jX0+ofpifcmRy6Lra127/kdl8l+00W6ERQ/QAhx8uiYrw3VGQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@@ -2546,8 +2546,8 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@next/swc-win32-x64-msvc@14.2.0-canary.61:
|
/@next/swc-win32-x64-msvc@14.2.0-canary.62:
|
||||||
resolution: {integrity: sha512-WB0UjpWcu+oXQOMFDTHDZWKcL2jiXeQfN+1RRkb0x7ZjVxvA/O66vOJE08fLSu7rdymLiGXxX+AKlGFq1Tpisg==}
|
resolution: {integrity: sha512-67gfnbOVzVrg4lsRhE9qHQegpPl/ljHMNFw4JyIOlLmCG7daHe6wgKmXGAyYBSZ6F6P9HiQWHcqU/qTHtw2lFw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@@ -5038,7 +5038,7 @@ packages:
|
|||||||
/@tanstack/query-core@5.28.6:
|
/@tanstack/query-core@5.28.6:
|
||||||
resolution: {integrity: sha512-hnhotV+DnQtvtR3jPvbQMPNMW4KEK0J4k7c609zJ8muiNknm+yoDyMHmxTWM5ZnlZpsz0zOxYFr+mzRJNHWJsA==}
|
resolution: {integrity: sha512-hnhotV+DnQtvtR3jPvbQMPNMW4KEK0J4k7c609zJ8muiNknm+yoDyMHmxTWM5ZnlZpsz0zOxYFr+mzRJNHWJsA==}
|
||||||
|
|
||||||
/@tanstack/react-query-next-experimental@5.28.14(@tanstack/react-query@5.28.6)(next@14.2.0-canary.61)(react@18.2.0):
|
/@tanstack/react-query-next-experimental@5.28.14(@tanstack/react-query@5.28.6)(next@14.2.0-canary.62)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-gGHx3uJkZNYYpFNFk8eEo96ssiFE2OmYA49wszHxHrtO5nL7kzRcnJF8SALGpqSEjo5D3fLMH24MrhbBsO0sig==}
|
resolution: {integrity: sha512-gGHx3uJkZNYYpFNFk8eEo96ssiFE2OmYA49wszHxHrtO5nL7kzRcnJF8SALGpqSEjo5D3fLMH24MrhbBsO0sig==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@tanstack/react-query': ^5.28.14
|
'@tanstack/react-query': ^5.28.14
|
||||||
@@ -5046,7 +5046,7 @@ packages:
|
|||||||
react: ^18.0.0
|
react: ^18.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tanstack/react-query': 5.28.6(react@18.2.0)
|
'@tanstack/react-query': 5.28.6(react@18.2.0)
|
||||||
next: 14.2.0-canary.61(react-dom@18.2.0)(react@18.2.0)
|
next: 14.2.0-canary.62(react-dom@18.2.0)(react@18.2.0)
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@@ -6858,12 +6858,12 @@ packages:
|
|||||||
/eastasianwidth@0.2.0:
|
/eastasianwidth@0.2.0:
|
||||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||||
|
|
||||||
/edge-csrf@1.0.9(next@14.2.0-canary.61):
|
/edge-csrf@1.0.9(next@14.2.0-canary.62):
|
||||||
resolution: {integrity: sha512-3F89YTh42UDdISr3s9AEcgJDLi4ysgjGfnybzF0LuZGaG2W31h1ZwgWwEQBLMj04lAklcP4XHZYi7vk9o8zcbg==}
|
resolution: {integrity: sha512-3F89YTh42UDdISr3s9AEcgJDLi4ysgjGfnybzF0LuZGaG2W31h1ZwgWwEQBLMj04lAklcP4XHZYi7vk9o8zcbg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
next: ^13.0.0 || ^14.0.0
|
next: ^13.0.0 || ^14.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
next: 14.2.0-canary.61(react-dom@18.2.0)(react@18.2.0)
|
next: 14.2.0-canary.62(react-dom@18.2.0)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/editorconfig@1.0.4:
|
/editorconfig@1.0.4:
|
||||||
@@ -9648,7 +9648,7 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/next-sitemap@4.2.3(next@14.2.0-canary.61):
|
/next-sitemap@4.2.3(next@14.2.0-canary.62):
|
||||||
resolution: {integrity: sha512-vjdCxeDuWDzldhCnyFCQipw5bfpl4HmZA7uoo3GAaYGjGgfL4Cxb1CiztPuWGmS+auYs7/8OekRS8C2cjdAsjQ==}
|
resolution: {integrity: sha512-vjdCxeDuWDzldhCnyFCQipw5bfpl4HmZA7uoo3GAaYGjGgfL4Cxb1CiztPuWGmS+auYs7/8OekRS8C2cjdAsjQ==}
|
||||||
engines: {node: '>=14.18'}
|
engines: {node: '>=14.18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -9659,7 +9659,7 @@ packages:
|
|||||||
'@next/env': 13.5.6
|
'@next/env': 13.5.6
|
||||||
fast-glob: 3.3.2
|
fast-glob: 3.3.2
|
||||||
minimist: 1.2.8
|
minimist: 1.2.8
|
||||||
next: 14.2.0-canary.61(react-dom@18.2.0)(react@18.2.0)
|
next: 14.2.0-canary.62(react-dom@18.2.0)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/next-themes@0.3.0(react-dom@18.2.0)(react@18.2.0):
|
/next-themes@0.3.0(react-dom@18.2.0)(react@18.2.0):
|
||||||
@@ -9751,8 +9751,8 @@ packages:
|
|||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/next@14.2.0-canary.61(react-dom@18.2.0)(react@18.2.0):
|
/next@14.2.0-canary.62(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-UbdoNkGX04TO0Q0N3k7fmiNCliE1yihVBHd/nwg2zMnpjB6dGU3r1UNgCBpfUUlrs1t19FAWazfVQANOOfBT4w==}
|
resolution: {integrity: sha512-SsS+fpJ/anrtLgeCC76V9WOlreZanUYsuKsRMx+FDwOJ3ZnbZkohu3+RRLIQM1vtWcp707iV11+OlF/qgOldCA==}
|
||||||
engines: {node: '>=18.17.0'}
|
engines: {node: '>=18.17.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -9769,7 +9769,7 @@ packages:
|
|||||||
sass:
|
sass:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@next/env': 14.2.0-canary.61
|
'@next/env': 14.2.0-canary.62
|
||||||
'@swc/helpers': 0.5.5
|
'@swc/helpers': 0.5.5
|
||||||
busboy: 1.6.0
|
busboy: 1.6.0
|
||||||
caniuse-lite: 1.0.30001600
|
caniuse-lite: 1.0.30001600
|
||||||
@@ -9779,15 +9779,15 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
styled-jsx: 5.1.1(react@18.2.0)
|
styled-jsx: 5.1.1(react@18.2.0)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@next/swc-darwin-arm64': 14.2.0-canary.61
|
'@next/swc-darwin-arm64': 14.2.0-canary.62
|
||||||
'@next/swc-darwin-x64': 14.2.0-canary.61
|
'@next/swc-darwin-x64': 14.2.0-canary.62
|
||||||
'@next/swc-linux-arm64-gnu': 14.2.0-canary.61
|
'@next/swc-linux-arm64-gnu': 14.2.0-canary.62
|
||||||
'@next/swc-linux-arm64-musl': 14.2.0-canary.61
|
'@next/swc-linux-arm64-musl': 14.2.0-canary.62
|
||||||
'@next/swc-linux-x64-gnu': 14.2.0-canary.61
|
'@next/swc-linux-x64-gnu': 14.2.0-canary.62
|
||||||
'@next/swc-linux-x64-musl': 14.2.0-canary.61
|
'@next/swc-linux-x64-musl': 14.2.0-canary.62
|
||||||
'@next/swc-win32-arm64-msvc': 14.2.0-canary.61
|
'@next/swc-win32-arm64-msvc': 14.2.0-canary.62
|
||||||
'@next/swc-win32-ia32-msvc': 14.2.0-canary.61
|
'@next/swc-win32-ia32-msvc': 14.2.0-canary.62
|
||||||
'@next/swc-win32-x64-msvc': 14.2.0-canary.61
|
'@next/swc-win32-x64-msvc': 14.2.0-canary.62
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
|
|||||||
Reference in New Issue
Block a user