mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
feat(schemas,cloud): align tenant types (#4004)
This commit is contained in:
parent
d2f7c94167
commit
e96e92b2df
24 changed files with 79 additions and 109 deletions
|
@ -1,11 +1,5 @@
|
||||||
import { createTenantMetadata } from '@logto/core-kit';
|
import { createTenantMetadata } from '@logto/core-kit';
|
||||||
import type {
|
import type { AdminData, UpdateAdminData, CreateScope, CreateRolesScope } from '@logto/schemas';
|
||||||
CreateTenant,
|
|
||||||
AdminData,
|
|
||||||
UpdateAdminData,
|
|
||||||
CreateScope,
|
|
||||||
CreateRolesScope,
|
|
||||||
} from '@logto/schemas';
|
|
||||||
import { generateStandardId } from '@logto/shared';
|
import { generateStandardId } from '@logto/shared';
|
||||||
import { assert } from '@silverhand/essentials';
|
import { assert } from '@silverhand/essentials';
|
||||||
import type { CommonQueryMethods } from 'slonik';
|
import type { CommonQueryMethods } from 'slonik';
|
||||||
|
@ -18,7 +12,11 @@ import { getDatabaseName } from '../../../queries/database.js';
|
||||||
export const createTenant = async (pool: CommonQueryMethods, tenantId: string) => {
|
export const createTenant = async (pool: CommonQueryMethods, tenantId: string) => {
|
||||||
const database = await getDatabaseName(pool, true);
|
const database = await getDatabaseName(pool, true);
|
||||||
const { parentRole, role, password } = createTenantMetadata(database, tenantId);
|
const { parentRole, role, password } = createTenantMetadata(database, tenantId);
|
||||||
const createTenant: CreateTenant = { id: tenantId, dbUser: role, dbUserPassword: password };
|
const createTenant = {
|
||||||
|
id: tenantId,
|
||||||
|
dbUser: role,
|
||||||
|
dbUserPassword: password,
|
||||||
|
};
|
||||||
|
|
||||||
await pool.query(insertInto(createTenant, 'tenants'));
|
await pool.query(insertInto(createTenant, 'tenants'));
|
||||||
await pool.query(sql`
|
await pool.query(sql`
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
"@logto/shared": "workspace:^2.0.0",
|
"@logto/shared": "workspace:^2.0.0",
|
||||||
"@silverhand/essentials": "^2.5.0",
|
"@silverhand/essentials": "^2.5.0",
|
||||||
"@withtyped/postgres": "^0.11.0",
|
"@withtyped/postgres": "^0.11.0",
|
||||||
"@withtyped/server": "^0.11.0",
|
"@withtyped/server": "^0.11.1",
|
||||||
"accepts": "^1.3.8",
|
"accepts": "^1.3.8",
|
||||||
"chalk": "^5.0.0",
|
"chalk": "^5.0.0",
|
||||||
"decamelize": "^6.0.0",
|
"decamelize": "^6.0.0",
|
||||||
|
|
|
@ -6,8 +6,6 @@ import { DemoConnector } from '@logto/connector-kit';
|
||||||
import { createTenantMetadata } from '@logto/core-kit';
|
import { createTenantMetadata } from '@logto/core-kit';
|
||||||
import {
|
import {
|
||||||
type LogtoOidcConfigType,
|
type LogtoOidcConfigType,
|
||||||
type TenantInfo,
|
|
||||||
type CreateTenant,
|
|
||||||
createAdminTenantApplicationRole,
|
createAdminTenantApplicationRole,
|
||||||
AdminTenantRole,
|
AdminTenantRole,
|
||||||
createTenantMachineToMachineApplication,
|
createTenantMachineToMachineApplication,
|
||||||
|
@ -20,8 +18,9 @@ import {
|
||||||
createAdminData,
|
createAdminData,
|
||||||
createAdminDataInAdminTenant,
|
createAdminDataInAdminTenant,
|
||||||
getManagementApiResourceIndicator,
|
getManagementApiResourceIndicator,
|
||||||
type PatchTenant,
|
type TenantModel,
|
||||||
} from '@logto/schemas';
|
} from '@logto/schemas';
|
||||||
|
import type { TenantInfo } from '@logto/schemas/models';
|
||||||
import { generateStandardId } from '@logto/shared';
|
import { generateStandardId } from '@logto/shared';
|
||||||
import { appendPath } from '@silverhand/essentials';
|
import { appendPath } from '@silverhand/essentials';
|
||||||
|
|
||||||
|
@ -71,7 +70,10 @@ export class TenantsLibrary {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateTenantById(tenantId: string, payload: PatchTenant): Promise<TenantInfo> {
|
async updateTenantById(
|
||||||
|
tenantId: string,
|
||||||
|
payload: Partial<Pick<TenantModel, 'name' | 'tag'>>
|
||||||
|
): Promise<TenantInfo> {
|
||||||
const { id, name, tag } = await this.queries.tenants.updateTenantById(tenantId, payload);
|
const { id, name, tag } = await this.queries.tenants.updateTenantById(tenantId, payload);
|
||||||
|
|
||||||
return { id, name, tag, indicator: getManagementApiResourceIndicator(id) };
|
return { id, name, tag, indicator: getManagementApiResourceIndicator(id) };
|
||||||
|
@ -119,13 +121,13 @@ export class TenantsLibrary {
|
||||||
|
|
||||||
async createNewTenant(
|
async createNewTenant(
|
||||||
forUserId: string,
|
forUserId: string,
|
||||||
payload: Pick<CreateTenant, 'name' | 'tag'>
|
payload: Partial<Pick<TenantModel, 'name' | 'tag'>>
|
||||||
): Promise<TenantInfo> {
|
): Promise<TenantInfo> {
|
||||||
const databaseName = await getDatabaseName(this.queries.client);
|
const databaseName = await getDatabaseName(this.queries.client);
|
||||||
const { id: tenantId, parentRole, role, password } = createTenantMetadata(databaseName);
|
const { id: tenantId, parentRole, role, password } = createTenantMetadata(databaseName);
|
||||||
|
|
||||||
// Init tenant
|
// Init tenant
|
||||||
const createTenant: CreateTenant = {
|
const createTenant = {
|
||||||
id: tenantId,
|
id: tenantId,
|
||||||
dbUser: role,
|
dbUser: role,
|
||||||
dbUserPassword: password,
|
dbUserPassword: password,
|
||||||
|
|
|
@ -8,11 +8,9 @@ import {
|
||||||
PredefinedScope,
|
PredefinedScope,
|
||||||
ApplicationType,
|
ApplicationType,
|
||||||
type AdminData,
|
type AdminData,
|
||||||
type CreateTenant,
|
|
||||||
type PatchTenant,
|
|
||||||
type CreateRolesScope,
|
type CreateRolesScope,
|
||||||
type TenantModel,
|
|
||||||
} from '@logto/schemas';
|
} from '@logto/schemas';
|
||||||
|
import type { TenantModel } from '@logto/schemas/models';
|
||||||
import { generateStandardId } from '@logto/shared';
|
import { generateStandardId } from '@logto/shared';
|
||||||
import {
|
import {
|
||||||
type PostgreSql,
|
type PostgreSql,
|
||||||
|
@ -47,20 +45,15 @@ export const createTenantsQueries = (client: Queryable<PostgreSql>) => {
|
||||||
where roles.tenant_id = ${adminTenantId};
|
where roles.tenant_id = ${adminTenantId};
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const insertTenant = async (tenant: CreateTenant) =>
|
const insertTenant = async (
|
||||||
client.query(
|
tenant: Pick<TenantModel, 'id' | 'dbUser' | 'dbUserPassword'> &
|
||||||
insertInto(
|
Partial<Pick<TenantModel, 'name' | 'tag'>>
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
) => client.query(insertInto(tenant, 'tenants'));
|
||||||
Object.fromEntries(Object.entries(tenant).filter(([_, value]) => value !== undefined)),
|
|
||||||
'tenants'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateTenantById = async (tenantId: string, rawPayload: PatchTenant) => {
|
const updateTenantById = async (
|
||||||
const payload: Record<string, string> = Object.fromEntries(
|
tenantId: string,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
payload: Partial<Pick<TenantModel, 'name' | 'tag'>>
|
||||||
Object.entries(rawPayload).filter(([_, value]) => value !== undefined)
|
) => {
|
||||||
);
|
|
||||||
const tenant = await client.maybeOne<TenantModel>(sql`
|
const tenant = await client.maybeOne<TenantModel>(sql`
|
||||||
update tenants
|
update tenants
|
||||||
set ${Object.entries(payload).map(([key, value]) => sql`${id(key)}=${jsonIfNeeded(value)}`)}
|
set ${Object.entries(payload).map(([key, value]) => sql`${id(key)}=${jsonIfNeeded(value)}`)}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { TenantInfo } from '@logto/schemas';
|
import { CloudScope } from '@logto/schemas';
|
||||||
import { CloudScope, TenantTag } from '@logto/schemas';
|
import { type TenantInfo, TenantTag } from '@logto/schemas/models';
|
||||||
|
|
||||||
import { buildRequestAuthContext, createHttpContext } from '#src/test-utils/context.js';
|
import { buildRequestAuthContext, createHttpContext } from '#src/test-utils/context.js';
|
||||||
import { noop } from '#src/test-utils/function.js';
|
import { noop } from '#src/test-utils/function.js';
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
import {
|
import { CloudScope, adminTenantId, defaultTenantId } from '@logto/schemas';
|
||||||
CloudScope,
|
import { Tenants, tenantInfoGuard } from '@logto/schemas/models';
|
||||||
tenantInfoGuard,
|
|
||||||
createTenantGuard,
|
|
||||||
adminTenantId,
|
|
||||||
defaultTenantId,
|
|
||||||
} from '@logto/schemas';
|
|
||||||
import { assert } from '@silverhand/essentials';
|
import { assert } from '@silverhand/essentials';
|
||||||
import { createRouter, RequestError } from '@withtyped/server';
|
import { createRouter, RequestError } from '@withtyped/server';
|
||||||
|
|
||||||
|
@ -23,7 +18,7 @@ export const tenantsRoutes = (library: TenantsLibrary) =>
|
||||||
.patch(
|
.patch(
|
||||||
'/:tenantId',
|
'/:tenantId',
|
||||||
{
|
{
|
||||||
body: createTenantGuard.pick({ name: true, tag: true }).partial(),
|
body: Tenants.guard('patch').pick({ name: true, tag: true }),
|
||||||
response: tenantInfoGuard,
|
response: tenantInfoGuard,
|
||||||
},
|
},
|
||||||
async (context, next) => {
|
async (context, next) => {
|
||||||
|
@ -61,7 +56,7 @@ export const tenantsRoutes = (library: TenantsLibrary) =>
|
||||||
.post(
|
.post(
|
||||||
'/',
|
'/',
|
||||||
{
|
{
|
||||||
body: createTenantGuard.pick({ name: true, tag: true }).required(),
|
body: Tenants.guard('create').pick({ name: true, tag: true }),
|
||||||
response: tenantInfoGuard,
|
response: tenantInfoGuard,
|
||||||
},
|
},
|
||||||
async (context, next) => {
|
async (context, next) => {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type { ServiceLogType, TenantInfo, TenantTag } from '@logto/schemas';
|
import type { ServiceLogType } from '@logto/schemas';
|
||||||
|
import type { TenantInfo, TenantTag } from '@logto/schemas/models';
|
||||||
|
|
||||||
import type { ServicesLibrary } from '#src/libraries/services.js';
|
import type { ServicesLibrary } from '#src/libraries/services.js';
|
||||||
import type { TenantsLibrary } from '#src/libraries/tenants.js';
|
import type { TenantsLibrary } from '#src/libraries/tenants.js';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useLogto } from '@logto/react';
|
import { useLogto } from '@logto/react';
|
||||||
import type { TenantInfo } from '@logto/schemas';
|
import type { TenantInfo } from '@logto/schemas/models';
|
||||||
import { trySafe } from '@silverhand/essentials';
|
import { trySafe } from '@silverhand/essentials';
|
||||||
import { useContext, useEffect } from 'react';
|
import { useContext, useEffect } from 'react';
|
||||||
import { useHref } from 'react-router-dom';
|
import { useHref } from 'react-router-dom';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { type TenantInfo, TenantTag } from '@logto/schemas';
|
import { type TenantInfo, TenantTag } from '@logto/schemas/models';
|
||||||
import { useCallback, useContext, useEffect } from 'react';
|
import { useCallback, useContext, useEffect } from 'react';
|
||||||
|
|
||||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useLogto } from '@logto/react';
|
import { useLogto } from '@logto/react';
|
||||||
import type { TenantInfo } from '@logto/schemas';
|
import type { TenantInfo } from '@logto/schemas/models';
|
||||||
import { conditional, yes } from '@silverhand/essentials';
|
import { conditional, yes } from '@silverhand/essentials';
|
||||||
import { HTTPError } from 'ky';
|
import { HTTPError } from 'ky';
|
||||||
import { useContext, useEffect, useState } from 'react';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { type TenantInfo, TenantTag, defaultManagementApi } from '@logto/schemas';
|
import { defaultManagementApi } from '@logto/schemas';
|
||||||
|
import { type TenantInfo, TenantTag } from '@logto/schemas/models';
|
||||||
import { conditional, noop } from '@silverhand/essentials';
|
import { conditional, noop } from '@silverhand/essentials';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { useCallback, useMemo, createContext, useState } from 'react';
|
import { useCallback, useMemo, createContext, useState } from 'react';
|
||||||
|
@ -24,7 +25,7 @@ type Tenants = {
|
||||||
const { tenantId, indicator } = defaultManagementApi.resource;
|
const { tenantId, indicator } = defaultManagementApi.resource;
|
||||||
const initialTenants = conditional(
|
const initialTenants = conditional(
|
||||||
!isCloud && [
|
!isCloud && [
|
||||||
{ id: tenantId, name: `tenant_${tenantId}`, tag: `${TenantTag.Development}`, indicator }, // Make `tag` value to be string type.
|
{ id: tenantId, name: `tenant_${tenantId}`, tag: TenantTag.Development, indicator }, // Make `tag` value to be string type.
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useLogto } from '@logto/react';
|
import { useLogto } from '@logto/react';
|
||||||
import { type TenantInfo } from '@logto/schemas';
|
import { type TenantInfo } from '@logto/schemas/models';
|
||||||
import { type Optional, trySafe } from '@silverhand/essentials';
|
import { type Optional, trySafe } from '@silverhand/essentials';
|
||||||
import type ky from 'ky';
|
import type ky from 'ky';
|
||||||
import { useCallback, useContext, useEffect, useMemo } from 'react';
|
import { useCallback, useContext, useEffect, useMemo } from 'react';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { type TenantInfo } from '@logto/schemas';
|
import { type TenantInfo } from '@logto/schemas/models';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useTranslation, Trans } from 'react-i18next';
|
import { useTranslation, Trans } from 'react-i18next';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { AdminConsoleKey } from '@logto/phrases';
|
import type { AdminConsoleKey } from '@logto/phrases';
|
||||||
import { TenantTag } from '@logto/schemas';
|
import { TenantTag } from '@logto/schemas/models';
|
||||||
import { Controller, useFormContext } from 'react-hook-form';
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { type PatchTenant, type TenantInfo, TenantTag } from '@logto/schemas';
|
import { type TenantInfo, TenantTag } from '@logto/schemas/models';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FormProvider, useForm } from 'react-hook-form';
|
import { FormProvider, useForm } from 'react-hook-form';
|
||||||
|
@ -49,7 +49,7 @@ function TenantBasicSettings() {
|
||||||
reset({ profile: { name, tag } });
|
reset({ profile: { name, tag } });
|
||||||
}, [currentTenant, reset]);
|
}, [currentTenant, reset]);
|
||||||
|
|
||||||
const saveData = async (data: PatchTenant) => {
|
const saveData = async (data: { name?: string; tag?: TenantTag }) => {
|
||||||
try {
|
try {
|
||||||
const { name, tag } = await cloudApi
|
const { name, tag } = await cloudApi
|
||||||
.patch(`/api/tenants/${currentTenantId}`, {
|
.patch(`/api/tenants/${currentTenantId}`, {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { type TenantInfo } from '@logto/schemas';
|
import { type TenantModel } from '@logto/schemas/models';
|
||||||
|
|
||||||
export type TenantSettingsForm = {
|
export type TenantSettingsForm = {
|
||||||
profile: Pick<TenantInfo, 'name' | 'tag'>;
|
profile: Pick<TenantModel, 'name' | 'tag'>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import type { CreateTenant, TenantInfo, TenantTag } from '@logto/schemas';
|
import type { TenantInfo, TenantTag } from '@logto/schemas/models';
|
||||||
|
|
||||||
import { cloudApi } from './api.js';
|
import { cloudApi } from './api.js';
|
||||||
|
|
||||||
export const createTenant = async (
|
export const createTenant = async (
|
||||||
accessToken: string,
|
accessToken: string,
|
||||||
payload: Required<Pick<CreateTenant, 'name' | 'tag'>>
|
payload: { name: string; tag: TenantTag }
|
||||||
) => {
|
) => {
|
||||||
return cloudApi
|
return cloudApi
|
||||||
.extend({
|
.extend({
|
||||||
|
|
|
@ -11,11 +11,9 @@ import {
|
||||||
type Resource,
|
type Resource,
|
||||||
type Scope,
|
type Scope,
|
||||||
type Role,
|
type Role,
|
||||||
TenantTag,
|
|
||||||
type TenantInfo,
|
|
||||||
type CreateTenant,
|
|
||||||
defaultTenantId,
|
defaultTenantId,
|
||||||
} from '@logto/schemas';
|
} from '@logto/schemas';
|
||||||
|
import { TenantTag, type TenantInfo } from '@logto/schemas/models';
|
||||||
import { GlobalValues } from '@logto/shared';
|
import { GlobalValues } from '@logto/shared';
|
||||||
import { appendPath } from '@silverhand/essentials';
|
import { appendPath } from '@silverhand/essentials';
|
||||||
|
|
||||||
|
@ -40,7 +38,7 @@ describe('Tenant APIs', () => {
|
||||||
for (const [payload, tenant] of [
|
for (const [payload, tenant] of [
|
||||||
[payload1, tenant1],
|
[payload1, tenant1],
|
||||||
[payload2, tenant2],
|
[payload2, tenant2],
|
||||||
] as Array<[Required<Pick<CreateTenant, 'name' | 'tag'>>, TenantInfo]>) {
|
] as Array<[{ name: string; tag: TenantTag }, TenantInfo]>) {
|
||||||
expect(tenant).toHaveProperty('id');
|
expect(tenant).toHaveProperty('id');
|
||||||
expect(tenant).toHaveProperty('tag', payload.tag);
|
expect(tenant).toHaveProperty('tag', payload.tag);
|
||||||
expect(tenant).toHaveProperty('name', payload.name);
|
expect(tenant).toHaveProperty('name', payload.name);
|
||||||
|
@ -82,7 +80,7 @@ describe('Tenant APIs', () => {
|
||||||
[payload1, tenant1],
|
[payload1, tenant1],
|
||||||
[payload2, tenant2],
|
[payload2, tenant2],
|
||||||
[payload3, tenant3],
|
[payload3, tenant3],
|
||||||
] as Array<[Required<Pick<CreateTenant, 'name' | 'tag'>>, TenantInfo]>) {
|
] as Array<[{ name: string; tag: TenantTag }, TenantInfo]>) {
|
||||||
expect(tenant).toHaveProperty('id');
|
expect(tenant).toHaveProperty('id');
|
||||||
expect(tenant).toHaveProperty('tag', payload.tag);
|
expect(tenant).toHaveProperty('tag', payload.tag);
|
||||||
expect(tenant).toHaveProperty('name', payload.name);
|
expect(tenant).toHaveProperty('name', payload.name);
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
"@logto/phrases": "workspace:^1.4.0",
|
"@logto/phrases": "workspace:^1.4.0",
|
||||||
"@logto/phrases-ui": "workspace:^1.2.0",
|
"@logto/phrases-ui": "workspace:^1.2.0",
|
||||||
"@logto/shared": "workspace:^2.0.0",
|
"@logto/shared": "workspace:^2.0.0",
|
||||||
"@withtyped/server": "^0.11.0",
|
"@withtyped/server": "^0.11.1",
|
||||||
"zod": "^3.20.2"
|
"zod": "^3.20.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import { createModel } from '@withtyped/server/model';
|
import { createModel } from '@withtyped/server/model';
|
||||||
|
import type { InferModelType } from '@withtyped/server/model';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { TenantTag } from '../index.js';
|
export enum TenantTag {
|
||||||
|
Development = 'development',
|
||||||
|
Staging = 'staging',
|
||||||
|
Production = 'production',
|
||||||
|
}
|
||||||
|
|
||||||
export const Tenants = createModel(/* sql */ `
|
export const Tenants = createModel(/* sql */ `
|
||||||
/* init_order = 0 */
|
/* init_order = 0 */
|
||||||
|
@ -16,4 +22,14 @@ export const Tenants = createModel(/* sql */ `
|
||||||
unique (db_user)
|
unique (db_user)
|
||||||
);
|
);
|
||||||
/* no_after_each */
|
/* no_after_each */
|
||||||
`);
|
`)
|
||||||
|
.extend('tag', z.nativeEnum(TenantTag))
|
||||||
|
.extend('createdAt', { readonly: true });
|
||||||
|
|
||||||
|
export type TenantModel = InferModelType<typeof Tenants>;
|
||||||
|
|
||||||
|
export type TenantInfo = Pick<TenantModel, 'id' | 'name' | 'tag'> & { indicator: string };
|
||||||
|
|
||||||
|
export const tenantInfoGuard: z.ZodType<TenantInfo> = Tenants.guard('model')
|
||||||
|
.pick({ id: true, name: true, tag: true })
|
||||||
|
.extend({ indicator: z.string() });
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
import type { InferModelType } from '@withtyped/server/model';
|
export type { TenantModel } from '../models/tenants.js';
|
||||||
|
|
||||||
import type { Tenants } from '../models/tenants.js';
|
|
||||||
|
|
||||||
export const defaultTenantId = 'default';
|
export const defaultTenantId = 'default';
|
||||||
export const adminTenantId = 'admin';
|
export const adminTenantId = 'admin';
|
||||||
|
|
||||||
export type TenantModel = InferModelType<typeof Tenants>;
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ export * from './role.js';
|
||||||
export * from './verification-code.js';
|
export * from './verification-code.js';
|
||||||
export * from './application.js';
|
export * from './application.js';
|
||||||
export * from './system.js';
|
export * from './system.js';
|
||||||
export * from './tenant.js';
|
|
||||||
export * from './user-assets.js';
|
export * from './user-assets.js';
|
||||||
export * from './hook.js';
|
export * from './hook.js';
|
||||||
export * from './service-log.js';
|
export * from './service-log.js';
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import { type TenantModel } from '../seeds/tenant.js';
|
|
||||||
|
|
||||||
export enum TenantTag {
|
|
||||||
Development = 'development',
|
|
||||||
Staging = 'staging',
|
|
||||||
Production = 'production',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PatchTenant = Partial<Pick<TenantModel, 'name' | 'tag'>>;
|
|
||||||
export type CreateTenant = Pick<TenantModel, 'id' | 'dbUser' | 'dbUserPassword'> &
|
|
||||||
PatchTenant & { createdAt?: number };
|
|
||||||
|
|
||||||
export const createTenantGuard = z.object({
|
|
||||||
id: z.string(),
|
|
||||||
dbUser: z.string(),
|
|
||||||
dbUserPassword: z.string(),
|
|
||||||
name: z.string().optional(),
|
|
||||||
tag: z.nativeEnum(TenantTag).optional(),
|
|
||||||
createdAt: z.number().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export type TenantInfo = Pick<TenantModel, 'id' | 'name' | 'tag'> & { indicator: string };
|
|
||||||
|
|
||||||
export const tenantInfoGuard: z.ZodType<TenantInfo> = createTenantGuard
|
|
||||||
.pick({ id: true, name: true, tag: true })
|
|
||||||
.extend({ indicator: z.string() })
|
|
||||||
.required();
|
|
|
@ -253,10 +253,10 @@ importers:
|
||||||
version: 2.5.0
|
version: 2.5.0
|
||||||
'@withtyped/postgres':
|
'@withtyped/postgres':
|
||||||
specifier: ^0.11.0
|
specifier: ^0.11.0
|
||||||
version: 0.11.0(@withtyped/server@0.11.0)
|
version: 0.11.0(@withtyped/server@0.11.1)
|
||||||
'@withtyped/server':
|
'@withtyped/server':
|
||||||
specifier: ^0.11.0
|
specifier: ^0.11.1
|
||||||
version: 0.11.0(zod@3.20.2)
|
version: 0.11.1(zod@3.20.2)
|
||||||
accepts:
|
accepts:
|
||||||
specifier: ^1.3.8
|
specifier: ^1.3.8
|
||||||
version: 1.3.8
|
version: 1.3.8
|
||||||
|
@ -3556,8 +3556,8 @@ importers:
|
||||||
specifier: workspace:^2.0.0
|
specifier: workspace:^2.0.0
|
||||||
version: link:../shared
|
version: link:../shared
|
||||||
'@withtyped/server':
|
'@withtyped/server':
|
||||||
specifier: ^0.11.0
|
specifier: ^0.11.1
|
||||||
version: 0.11.0(zod@3.20.2)
|
version: 0.11.1(zod@3.20.2)
|
||||||
zod:
|
zod:
|
||||||
specifier: ^3.20.2
|
specifier: ^3.20.2
|
||||||
version: 3.20.2
|
version: 3.20.2
|
||||||
|
@ -9808,21 +9808,21 @@ packages:
|
||||||
eslint-visitor-keys: 3.3.0
|
eslint-visitor-keys: 3.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@withtyped/postgres@0.11.0(@withtyped/server@0.11.0):
|
/@withtyped/postgres@0.11.0(@withtyped/server@0.11.1):
|
||||||
resolution: {integrity: sha512-PHnx6ake/MDdyy4sZXS/7l5XNBtjqlPSqSHrlmCYUXYxUV0sHSrXECKxX7deAvWZtcHVh9VaWEpiQBhFS06Vig==}
|
resolution: {integrity: sha512-PHnx6ake/MDdyy4sZXS/7l5XNBtjqlPSqSHrlmCYUXYxUV0sHSrXECKxX7deAvWZtcHVh9VaWEpiQBhFS06Vig==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@withtyped/server': ^0.11.0
|
'@withtyped/server': ^0.11.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/pg': 8.6.6
|
'@types/pg': 8.6.6
|
||||||
'@withtyped/server': 0.11.0(zod@3.20.2)
|
'@withtyped/server': 0.11.1(zod@3.20.2)
|
||||||
'@withtyped/shared': 0.2.0
|
'@withtyped/shared': 0.2.0
|
||||||
pg: 8.8.0
|
pg: 8.8.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- pg-native
|
- pg-native
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@withtyped/server@0.11.0(zod@3.20.2):
|
/@withtyped/server@0.11.1(zod@3.20.2):
|
||||||
resolution: {integrity: sha512-InF3g9uv63ImK/sTIywcwX9tg2KnyFOlYsqeVI1WDjV1eTdzVxRJInD8iA08+U10S/dhBimukSx2Bfjwt8MWiw==}
|
resolution: {integrity: sha512-9b/rH+6S8rKlgVTuDfDOSXiVjOBz5yd4EIP6qswncIJvA+i9j1ykR0GIBGuJSQAr7SWrSNCILUVK+oDTiWzJ6g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
zod: ^3.19.1
|
zod: ^3.19.1
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Reference in a new issue