mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
refactor(console): add get tenant add-on-skus endpoint (#6886)
* refactor(console): add get tenant add-on-skus endpoint dynamicly display token usage tooltips content based on the token add-on SKU details * fix: fix email connector ts error fix email connector ts error
This commit is contained in:
parent
8fc5e250e6
commit
a6aa235289
27 changed files with 118 additions and 62 deletions
|
@ -52,7 +52,7 @@
|
|||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@logto/cloud": "0.2.5-5e334eb",
|
||||
"@logto/cloud": "0.2.5-aac51e9",
|
||||
"@silverhand/eslint-config": "6.0.1",
|
||||
"@silverhand/ts-config": "6.0.0",
|
||||
"@types/node": "^20.11.20",
|
||||
|
|
|
@ -40,8 +40,6 @@ const sendMessage =
|
|||
body: {
|
||||
data: {
|
||||
to,
|
||||
// TODO @wangsijie: fix this circular dependency, the connector-kit type change should be released first
|
||||
// @ts-expect-error circular dependency
|
||||
type,
|
||||
payload: {
|
||||
...payload,
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
"devDependencies": {
|
||||
"@fontsource/roboto-mono": "^5.0.0",
|
||||
"@jest/types": "^29.5.0",
|
||||
"@logto/cloud": "0.2.5-5e334eb",
|
||||
"@logto/cloud": "0.2.5-aac51e9",
|
||||
"@logto/connector-kit": "workspace:^4.1.0",
|
||||
"@logto/core-kit": "workspace:^2.5.0",
|
||||
"@logto/language-kit": "workspace:^1.1.0",
|
||||
|
|
|
@ -11,6 +11,10 @@ export type LogtoSkuResponse = GetArrayElementType<GuardedResponse<GetRoutes['/a
|
|||
|
||||
export type Subscription = GuardedResponse<GetRoutes['/api/tenants/:tenantId/subscription']>;
|
||||
|
||||
export type TenantUsageAddOnSkus = GuardedResponse<
|
||||
GetRoutes['/api/tenants/:tenantId/subscription/add-on-skus']
|
||||
>;
|
||||
|
||||
/* ===== Use `New` in the naming to avoid confusion with legacy types ===== */
|
||||
export type NewSubscriptionUsageResponse = GuardedResponse<
|
||||
GetRoutes['/api/tenants/:tenantId/subscription-usage']
|
||||
|
|
|
@ -5,6 +5,7 @@ import { useContext } from 'react';
|
|||
import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
import Tip from '@/assets/icons/tip.svg?react';
|
||||
import { type LogtoSkuResponse } from '@/cloud/types/router';
|
||||
import { addOnPricingExplanationLink } from '@/consts/external-links';
|
||||
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
|
||||
import DynamicT from '@/ds-components/DynamicT';
|
||||
|
@ -60,6 +61,30 @@ const formatNumberTypedUsageDescription = ({
|
|||
return `${formatNumber(usage)} / ${unlimitedString}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* The price unit returned from DB is cent, so we need to divide it by 100 to get the dollar price.
|
||||
*/
|
||||
const formatDecimalPrice = (price: number): string => {
|
||||
return (price / 100).toFixed(2);
|
||||
};
|
||||
|
||||
// Manually format the quota display for add-on usages
|
||||
const formatAddOnQuota = (quota?: LogtoSkuResponse['quota']) => {
|
||||
if (!quota) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
...quota,
|
||||
...conditional(quota.tokenLimit && { tokenLimit: formatQuotaNumber(quota.tokenLimit) }),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param unitPrice Hardcoded add-on unit price. Only used for the tooltip.
|
||||
* @param usageAddOnSku The add-on SKU object. Only used for the tooltip.
|
||||
* If provided, use the unit price and count from the SKU object first. Otherwise, fallback to the hardcoded unit price.
|
||||
*/
|
||||
export type Props = {
|
||||
readonly usage: number | boolean;
|
||||
readonly quota?: Nullable<number> | boolean;
|
||||
|
@ -70,6 +95,7 @@ export type Props = {
|
|||
readonly unitPrice: number;
|
||||
readonly className?: string;
|
||||
readonly isQuotaNoticeHidden?: boolean;
|
||||
readonly usageAddOnSku?: LogtoSkuResponse;
|
||||
};
|
||||
|
||||
function PlanUsageCard({
|
||||
|
@ -82,6 +108,7 @@ function PlanUsageCard({
|
|||
tooltipKey,
|
||||
className,
|
||||
isQuotaNoticeHidden,
|
||||
usageAddOnSku,
|
||||
}: Props) {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const {
|
||||
|
@ -109,12 +136,15 @@ function PlanUsageCard({
|
|||
}}
|
||||
>
|
||||
{t(tooltipKey, {
|
||||
price: unitPrice,
|
||||
price: usageAddOnSku?.unitPrice
|
||||
? formatDecimalPrice(usageAddOnSku.unitPrice)
|
||||
: unitPrice,
|
||||
...conditional(
|
||||
typeof basicQuota === 'number' && {
|
||||
basicQuota: formatQuotaNumber(basicQuota),
|
||||
}
|
||||
),
|
||||
...conditional(usageAddOnSku && formatAddOnQuota(usageAddOnSku.quota)),
|
||||
})}
|
||||
</Trans>
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
type NewSubscriptionPeriodicUsage,
|
||||
type NewSubscriptionCountBasedUsage,
|
||||
type NewSubscriptionQuota,
|
||||
type TenantUsageAddOnSkus,
|
||||
} from '@/cloud/types/router';
|
||||
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
|
||||
import DynamicT from '@/ds-components/DynamicT';
|
||||
|
@ -26,6 +27,7 @@ import {
|
|||
|
||||
type Props = {
|
||||
readonly periodicUsage: NewSubscriptionPeriodicUsage | undefined;
|
||||
readonly usageAddOnSkus?: TenantUsageAddOnSkus;
|
||||
};
|
||||
|
||||
const getUsageByKey = (
|
||||
|
@ -57,7 +59,7 @@ const getUsageByKey = (
|
|||
return countBasedUsage[key];
|
||||
};
|
||||
|
||||
function PlanUsage({ periodicUsage }: Props) {
|
||||
function PlanUsage({ periodicUsage, usageAddOnSkus }: Props) {
|
||||
const {
|
||||
currentSubscriptionQuota,
|
||||
currentSubscriptionBasicQuota,
|
||||
|
@ -87,6 +89,8 @@ function PlanUsage({ periodicUsage }: Props) {
|
|||
usageKey: 'subscription.usage.usage_description_with_limited_quota',
|
||||
titleKey: `subscription.usage.${titleKeyMap[key]}`,
|
||||
unitPrice: usageKeyPriceMap[key],
|
||||
// Only support tokenLimit for now
|
||||
usageAddOnSku: cond(key === 'tokenLimit' && usageAddOnSkus?.[key]),
|
||||
...cond(
|
||||
// We only show the usage card for MAU and token for Free plan
|
||||
(key === 'tokenLimit' || key === 'mauLimit' || isPaidTenant) && {
|
||||
|
|
|
@ -64,7 +64,6 @@ const useSubscribe = () => {
|
|||
const { redirectUri, sessionId } = await cloudApi.post('/api/checkout-session', {
|
||||
body: {
|
||||
skuId,
|
||||
planId,
|
||||
successCallbackUrl,
|
||||
tenantId,
|
||||
tenantName: tenantData?.name,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useContext, useMemo } from 'react';
|
||||
|
||||
import { type NewSubscriptionPeriodicUsage } from '@/cloud/types/router';
|
||||
import { type TenantUsageAddOnSkus, type NewSubscriptionPeriodicUsage } from '@/cloud/types/router';
|
||||
import BillInfo from '@/components/BillInfo';
|
||||
import FormCard from '@/components/FormCard';
|
||||
import PlanDescription from '@/components/PlanDescription';
|
||||
|
@ -17,9 +17,10 @@ import styles from './index.module.scss';
|
|||
|
||||
type Props = {
|
||||
readonly periodicUsage?: NewSubscriptionPeriodicUsage;
|
||||
readonly usageAddOnSkus?: TenantUsageAddOnSkus;
|
||||
};
|
||||
|
||||
function CurrentPlan({ periodicUsage }: Props) {
|
||||
function CurrentPlan({ periodicUsage, usageAddOnSkus }: Props) {
|
||||
const {
|
||||
currentSku: { unitPrice },
|
||||
currentSubscription: { upcomingInvoice, isEnterprisePlan, planId },
|
||||
|
@ -49,7 +50,7 @@ function CurrentPlan({ periodicUsage }: Props) {
|
|||
</div>
|
||||
</div>
|
||||
<FormField title="subscription.plan_usage">
|
||||
<PlanUsage periodicUsage={periodicUsage} />
|
||||
<PlanUsage periodicUsage={periodicUsage} usageAddOnSkus={usageAddOnSkus} />
|
||||
</FormField>
|
||||
<FormField title="subscription.next_bill">
|
||||
<BillInfo cost={upcomingCost} isManagePaymentVisible={Boolean(upcomingCost)} />
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { type ResponseError } from '@withtyped/client';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import { type TenantUsageAddOnSkus, type NewSubscriptionPeriodicUsage } from '@/cloud/types/router';
|
||||
import PageMeta from '@/components/PageMeta';
|
||||
import { isCloud } from '@/consts/env';
|
||||
import { isCloud, isDevFeaturesEnabled } from '@/consts/env';
|
||||
import { SubscriptionDataContext } from '@/contexts/SubscriptionDataProvider';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
import { pickupFeaturedLogtoSkus } from '@/utils/subscription';
|
||||
|
@ -23,14 +25,27 @@ function Subscription() {
|
|||
|
||||
const reservedSkus = pickupFeaturedLogtoSkus(logtoSkus);
|
||||
|
||||
const { data: periodicUsage, isLoading } = useSWR(
|
||||
isCloud && `/api/tenants/${currentTenantId}/subscription/periodic-usage`,
|
||||
async () =>
|
||||
cloudApi.get(`/api/tenants/:tenantId/subscription/periodic-usage`, {
|
||||
params: { tenantId: currentTenantId },
|
||||
})
|
||||
const { data: periodicUsage, error: periodicUsageError } = useSWR<
|
||||
NewSubscriptionPeriodicUsage,
|
||||
ResponseError
|
||||
>(isCloud && `/api/tenants/${currentTenantId}/subscription/periodic-usage`, async () =>
|
||||
cloudApi.get(`/api/tenants/:tenantId/subscription/periodic-usage`, {
|
||||
params: { tenantId: currentTenantId },
|
||||
})
|
||||
);
|
||||
|
||||
const { data: usageAddOnSkus, error: usageAddOnSkusError } = useSWR<
|
||||
TenantUsageAddOnSkus,
|
||||
ResponseError
|
||||
>(isCloud && isDevFeaturesEnabled && `/api/tenants/${currentTenantId}/add-on-skus`, async () =>
|
||||
cloudApi.get(`/api/tenants/:tenantId/subscription/add-on-skus`, {
|
||||
params: { tenantId: currentTenantId },
|
||||
})
|
||||
);
|
||||
|
||||
const isLoading =
|
||||
(!periodicUsage && !periodicUsageError) || (!usageAddOnSkus && !usageAddOnSkusError);
|
||||
|
||||
useEffect(() => {
|
||||
if (isCloud) {
|
||||
onCurrentSubscriptionUpdated();
|
||||
|
@ -55,7 +70,7 @@ function Subscription() {
|
|||
return (
|
||||
<div className={styles.container}>
|
||||
<PageMeta titleKey={['tenants.tabs.subscription', 'tenants.title']} />
|
||||
<CurrentPlan periodicUsage={periodicUsage} />
|
||||
<CurrentPlan periodicUsage={periodicUsage} usageAddOnSkus={usageAddOnSkus} />
|
||||
<PlanComparisonTable />
|
||||
<SwitchPlanActionBar
|
||||
currentSkuId={currentSku.id}
|
||||
|
|
|
@ -99,7 +99,7 @@
|
|||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@logto/cloud": "0.2.5-5e334eb",
|
||||
"@logto/cloud": "0.2.5-aac51e9",
|
||||
"@silverhand/eslint-config": "6.0.1",
|
||||
"@silverhand/ts-config": "6.0.0",
|
||||
"@types/adm-zip": "^0.5.5",
|
||||
|
|
|
@ -47,7 +47,8 @@ const usage = {
|
|||
tokens: {
|
||||
title: 'الرموز',
|
||||
description: '{{usage}}',
|
||||
tooltip: 'ميزة إضافية بسعر قدره ${{price, number}} لكل مليون رمز. الرموز الأولى مليون مشمولة.',
|
||||
tooltip:
|
||||
'ميزة إضافية بسعر ${{price, number}} لكل {{tokenLimit}} توكن. أول {{basicQuota}} توكن مشمولة.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'الخطافات',
|
||||
|
|
|
@ -48,7 +48,7 @@ const usage = {
|
|||
title: 'Tokens',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Zusatzfeature zu einem Preis von ${{price, number}} pro Million Tokens. Die ersten 1 Million Tokens sind inklusive.',
|
||||
'Zusatzfeature zu einem Preis von ${{price, number}} pro {{tokenLimit}} Tokens. Die ersten {{basicQuota}} Tokens sind inklusive.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Hooks',
|
||||
|
|
|
@ -61,9 +61,9 @@ const usage = {
|
|||
tokens: {
|
||||
title: 'Tokens',
|
||||
tooltip:
|
||||
'Add-on feature priced at ${{price, number}} per million tokens. The first 1 million tokens is included.',
|
||||
'Add-on feature priced at ${{price, number}} per {{tokenLimit}} tokens. The first {{basicQuota}} tokens is included.',
|
||||
tooltip_for_enterprise:
|
||||
'The first {{basicQuota}} tokens is included and free to use in your contract-based plan. If you need more, ${{price, number}} per million tokens per month.',
|
||||
'The first {{basicQuota}} tokens is included and free to use in your contract-based plan. If you need more, ${{price, number}} per {{tokenLimit}} tokens per month.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Hooks',
|
||||
|
|
|
@ -48,7 +48,7 @@ const usage = {
|
|||
title: 'Tokens',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Función adicional con un precio de ${{price, number}} por millón de tokens. El primer millón de tokens está incluido.',
|
||||
'Función adicional con un precio de ${{price, number}} por {{tokenLimit}} de tokens. El primer {{basicQuota}} de tokens está incluido.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Ganchos',
|
||||
|
|
|
@ -49,7 +49,7 @@ const usage = {
|
|||
title: 'Jetons',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Fonctionnalité en supplément au prix de ${{price, number}} par million de jetons. Le premier million de jetons est inclus.',
|
||||
'Fonctionnalité en supplément au prix de ${{price, number}} par {{tokenLimit}} de jetons. Le premier {{basicQuota}} de jetons est inclus.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Hooks',
|
||||
|
|
|
@ -49,7 +49,7 @@ const usage = {
|
|||
title: 'Token',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Funzionalità aggiuntiva con un prezzo di ${{price, number}} per milione di token. Il primo milione di token è incluso.',
|
||||
'Funzionalità aggiuntiva con un prezzo di ${{price, number}} per {{tokenLimit}} di token. Il primo {{basicQuota}} di token è incluso.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Hook',
|
||||
|
|
|
@ -48,7 +48,7 @@ const usage = {
|
|||
title: 'トークン',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'追加機能として、100 万トークンにつき {{price, number}} ドルの料金です。最初の 100 万トークンは含まれています。',
|
||||
'追加機能として、{{tokenLimit}} トークンにつき {{price, number}} ドルの料金です。最初の {{basicQuota}} トークンは含まれています。',
|
||||
},
|
||||
hooks: {
|
||||
title: 'フック',
|
||||
|
|
|
@ -53,7 +53,8 @@ const usage = {
|
|||
hooks: {
|
||||
title: '훅',
|
||||
description: '{{usage}} <span>(처음 10개는 무료)</span>',
|
||||
tooltip: '훅 하나당 ${{price, number}} 의 추가 기능입니다. 처음 10개의 훅이 포함되어 있습니다.',
|
||||
tooltip:
|
||||
'추가 기능은 ${{price, number}}에 {{tokenLimit}} 토큰당 가격이 책정됩니다. 처음 {{basicQuota}} 토큰이 포함되어 있습니다.',
|
||||
},
|
||||
pricing: {
|
||||
add_on_changes_in_current_cycle_notice:
|
||||
|
|
|
@ -48,7 +48,7 @@ const usage = {
|
|||
title: 'Tokeny',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Funkcja dodatkowa w cenie ${{price, number}} za milion tokenów. Pierwszy 1 milion tokenów jest wliczony.',
|
||||
'Funkcja dodatkowa w cenie ${{price, number}} za {{tokenLimit}} tokenów. Pierwszy {{basicQuota}} tokenów jest wliczony.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Haki',
|
||||
|
|
|
@ -48,7 +48,7 @@ const usage = {
|
|||
title: 'Tokens',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Recurso adicional com preço de ${{price, number}} por milhão de tokens. O primeiro 1 milhão de tokens está incluído.',
|
||||
'Recurso adicional com preço de ${{price, number}} por {{tokenLimit}} de tokens. O primeiro {{basicQuota}} de tokens está incluído.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Hooks',
|
||||
|
|
|
@ -48,7 +48,7 @@ const usage = {
|
|||
title: 'Tokens',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Funcionalidade adicional com um preço de ${{price, number}} por milhão de tokens. O primeiro milhão de tokens está incluído.',
|
||||
'Funcionalidade adicional com um preço de ${{price, number}} por {{tokenLimit}} de tokens. O primeiro {{basicQuota}} de tokens está incluído.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Hooks',
|
||||
|
|
|
@ -48,7 +48,7 @@ const usage = {
|
|||
title: 'Токены',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Дополнительная функция с ценой ${{price, number}} за миллион токенов. Первые 1 миллион токенов включены.',
|
||||
'Дополнительная функция с ценой ${{price, number}} за {{tokenLimit}} токенов. Первые 1 {{basicQuota}} токенов включены.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Хуки',
|
||||
|
|
|
@ -48,7 +48,7 @@ const usage = {
|
|||
title: 'Tokenler',
|
||||
description: '{{usage}}',
|
||||
tooltip:
|
||||
'Milyon token başına {{price, number}} $ ücretle ek özellik. İlk 1 milyon token dahildir.',
|
||||
'{{tokenLimit}} token başına {{price, number}} $ ücretle ek özellik. İlk 1 {{basicQuota}} token dahildir.',
|
||||
},
|
||||
hooks: {
|
||||
title: 'Hooklar',
|
||||
|
|
|
@ -42,7 +42,8 @@ const usage = {
|
|||
tokens: {
|
||||
title: '令牌',
|
||||
description: '{{usage}}',
|
||||
tooltip: '附加功能,每百万个令牌价格为 ${{price, number}} 。首百万个令牌包含在内。',
|
||||
tooltip:
|
||||
'附加功能,每 {{tokenLimit}} 个令牌价格为 ${{price, number}} 。首 {{basicQuota}} 个令牌包含在内。',
|
||||
},
|
||||
hooks: {
|
||||
title: '钩子',
|
||||
|
|
|
@ -42,7 +42,8 @@ const usage = {
|
|||
tokens: {
|
||||
title: '令牌',
|
||||
description: '{{usage}}',
|
||||
tooltip: '附加功能,每百萬次令牌 ${{price, number}}。首百萬次令牌已包含在內。',
|
||||
tooltip:
|
||||
'附加功能,每 {{tokenLimit}} 次令牌 ${{price, number}}。首 {{basicQuota}} 次令牌已包含在內。',
|
||||
},
|
||||
hooks: {
|
||||
title: '鉤子',
|
||||
|
|
|
@ -42,7 +42,8 @@ const usage = {
|
|||
tokens: {
|
||||
title: '令牌',
|
||||
description: '{{usage}}',
|
||||
tooltip: '附加功能,每百萬令牌 ${{price, number}}。前 1 百萬令牌包含在內。',
|
||||
tooltip:
|
||||
'附加功能,每 {{tokenLimit}} 令牌 ${{price, number}}。前 {{basicQuota}} 令牌包含在內。',
|
||||
},
|
||||
hooks: {
|
||||
title: '鉤子',
|
||||
|
|
|
@ -1394,8 +1394,8 @@ importers:
|
|||
version: 3.23.8
|
||||
devDependencies:
|
||||
'@logto/cloud':
|
||||
specifier: 0.2.5-5e334eb
|
||||
version: 0.2.5-5e334eb(zod@3.23.8)
|
||||
specifier: 0.2.5-aac51e9
|
||||
version: 0.2.5-aac51e9(zod@3.23.8)
|
||||
'@silverhand/eslint-config':
|
||||
specifier: 6.0.1
|
||||
version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.5.3)
|
||||
|
@ -2748,8 +2748,8 @@ importers:
|
|||
specifier: ^29.5.0
|
||||
version: 29.5.0
|
||||
'@logto/cloud':
|
||||
specifier: 0.2.5-5e334eb
|
||||
version: 0.2.5-5e334eb(zod@3.23.8)
|
||||
specifier: 0.2.5-aac51e9
|
||||
version: 0.2.5-aac51e9(zod@3.23.8)
|
||||
'@logto/connector-kit':
|
||||
specifier: workspace:^4.1.0
|
||||
version: link:../toolkit/connector-kit
|
||||
|
@ -3244,8 +3244,8 @@ importers:
|
|||
version: 3.23.8
|
||||
devDependencies:
|
||||
'@logto/cloud':
|
||||
specifier: 0.2.5-5e334eb
|
||||
version: 0.2.5-5e334eb(zod@3.23.8)
|
||||
specifier: 0.2.5-aac51e9
|
||||
version: 0.2.5-aac51e9(zod@3.23.8)
|
||||
'@silverhand/eslint-config':
|
||||
specifier: 6.0.1
|
||||
version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.5.3)
|
||||
|
@ -4747,7 +4747,7 @@ packages:
|
|||
'@azure/core-http@3.0.4':
|
||||
resolution: {integrity: sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
deprecated: This package is no longer supported. Please migrate to use @azure/core-rest-pipeline
|
||||
deprecated: deprecating as we migrated to core v2
|
||||
|
||||
'@azure/core-lro@2.5.1':
|
||||
resolution: {integrity: sha512-JHQy/bA3NOz2WuzOi5zEk6n/TJdAropupxUT521JIJvW7EXV2YN2SFYZrf/2RHeD28QAClGdynYadZsbmP+nyQ==}
|
||||
|
@ -6092,8 +6092,8 @@ packages:
|
|||
'@logto/client@2.7.2':
|
||||
resolution: {integrity: sha512-jsmuDl9QpXfR3uLEMPE67tvYoL5XcjJi+4yGqucYPjd4GH6SUHp3N9skk8C/OyygnKDPLY+ttwD0LaIbpGvn+Q==}
|
||||
|
||||
'@logto/cloud@0.2.5-5e334eb':
|
||||
resolution: {integrity: sha512-HqcxjQV5F87Q5dM8sQY+F06YrjZofFl2Hb3VJh6c6Q5fHIPZ6WWJDAVVbGZU8GK7LO2f8gpLWWD+p7DIyLzDoA==}
|
||||
'@logto/cloud@0.2.5-aac51e9':
|
||||
resolution: {integrity: sha512-p/9u33xBFIuh6NRFO5D/G2rsvmZJAdnjjB6n8RxlMp34XHBuRRmiuB/KadKFQmUkPVJhDOo5hs9dgdd28ClQIA==}
|
||||
engines: {node: ^20.9.0}
|
||||
|
||||
'@logto/js@4.1.4':
|
||||
|
@ -8308,7 +8308,7 @@ packages:
|
|||
engines: {node: '>= 0.6'}
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
|
||||
confusing-browser-globals@1.0.11:
|
||||
resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
|
||||
|
@ -8950,7 +8950,7 @@ packages:
|
|||
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
|
||||
|
||||
ee-first@1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
|
||||
|
||||
electron-to-chromium@1.5.0:
|
||||
resolution: {integrity: sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==}
|
||||
|
@ -10019,7 +10019,7 @@ packages:
|
|||
engines: {node: '>=16.17.0'}
|
||||
|
||||
humanize-number@0.0.2:
|
||||
resolution: {integrity: sha512-un3ZAcNQGI7RzaWGZzQDH47HETM4Wrj6z6E4TId8Yeq9w5ZKUVB1nrT2jwFheTUjEmqcgTjXDc959jum+ai1kQ==}
|
||||
resolution: {integrity: sha1-EcCvakcWQ2M1iFiASPF5lUFInBg=}
|
||||
|
||||
husky@9.0.7:
|
||||
resolution: {integrity: sha512-vWdusw+y12DUEeoZqW1kplOFqk3tedGV8qlga8/SF6a3lOiWLqGZZQvfWvY0fQYdfiRi/u1DFNpudTSV9l1aCg==}
|
||||
|
@ -11272,7 +11272,7 @@ packages:
|
|||
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
|
||||
|
||||
media-typer@0.3.0:
|
||||
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
||||
resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
meow@10.1.5:
|
||||
|
@ -13335,7 +13335,7 @@ packages:
|
|||
resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
|
||||
|
||||
stubs@3.0.0:
|
||||
resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==}
|
||||
resolution: {integrity: sha1-6NK6H6nJBXAwPAMLaQD31fiavls=}
|
||||
|
||||
style-search@0.1.0:
|
||||
resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==}
|
||||
|
@ -13993,7 +13993,7 @@ packages:
|
|||
optional: true
|
||||
|
||||
void-elements@3.1.0:
|
||||
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
||||
resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
w3c-xmlserializer@3.0.0:
|
||||
|
@ -16382,11 +16382,11 @@ snapshots:
|
|||
'@logto/client@2.7.2':
|
||||
dependencies:
|
||||
'@logto/js': 4.1.4
|
||||
'@silverhand/essentials': 2.9.2
|
||||
'@silverhand/essentials': 2.9.1
|
||||
camelcase-keys: 7.0.2
|
||||
jose: 5.9.6
|
||||
|
||||
'@logto/cloud@0.2.5-5e334eb(zod@3.23.8)':
|
||||
'@logto/cloud@0.2.5-aac51e9(zod@3.23.8)':
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.9.2
|
||||
'@withtyped/server': 0.14.0(zod@3.23.8)
|
||||
|
@ -16898,10 +16898,10 @@ snapshots:
|
|||
eslint-config-prettier: 9.1.0(eslint@8.57.0)
|
||||
eslint-config-xo: 0.44.0(eslint@8.57.0)
|
||||
eslint-config-xo-typescript: 4.0.0(@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3))(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)
|
||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
|
||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-consistent-default-export-name: 0.0.15
|
||||
eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-n: 17.2.1(eslint@8.57.0)
|
||||
eslint-plugin-no-use-extend-native: 0.5.0
|
||||
eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.0.0)
|
||||
|
@ -20350,13 +20350,13 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0):
|
||||
eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0):
|
||||
dependencies:
|
||||
debug: 4.3.5
|
||||
enhanced-resolve: 5.16.0
|
||||
eslint: 8.57.0
|
||||
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
|
||||
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
|
||||
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
|
||||
fast-glob: 3.3.2
|
||||
get-tsconfig: 4.7.3
|
||||
is-core-module: 2.13.1
|
||||
|
@ -20367,14 +20367,14 @@ snapshots:
|
|||
- eslint-import-resolver-webpack
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
|
||||
eslint-module-utils@2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.5.3)
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
|
||||
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
@ -20396,7 +20396,7 @@ snapshots:
|
|||
eslint: 8.57.0
|
||||
ignore: 5.3.1
|
||||
|
||||
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
|
||||
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
|
||||
dependencies:
|
||||
array-includes: 3.1.8
|
||||
array.prototype.findlastindex: 1.2.5
|
||||
|
@ -20406,7 +20406,7 @@ snapshots:
|
|||
doctrine: 2.1.0
|
||||
eslint: 8.57.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
|
||||
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.13.1
|
||||
is-glob: 4.0.3
|
||||
|
|
Loading…
Reference in a new issue