diff --git a/packages/core/package.json b/packages/core/package.json index ee5ca225d..2571b69b7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -42,7 +42,7 @@ "@logto/shared": "workspace:^2.0.0", "@logto/ui": "workspace:*", "@silverhand/essentials": "^2.5.0", - "@withtyped/client": "^0.7.21", + "@withtyped/client": "^0.7.22", "chalk": "^5.0.0", "clean-deep": "^3.4.0", "date-fns": "^2.29.3", @@ -82,7 +82,7 @@ "zod": "^3.20.2" }, "devDependencies": { - "@logto/cloud": "0.2.5-33a6965", + "@logto/cloud": "0.2.5-a3e852f", "@silverhand/eslint-config": "4.0.1", "@silverhand/ts-config": "4.0.0", "@types/debug": "^4.1.7", diff --git a/packages/core/src/middleware/koa-tenant-guard.test.ts b/packages/core/src/middleware/koa-tenant-guard.test.ts new file mode 100644 index 000000000..d6c18baf9 --- /dev/null +++ b/packages/core/src/middleware/koa-tenant-guard.test.ts @@ -0,0 +1,84 @@ +import type router from '@logto/cloud/routes'; +import Client from '@withtyped/client'; +import Sinon from 'sinon'; + +import { EnvSet } from '#src/env-set/index.js'; +import RequestError from '#src/errors/RequestError/index.js'; +import { CloudConnectionLibrary } from '#src/libraries/cloud-connection.js'; +import { type LogtoConfigLibrary } from '#src/libraries/logto-config.js'; +import { createContextWithRouteParameters } from '#src/utils/test-utils.js'; + +import koaTenantGuard from './koa-tenant-guard.js'; + +const { jest } = import.meta; + +const logtoConfigs: LogtoConfigLibrary = { + getCloudConnectionData: jest.fn().mockResolvedValue({ + appId: 'appId', + appSecret: 'appSecret', + resource: 'resource', + }), + getOidcConfigs: jest.fn(), +}; + +describe('koaTenantGuard middleware', () => { + const cloudConnection = new CloudConnectionLibrary(logtoConfigs); + const mockCloudClient = new Client({ baseUrl: 'http://localhost:3000' }); + + const getClientSpy = jest.spyOn(cloudConnection, 'getClient').mockResolvedValue(mockCloudClient); + const clientGetSpy = jest.spyOn(mockCloudClient, 'get'); + + const next = jest.fn(); + const ctx = createContextWithRouteParameters(); + + it('should return directly if not in cloud', async () => { + const stub = Sinon.stub(EnvSet, 'values').value({ + ...EnvSet.values, + isCloud: false, + }); + + await expect(koaTenantGuard(cloudConnection)(ctx, next)).resolves.not.toThrow(); + expect(clientGetSpy).not.toBeCalled(); + expect(getClientSpy).not.toBeCalled(); + + stub.restore(); + }); + + it('should reject if tenant is suspended', async () => { + const stub = Sinon.stub(EnvSet, 'values').value({ + ...EnvSet.values, + isCloud: true, + }); + + // @ts-expect-error mock returning value + clientGetSpy.mockResolvedValue({ + isSuspended: true, + }); + + await expect(koaTenantGuard(cloudConnection)(ctx, next)).rejects.toMatchError( + new RequestError('subscription.tenant_suspended', 403) + ); + + expect(clientGetSpy).toBeCalledWith('/api/my/tenant'); + + stub.restore(); + }); + + it('should resolve if tenant is not suspended', async () => { + const stub = Sinon.stub(EnvSet, 'values').value({ + ...EnvSet.values, + isCloud: true, + }); + + // @ts-expect-error mock returning value + clientGetSpy.mockResolvedValue({ + isSuspended: false, + }); + + await expect(koaTenantGuard(cloudConnection)(ctx, next)).resolves.not.toThrow(); + + expect(clientGetSpy).toBeCalledWith('/api/my/tenant'); + + stub.restore(); + }); +}); diff --git a/packages/core/src/middleware/koa-tenant-guard.ts b/packages/core/src/middleware/koa-tenant-guard.ts new file mode 100644 index 000000000..a5ca8d697 --- /dev/null +++ b/packages/core/src/middleware/koa-tenant-guard.ts @@ -0,0 +1,33 @@ +import type { Middleware } from 'koa'; +import { type IRouterParamContext } from 'koa-router'; + +import { EnvSet } from '#src/env-set/index.js'; +import RequestError from '#src/errors/RequestError/index.js'; +import { type CloudConnectionLibrary } from '#src/libraries/cloud-connection.js'; + +const getAvailableTenant = async (cloudConnection: CloudConnectionLibrary) => { + const client = await cloudConnection.getClient(); + const tenant = await client.get('/api/my/tenant'); + + return tenant; +}; + +export default function koaTenantGuard( + cloudConnection: CloudConnectionLibrary +): Middleware { + return async (ctx, next) => { + const { isCloud } = EnvSet.values; + + if (!isCloud) { + return next(); + } + + const tenant = await getAvailableTenant(cloudConnection); + + if (tenant.isSuspended) { + throw new RequestError('subscription.tenant_suspended', 403); + } + + await next(); + }; +} diff --git a/packages/core/src/routes/init.ts b/packages/core/src/routes/init.ts index 0a2272d7f..1659ec404 100644 --- a/packages/core/src/routes/init.ts +++ b/packages/core/src/routes/init.ts @@ -5,6 +5,7 @@ import Router from 'koa-router'; import { EnvSet } from '#src/env-set/index.js'; import koaBodyEtag from '#src/middleware/koa-body-etag.js'; import koaCors from '#src/middleware/koa-cors.js'; +import koaTenantGuard from '#src/middleware/koa-tenant-guard.js'; import type TenantContext from '#src/tenants/TenantContext.js'; import koaAuth from '../middleware/koa-auth/index.js'; @@ -40,6 +41,8 @@ const createRouters = (tenant: TenantContext) => { const managementRouter: AuthedRouter = new Router(); managementRouter.use(koaAuth(tenant.envSet, getManagementApiResourceIndicator(tenant.id))); + managementRouter.use(koaTenantGuard(tenant.cloudConnection)); + applicationRoutes(managementRouter, tenant); logtoConfigRoutes(managementRouter, tenant); connectorRoutes(managementRouter, tenant); diff --git a/packages/phrases/src/locales/de/errors/subscription.ts b/packages/phrases/src/locales/de/errors/subscription.ts index 4eb498cc7..f8ce4c7f5 100644 --- a/packages/phrases/src/locales/de/errors/subscription.ts +++ b/packages/phrases/src/locales/de/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'Sie haben das Limit Ihres Abonnementplans erreicht.', get_plan_failed: 'Fehler beim Abrufen des Abonnementplans für den Mandanten.', + tenant_suspended: 'Mandant ist gesperrt. Bitte kontaktieren Sie Ihren Administrator.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/en/errors/subscription.ts b/packages/phrases/src/locales/en/errors/subscription.ts index 6d5630b7d..186f76bef 100644 --- a/packages/phrases/src/locales/en/errors/subscription.ts +++ b/packages/phrases/src/locales/en/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'You have reached the limit of your subscription plan.', get_plan_failed: 'Unable to get subscription plan for tenant.', + tenant_suspended: 'Tenant is suspended. Please contact your administrator.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/es/errors/subscription.ts b/packages/phrases/src/locales/es/errors/subscription.ts index fa1cf4840..b3305dcb5 100644 --- a/packages/phrases/src/locales/es/errors/subscription.ts +++ b/packages/phrases/src/locales/es/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'Has alcanzado el límite de tu plan de suscripción.', get_plan_failed: 'No se pudo obtener el plan de suscripción para el inquilino.', + tenant_suspended: 'El inquilino está suspendido. Por favor, contacta con tu administrador.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/fr/errors/subscription.ts b/packages/phrases/src/locales/fr/errors/subscription.ts index 93fabed34..27017a00d 100644 --- a/packages/phrases/src/locales/fr/errors/subscription.ts +++ b/packages/phrases/src/locales/fr/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: "Vous avez atteint la limite de votre plan d'abonnement.", get_plan_failed: "Échec de l'obtention du plan d'abonnement pour le locataire.", + tenant_suspended: 'Le locataire est suspendu. Veuillez contacter votre administrateur.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/it/errors/subscription.ts b/packages/phrases/src/locales/it/errors/subscription.ts index cd17c8efc..b8c272bfe 100644 --- a/packages/phrases/src/locales/it/errors/subscription.ts +++ b/packages/phrases/src/locales/it/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'Hai raggiunto il limite del tuo piano di abbonamento.', get_plan_failed: "Impossibile ottenere il piano di abbonamento per l'inquilino.", + tenant_suspended: "L'inquilino è sospeso. Si prega di contattare l'amministratore.", }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/ja/errors/subscription.ts b/packages/phrases/src/locales/ja/errors/subscription.ts index d0f04213b..70ea6243e 100644 --- a/packages/phrases/src/locales/ja/errors/subscription.ts +++ b/packages/phrases/src/locales/ja/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: '定めた定期プランの上限に達しました。', get_plan_failed: 'テナントのサブスクリプションプランを取得できませんでした。', + tenant_suspended: 'テナントが停止されています。管理者に連絡してください。', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/ko/errors/subscription.ts b/packages/phrases/src/locales/ko/errors/subscription.ts index 546438c35..0668f0fbb 100644 --- a/packages/phrases/src/locales/ko/errors/subscription.ts +++ b/packages/phrases/src/locales/ko/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: '당신은 구독 플랜 한도에 도달하였습니다.', get_plan_failed: '임차인에 대한 구독 플랜을 가져올 수 없습니다.', + tenant_suspended: '임차인이 정지되었습니다. 관리자에게 문의하십시오.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/pl-pl/errors/subscription.ts b/packages/phrases/src/locales/pl-pl/errors/subscription.ts index 8062288dd..13d3e3783 100644 --- a/packages/phrases/src/locales/pl-pl/errors/subscription.ts +++ b/packages/phrases/src/locales/pl-pl/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'Osiągnąłeś limit swojego planu subskrypcji.', get_plan_failed: 'Nie można pobrać planu subskrypcji dla najemcy.', + tenant_suspended: 'Najemca jest zawieszony. Skontaktuj się z administratorem.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/pt-br/errors/subscription.ts b/packages/phrases/src/locales/pt-br/errors/subscription.ts index 10a8cdc02..eedeca013 100644 --- a/packages/phrases/src/locales/pt-br/errors/subscription.ts +++ b/packages/phrases/src/locales/pt-br/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'Você atingiu o limite do seu plano de assinatura.', get_plan_failed: 'Não foi possível obter o plano de assinatura para o inquilino.', + tenant_suspended: 'O inquilino está suspenso. Por favor, entre em contato com o administrador.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/pt-pt/errors/subscription.ts b/packages/phrases/src/locales/pt-pt/errors/subscription.ts index 10a8cdc02..eedeca013 100644 --- a/packages/phrases/src/locales/pt-pt/errors/subscription.ts +++ b/packages/phrases/src/locales/pt-pt/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'Você atingiu o limite do seu plano de assinatura.', get_plan_failed: 'Não foi possível obter o plano de assinatura para o inquilino.', + tenant_suspended: 'O inquilino está suspenso. Por favor, entre em contato com o administrador.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/ru/errors/subscription.ts b/packages/phrases/src/locales/ru/errors/subscription.ts index efa2fa91a..d421f45ab 100644 --- a/packages/phrases/src/locales/ru/errors/subscription.ts +++ b/packages/phrases/src/locales/ru/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'Вы достигли лимита вашего плана подписки.', get_plan_failed: 'Не удалось получить план подписки для арендатора.', + tenant_suspended: 'Арендатор приостановлен. Пожалуйста, свяжитесь с администратором.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/tr-tr/errors/subscription.ts b/packages/phrases/src/locales/tr-tr/errors/subscription.ts index a2acf4a05..bf8f548d6 100644 --- a/packages/phrases/src/locales/tr-tr/errors/subscription.ts +++ b/packages/phrases/src/locales/tr-tr/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: 'Abonelik planınızın limitine ulaştınız.', get_plan_failed: 'Abonelik planınızı almak için başarısız oldu.', + tenant_suspended: 'Kiracı askıya alındı. Lütfen yöneticinize başvurun.', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/zh-cn/errors/subscription.ts b/packages/phrases/src/locales/zh-cn/errors/subscription.ts index 9403c1079..eb6fa53fa 100644 --- a/packages/phrases/src/locales/zh-cn/errors/subscription.ts +++ b/packages/phrases/src/locales/zh-cn/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: '您已达到订阅计划的限制。', get_plan_failed: '无法获取租户的订阅计划。', + tenant_suspended: '租户已被暂停。 请联系您的管理员。', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/zh-hk/errors/subscription.ts b/packages/phrases/src/locales/zh-hk/errors/subscription.ts index 571e87de7..cf7347228 100644 --- a/packages/phrases/src/locales/zh-hk/errors/subscription.ts +++ b/packages/phrases/src/locales/zh-hk/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: '您已達到訂閱計劃的限制。', get_plan_failed: '無法取得租戶的訂閱計劃。', + tenant_suspended: '租戶已被暫停。 請聯繫您的管理員。', }; export default Object.freeze(subscription); diff --git a/packages/phrases/src/locales/zh-tw/errors/subscription.ts b/packages/phrases/src/locales/zh-tw/errors/subscription.ts index 68e02b7ce..d631eb1cf 100644 --- a/packages/phrases/src/locales/zh-tw/errors/subscription.ts +++ b/packages/phrases/src/locales/zh-tw/errors/subscription.ts @@ -1,6 +1,7 @@ const subscription = { limit_exceeded: '您已達到訂閱計劃的限制。', get_plan_failed: '無法為租戶獲取訂閱計劃。', + tenant_suspended: '租戶已被暫停。 請聯繫您的管理員。', }; export default Object.freeze(subscription); diff --git a/packages/toolkit/connector-kit/package.json b/packages/toolkit/connector-kit/package.json index 9011f6790..939605fa0 100644 --- a/packages/toolkit/connector-kit/package.json +++ b/packages/toolkit/connector-kit/package.json @@ -38,13 +38,13 @@ "dependencies": { "@logto/language-kit": "workspace:^1.0.0", "@silverhand/essentials": "^2.5.0", - "@withtyped/client": "^0.7.21" + "@withtyped/client": "^0.7.22" }, "optionalDependencies": { "zod": "^3.20.2" }, "devDependencies": { - "@logto/cloud": "0.2.5-33a6965", + "@logto/cloud": "0.2.5-a3e852f", "@jest/types": "^29.0.3", "@silverhand/eslint-config": "4.0.1", "@silverhand/ts-config": "4.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7050a1e1e..5ff1899bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1541,7 +1541,7 @@ importers: version: link:../../toolkit/connector-kit '@silverhand/essentials': specifier: ^2.5.0 - version: 2.5.0 + version: 2.7.0 got: specifier: ^13.0.0 version: 13.0.0 @@ -1596,7 +1596,7 @@ importers: version: 14.0.0 nock: specifier: ^13.2.2 - version: 13.2.2 + version: 13.3.1 prettier: specifier: ^3.0.0 version: 3.0.0 @@ -3167,8 +3167,8 @@ importers: specifier: ^2.5.0 version: 2.5.0 '@withtyped/client': - specifier: ^0.7.21 - version: 0.7.21(zod@3.20.2) + specifier: ^0.7.22 + version: 0.7.22(zod@3.20.2) chalk: specifier: ^5.0.0 version: 5.1.2 @@ -3282,8 +3282,8 @@ importers: version: 3.20.2 devDependencies: '@logto/cloud': - specifier: 0.2.5-33a6965 - version: 0.2.5-33a6965(zod@3.20.2) + specifier: 0.2.5-a3e852f + version: 0.2.5-a3e852f(zod@3.20.2) '@silverhand/eslint-config': specifier: 4.0.1 version: 4.0.1(eslint@8.44.0)(prettier@3.0.0)(typescript@5.0.2) @@ -3754,8 +3754,8 @@ importers: specifier: ^2.5.0 version: 2.5.0 '@withtyped/client': - specifier: ^0.7.21 - version: 0.7.21(zod@3.20.2) + specifier: ^0.7.22 + version: 0.7.22(zod@3.20.2) optionalDependencies: zod: specifier: ^3.20.2 @@ -3765,8 +3765,8 @@ importers: specifier: ^29.0.3 version: 29.1.2 '@logto/cloud': - specifier: 0.2.5-33a6965 - version: 0.2.5-33a6965(zod@3.20.2) + specifier: 0.2.5-a3e852f + version: 0.2.5-a3e852f(zod@3.20.2) '@silverhand/eslint-config': specifier: 4.0.1 version: 4.0.1(eslint@8.44.0)(prettier@3.0.0)(typescript@5.0.2) @@ -7189,8 +7189,8 @@ packages: engines: {node: '>=6.0.0'} dev: true - /@jridgewell/source-map@0.3.5: - resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + /@jridgewell/source-map@0.3.3: + resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==} dependencies: '@jridgewell/gen-mapping': 0.3.2 '@jridgewell/trace-mapping': 0.3.18 @@ -7305,7 +7305,7 @@ packages: resolution: {integrity: sha512-4XsXlCC0uZHcfazV09/4YKo4koqvSzQlkPUAToTp/WHpb6h2XDOJh5/hi55LXL4zp0PCcgpErKRxFCtgXCc6WQ==} dependencies: '@logto/client': 2.2.0 - '@silverhand/essentials': 2.8.2 + '@silverhand/essentials': 2.7.0 js-base64: 3.7.5 dev: true @@ -7313,7 +7313,7 @@ packages: resolution: {integrity: sha512-vw8xDW8k38/58Q1r592z/9JdsmUh4+LMmoVm/Nu7LbWKlT32eD3H9hZDkFK9XEHpriifhI0hP7asGWEmhrEUuQ==} dependencies: '@logto/js': 2.1.1 - '@silverhand/essentials': 2.8.2 + '@silverhand/essentials': 2.7.0 camelcase-keys: 7.0.2 jose: 4.14.4 dev: true @@ -7331,18 +7331,18 @@ packages: resolution: {integrity: sha512-zxy9zr5swOxbzYJNYtKXofj2tSIS9565d+1pT6RSbmx3Hn+JG6uzsb75PZXW9vlmmm7p1sGZeTQ+xVzKNFPsMg==} engines: {node: ^18.12.0} dependencies: - '@silverhand/essentials': 2.8.2 + '@silverhand/essentials': 2.7.0 '@withtyped/server': 0.12.8(zod@3.20.2) transitivePeerDependencies: - zod dev: true - /@logto/cloud@0.2.5-33a6965(zod@3.20.2): - resolution: {integrity: sha512-Jawe/nWJmjBDDhNfcxOsQfWsLaUifV5az1mNwn23xwVM/6L/YAkwOj+dWi12lqQ+Vk6MLUPzycXvZLV28tVxQg==} + /@logto/cloud@0.2.5-a3e852f(zod@3.20.2): + resolution: {integrity: sha512-dIrEUW7gi477HQpNsq/HT1gdvPK2ZmVuV73u2rH9LXGEIFIVGqmmIaaK3IcOPG110jKCBhTzF0+hKsW9Y3Pjmw==} engines: {node: ^18.12.0} dependencies: '@silverhand/essentials': 2.8.2 - '@withtyped/server': 0.12.8(zod@3.20.2) + '@withtyped/server': 0.12.9(zod@3.20.2) transitivePeerDependencies: - zod dev: true @@ -7350,7 +7350,7 @@ packages: /@logto/js@2.1.1: resolution: {integrity: sha512-PHikheavVK+l4ivgtzi14p184hEPgXjqQEAom1Gme1MZoopx+WlwxvHSEQBsmyvVqRtI0oiojhoU5tgYi1FKJw==} dependencies: - '@silverhand/essentials': 2.8.2 + '@silverhand/essentials': 2.7.0 camelcase-keys: 7.0.2 jose: 4.14.2 dev: true @@ -7359,7 +7359,7 @@ packages: resolution: {integrity: sha512-joSzzAqaRKeEquRenoFrIXXkNxkJci5zSkk4afywz1P8tTcTysnV4eXaBmwXNpmDfQdtHBwRdSACZPLgeF8JiQ==} dependencies: '@logto/client': 2.1.0 - '@silverhand/essentials': 2.8.2 + '@silverhand/essentials': 2.7.0 js-base64: 3.7.5 node-fetch: 2.6.7 transitivePeerDependencies: @@ -7372,7 +7372,7 @@ packages: react: '>=16.8.0 || ^18.0.0' dependencies: '@logto/browser': 2.1.0 - '@silverhand/essentials': 2.8.2 + '@silverhand/essentials': 2.7.0 react: 18.2.0 dev: true @@ -8745,7 +8745,7 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.3(rollup@3.8.0) + '@rollup/pluginutils': 5.0.2(rollup@3.8.0) commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.1.0 @@ -8763,7 +8763,7 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.3(rollup@3.8.0) + '@rollup/pluginutils': 5.0.2(rollup@3.8.0) rollup: 3.8.0 dev: true @@ -8776,12 +8776,12 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.3(rollup@3.8.0) + '@rollup/pluginutils': 5.0.2(rollup@3.8.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 - is-builtin-module: 3.2.1 + is-builtin-module: 3.2.0 is-module: 1.0.0 - resolve: 1.22.2 + resolve: 1.22.1 rollup: 3.8.0 dev: true @@ -8798,14 +8798,14 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.3(rollup@3.8.0) - resolve: 1.22.2 + '@rollup/pluginutils': 5.0.2(rollup@3.8.0) + resolve: 1.22.1 rollup: 3.8.0 typescript: 5.0.2 dev: true - /@rollup/pluginutils@5.0.3(rollup@3.8.0): - resolution: {integrity: sha512-hfllNN4a80rwNQ9QCxhxuHCGHMAvabXqxNdaChUSSadMre7t4iEUI6fFAhBOn/eIYTgYVhBv7vCLsAJ4u3lf3g==} + /@rollup/pluginutils@5.0.2(rollup@3.8.0): + resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0 @@ -8966,6 +8966,10 @@ packages: resolution: {integrity: sha512-8GgVFAmbo6S0EgsjYXH4aH8a69O7SzEtPFPDpVZmJuGEt8e3ODVx0F2V4rXyC3/SzFbcb2md2gRbA+Z6aTad6g==} engines: {node: ^16.13.0 || ^18.12.0 || ^19.2.0, pnpm: ^7} + /@silverhand/essentials@2.7.0: + resolution: {integrity: sha512-F5Qo5ZNnERUURK/9F1ZIi4FBDM22aeD59Zv0VtkgIhUL9tYK9svA2Jz88NNdYBwqCPrh8ExZlpFNi+pNmXKNlQ==} + engines: {node: ^16.13.0 || ^18.12.0 || ^19.2.0, pnpm: ^8.0.0} + /@silverhand/essentials@2.8.2: resolution: {integrity: sha512-mrXzAQ6ZGyLoKQpfEOr/LmbQL7FIurVsBaymnsQyKNV56bFYCv5M+2irsAKROtmLMgSunAU/10XiDIaEYW9tbA==} engines: {node: ^16.13.0 || ^18.12.0 || ^19.2.0, pnpm: ^8.0.0} @@ -10059,6 +10063,16 @@ packages: '@withtyped/shared': 0.2.2 transitivePeerDependencies: - zod + dev: true + + /@withtyped/client@0.7.22(zod@3.20.2): + resolution: {integrity: sha512-emNtcO0jc0dFWhvL7eUIRYzhTfn+JqgIvCmXb8ZUFOR8wdSSGrr9VDlm+wgQD06DEBBpmqtTHMMHTNXJdUC/Qw==} + dependencies: + '@withtyped/server': 0.12.9(zod@3.20.2) + '@withtyped/shared': 0.2.2 + transitivePeerDependencies: + - zod + dev: false /@withtyped/server@0.12.8(zod@3.20.2): resolution: {integrity: sha512-fv9feTOKJhtlaoYM/Kbs2gSTcIXlmu4OMUFwGmK5jqdbVNIOkDBIPxtcC5ZEwevWFgOcd5OqBW+FvbjiaF27Fw==} @@ -10068,6 +10082,7 @@ packages: '@silverhand/essentials': 2.8.2 '@withtyped/shared': 0.2.2 zod: 3.20.2 + dev: true /@withtyped/server@0.12.9(zod@3.20.2): resolution: {integrity: sha512-K5zoV9D+WpawbghtlJKF1KOshKkBjq+gYzNRWuZk13YmFWFLcmZn+QCblNP55z9IGdcHWpTRknqb1APuicdzgA==} @@ -10077,7 +10092,6 @@ packages: '@silverhand/essentials': 2.8.2 '@withtyped/shared': 0.2.2 zod: 3.20.2 - dev: false /@withtyped/shared@0.2.2: resolution: {integrity: sha512-Vpcj12NqaoZ8M5Z/1kffheI9FBZEm9goed0THmgTcMKXLHjXSRbMZMp0olVxovEgaTIAydshqJOQUXKZMctIZw==} @@ -12746,8 +12760,8 @@ packages: tslib: 2.5.0 dev: true - /filesize@10.0.12: - resolution: {integrity: sha512-6RS9gDchbn+qWmtV2uSjo5vmKizgfCQeb5jKmqx8HyzA3MoLqqyQxN+QcjkGBJt7FjJ9qFce67Auyya5rRRbpw==} + /filesize@10.0.7: + resolution: {integrity: sha512-iMRG7Qo9nayLoU3PNCiLizYtsy4W1ClrapeCwEgtiQelOAOuRJiw4QaLI+sSr8xr901dgHv+EYP2bCusGZgoiA==} engines: {node: '>= 10.4.0'} dev: true @@ -13843,6 +13857,13 @@ packages: engines: {node: '>=4'} dev: true + /is-builtin-module@3.2.0: + resolution: {integrity: sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: true + /is-builtin-module@3.2.1: resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} engines: {node: '>=6'} @@ -18350,6 +18371,15 @@ packages: engines: {node: '>=10'} dev: true + /resolve@1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.12.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /resolve@1.22.2: resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} hasBin: true @@ -18431,10 +18461,10 @@ packages: dependencies: brotli-size: 4.0.0 cli-table3: 0.6.3 - filesize: 10.0.12 + filesize: 10.0.7 gzip-size: 7.0.0 rollup: 3.8.0 - terser: 5.19.2 + terser: 5.17.7 dev: true /rollup@3.8.0: @@ -19594,12 +19624,12 @@ packages: engines: {node: '>=8'} dev: true - /terser@5.19.2: - resolution: {integrity: sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==} + /terser@5.17.7: + resolution: {integrity: sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==} engines: {node: '>=10'} hasBin: true dependencies: - '@jridgewell/source-map': 0.3.5 + '@jridgewell/source-map': 0.3.3 acorn: 8.10.0 commander: 2.20.3 source-map-support: 0.5.21