mirror of
https://github.com/logto-io/logto.git
synced 2025-01-20 21:32:31 -05:00
refactor: fix schema types (#3379)
by separating CreateSchema and Schema. also no need for explicitly set generic type for database builders like `buildInsertIntoWithPool()`.
This commit is contained in:
parent
68ca4ae7a8
commit
0b45c8f487
25 changed files with 109 additions and 117 deletions
|
@ -9,8 +9,8 @@ import { isKeyOf } from '#src/utils/schema.js';
|
|||
|
||||
export const buildFindEntityByIdWithPool =
|
||||
(pool: CommonQueryMethods) =>
|
||||
<Schema extends SchemaLike, ReturnType extends SchemaLike>(
|
||||
schema: GeneratedSchema<Schema & { id: string }>
|
||||
<CreateSchema extends SchemaLike, Schema extends CreateSchema>(
|
||||
schema: GeneratedSchema<CreateSchema, Schema & { id: string }>
|
||||
) => {
|
||||
const { table, fields } = convertToIdentifiers(schema);
|
||||
const isKeyOfSchema = isKeyOf(schema);
|
||||
|
@ -20,7 +20,7 @@ export const buildFindEntityByIdWithPool =
|
|||
|
||||
return async (id: string) => {
|
||||
try {
|
||||
return await pool.one<ReturnType>(sql`
|
||||
return await pool.one<Schema>(sql`
|
||||
select ${sql.join(Object.values(fields), sql`, `)}
|
||||
from ${table}
|
||||
where ${fields.id}=${id}
|
||||
|
|
|
@ -35,20 +35,20 @@ type InsertIntoConfig = {
|
|||
};
|
||||
|
||||
type BuildInsertInto = {
|
||||
<Schema extends SchemaLike, ReturnType extends SchemaLike>(
|
||||
{ fieldKeys, ...rest }: GeneratedSchema<Schema>,
|
||||
<CreateSchema extends SchemaLike, Schema extends CreateSchema>(
|
||||
{ fieldKeys, ...rest }: GeneratedSchema<CreateSchema, Schema>,
|
||||
config: InsertIntoConfigReturning
|
||||
): (data: OmitAutoSetFields<Schema>) => Promise<ReturnType>;
|
||||
<Schema extends SchemaLike>(
|
||||
{ fieldKeys, ...rest }: GeneratedSchema<Schema>,
|
||||
): (data: OmitAutoSetFields<CreateSchema>) => Promise<Schema>;
|
||||
<CreateSchema extends SchemaLike, Schema extends CreateSchema>(
|
||||
{ fieldKeys, ...rest }: GeneratedSchema<CreateSchema, Schema>,
|
||||
config?: InsertIntoConfig
|
||||
): (data: OmitAutoSetFields<Schema>) => Promise<void>;
|
||||
): (data: OmitAutoSetFields<CreateSchema>) => Promise<void>;
|
||||
};
|
||||
|
||||
export const buildInsertIntoWithPool =
|
||||
(pool: CommonQueryMethods): BuildInsertInto =>
|
||||
<Schema extends SchemaLike, ReturnType extends SchemaLike>(
|
||||
schema: GeneratedSchema<Schema>,
|
||||
<CreateSchema extends SchemaLike, Schema extends CreateSchema>(
|
||||
schema: GeneratedSchema<CreateSchema, Schema>,
|
||||
config?: InsertIntoConfig | InsertIntoConfigReturning
|
||||
) => {
|
||||
const { fieldKeys, ...rest } = schema;
|
||||
|
@ -57,11 +57,11 @@ export const buildInsertIntoWithPool =
|
|||
const returning = Boolean(config?.returning);
|
||||
const onConflict = config?.onConflict;
|
||||
|
||||
return async (data: OmitAutoSetFields<Schema>): Promise<ReturnType | void> => {
|
||||
return async (data: OmitAutoSetFields<CreateSchema>): Promise<Schema | void> => {
|
||||
const insertingKeys = keys.filter((key) => has(data, key));
|
||||
const {
|
||||
rows: [entry],
|
||||
} = await pool.query<ReturnType>(sql`
|
||||
} = await pool.query<Schema>(sql`
|
||||
insert into ${table} (${sql.join(
|
||||
insertingKeys.map((key) => fields[key]),
|
||||
sql`, `
|
||||
|
@ -80,7 +80,7 @@ export const buildInsertIntoWithPool =
|
|||
${conditionalSql(returning, () => sql`returning *`)}
|
||||
`);
|
||||
|
||||
assertThat(!returning || entry, new InsertionError(schema, data));
|
||||
assertThat(!returning || entry, new InsertionError<CreateSchema, Schema>(schema, data));
|
||||
|
||||
return entry;
|
||||
};
|
||||
|
|
|
@ -11,19 +11,20 @@ import assertThat from '#src/utils/assert-that.js';
|
|||
import { isKeyOf } from '#src/utils/schema.js';
|
||||
|
||||
type BuildUpdateWhere = {
|
||||
<Schema extends SchemaLike, ReturnType extends SchemaLike>(
|
||||
schema: GeneratedSchema<Schema>,
|
||||
<CreateSchema extends SchemaLike, Schema extends CreateSchema>(
|
||||
schema: GeneratedSchema<CreateSchema, Schema>,
|
||||
returning: true
|
||||
): (data: UpdateWhereData<Schema>) => Promise<ReturnType>;
|
||||
<Schema extends SchemaLike>(schema: GeneratedSchema<Schema>, returning?: false): (
|
||||
data: UpdateWhereData<Schema>
|
||||
) => Promise<void>;
|
||||
): (data: UpdateWhereData<Schema>) => Promise<Schema>;
|
||||
<CreateSchema extends SchemaLike, Schema extends CreateSchema>(
|
||||
schema: GeneratedSchema<CreateSchema, Schema>,
|
||||
returning?: false
|
||||
): (data: UpdateWhereData<Schema>) => Promise<void>;
|
||||
};
|
||||
|
||||
export const buildUpdateWhereWithPool =
|
||||
(pool: CommonQueryMethods): BuildUpdateWhere =>
|
||||
<Schema extends SchemaLike, ReturnType extends SchemaLike>(
|
||||
schema: GeneratedSchema<Schema>,
|
||||
<CreateSchema extends SchemaLike, Schema extends CreateSchema>(
|
||||
schema: GeneratedSchema<CreateSchema, Schema>,
|
||||
returning = false
|
||||
) => {
|
||||
const { table, fields } = convertToIdentifiers(schema);
|
||||
|
@ -59,7 +60,7 @@ export const buildUpdateWhereWithPool =
|
|||
return async ({ set, where, jsonbMode }: UpdateWhereData<Schema>) => {
|
||||
const {
|
||||
rows: [data],
|
||||
} = await pool.query<ReturnType>(sql`
|
||||
} = await pool.query<Schema>(sql`
|
||||
update ${table}
|
||||
set ${sql.join(connectKeyValueWithEqualSign(set, jsonbMode), sql`, `)}
|
||||
where ${sql.join(connectKeyValueWithEqualSign(where, jsonbMode), sql` and `)}
|
||||
|
|
|
@ -14,11 +14,17 @@ export class DeletionError extends SlonikError {
|
|||
}
|
||||
}
|
||||
|
||||
export class UpdateError<Schema extends SchemaLike> extends SlonikError {
|
||||
schema: GeneratedSchema<Schema>;
|
||||
export class UpdateError<
|
||||
CreateSchema extends SchemaLike,
|
||||
Schema extends CreateSchema
|
||||
> extends SlonikError {
|
||||
schema: GeneratedSchema<CreateSchema, Schema>;
|
||||
detail: UpdateWhereData<Schema>;
|
||||
|
||||
public constructor(schema: GeneratedSchema<Schema>, detail: UpdateWhereData<Schema>) {
|
||||
public constructor(
|
||||
schema: GeneratedSchema<CreateSchema, Schema>,
|
||||
detail: UpdateWhereData<Schema>
|
||||
) {
|
||||
super('Resource not found.');
|
||||
|
||||
this.schema = schema;
|
||||
|
@ -26,11 +32,17 @@ export class UpdateError<Schema extends SchemaLike> extends SlonikError {
|
|||
}
|
||||
}
|
||||
|
||||
export class InsertionError<Schema extends SchemaLike> extends SlonikError {
|
||||
schema: GeneratedSchema<Schema>;
|
||||
detail?: OmitAutoSetFields<Schema>;
|
||||
export class InsertionError<
|
||||
CreateSchema extends SchemaLike,
|
||||
Schema extends CreateSchema
|
||||
> extends SlonikError {
|
||||
schema: GeneratedSchema<CreateSchema, Schema>;
|
||||
detail?: OmitAutoSetFields<CreateSchema>;
|
||||
|
||||
public constructor(schema: GeneratedSchema<Schema>, detail?: OmitAutoSetFields<Schema>) {
|
||||
public constructor(
|
||||
schema: GeneratedSchema<CreateSchema, Schema>,
|
||||
detail?: OmitAutoSetFields<CreateSchema>
|
||||
) {
|
||||
super('Create Error.');
|
||||
|
||||
this.schema = schema;
|
||||
|
|
|
@ -74,7 +74,7 @@ export const createUserLibrary = (queries: Queries) => {
|
|||
{ retries, factor: 0 } // No need for exponential backoff
|
||||
);
|
||||
|
||||
const insertUserQuery = buildInsertIntoWithPool(pool)<CreateUser, User>(Users, {
|
||||
const insertUserQuery = buildInsertIntoWithPool(pool)(Users, {
|
||||
returning: true,
|
||||
});
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ export default function koaSlonikErrorHandler<StateT, ContextT>(): Middleware<St
|
|||
code: 'entity.create_failed',
|
||||
// Assert generic type of the Class instance
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
name: (error as InsertionError<SchemaLike>).schema.tableSingular,
|
||||
name: (error as InsertionError<SchemaLike, SchemaLike>).schema.tableSingular,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ export default function koaSlonikErrorHandler<StateT, ContextT>(): Middleware<St
|
|||
code: 'entity.not_exists',
|
||||
// Assert generic type of the Class instance
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
name: (error as UpdateError<SchemaLike>).schema.tableSingular,
|
||||
name: (error as UpdateError<SchemaLike, SchemaLike>).schema.tableSingular,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -25,19 +25,11 @@ export const createApplicationQueries = (pool: CommonQueryMethods) => {
|
|||
${conditionalSql(offset, (offset) => sql`offset ${offset}`)}
|
||||
`)
|
||||
);
|
||||
const findApplicationById = buildFindEntityByIdWithPool(pool)<CreateApplication, Application>(
|
||||
Applications
|
||||
);
|
||||
const insertApplication = buildInsertIntoWithPool(pool)<CreateApplication, Application>(
|
||||
Applications,
|
||||
{
|
||||
returning: true,
|
||||
}
|
||||
);
|
||||
const updateApplication = buildUpdateWhereWithPool(pool)<CreateApplication, Application>(
|
||||
Applications,
|
||||
true
|
||||
);
|
||||
const findApplicationById = buildFindEntityByIdWithPool(pool)(Applications);
|
||||
const insertApplication = buildInsertIntoWithPool(pool)(Applications, {
|
||||
returning: true,
|
||||
});
|
||||
const updateApplication = buildUpdateWhereWithPool(pool)(Applications, true);
|
||||
const updateApplicationById = async (
|
||||
id: string,
|
||||
set: Partial<OmitAutoSetFields<CreateApplication>>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { Connector, CreateConnector } from '@logto/schemas';
|
||||
import type { Connector } from '@logto/schemas';
|
||||
import { Connectors } from '@logto/schemas';
|
||||
import { manyRows, convertToIdentifiers } from '@logto/shared';
|
||||
import type { CommonQueryMethods } from 'slonik';
|
||||
|
@ -71,13 +71,10 @@ export const createConnectorQueries = (pool: CommonQueryMethods) => {
|
|||
throw new DeletionError(Connectors.table, JSON.stringify({ ids }));
|
||||
}
|
||||
};
|
||||
const insertConnector = buildInsertIntoWithPool(pool)<CreateConnector, Connector>(Connectors, {
|
||||
const insertConnector = buildInsertIntoWithPool(pool)(Connectors, {
|
||||
returning: true,
|
||||
});
|
||||
const updateConnector = buildUpdateWhereWithPool(pool)<CreateConnector, Connector>(
|
||||
Connectors,
|
||||
true
|
||||
);
|
||||
const updateConnector = buildUpdateWhereWithPool(pool)(Connectors, true);
|
||||
|
||||
return {
|
||||
findAllConnectors,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { CreateCustomPhrase, CustomPhrase } from '@logto/schemas';
|
||||
import type { CustomPhrase } from '@logto/schemas';
|
||||
import { CustomPhrases } from '@logto/schemas';
|
||||
import { convertToIdentifiers, manyRows } from '@logto/shared';
|
||||
import type { CommonQueryMethods } from 'slonik';
|
||||
|
@ -38,16 +38,13 @@ export const createCustomPhraseQueries = (pool: CommonQueryMethods) => {
|
|||
where ${fields.languageTag} = ${languageTag}
|
||||
`);
|
||||
|
||||
const upsertCustomPhrase = buildInsertIntoWithPool(pool)<CreateCustomPhrase, CustomPhrase>(
|
||||
CustomPhrases,
|
||||
{
|
||||
returning: true,
|
||||
onConflict: {
|
||||
fields: [fields.tenantId, fields.languageTag],
|
||||
setExcludedFields: [fields.translation],
|
||||
},
|
||||
}
|
||||
);
|
||||
const upsertCustomPhrase = buildInsertIntoWithPool(pool)(CustomPhrases, {
|
||||
returning: true,
|
||||
onConflict: {
|
||||
fields: [fields.tenantId, fields.languageTag],
|
||||
setExcludedFields: [fields.translation],
|
||||
},
|
||||
});
|
||||
|
||||
const deleteCustomPhraseByLanguageTag = async (languageTag: string) => {
|
||||
const { rowCount } = await pool.query(sql`
|
||||
|
|
|
@ -21,13 +21,13 @@ export const createHooksQueries = (pool: CommonQueryMethods) => {
|
|||
`)
|
||||
);
|
||||
|
||||
const findHookById = buildFindEntityByIdWithPool(pool)<CreateHook, Hook>(Hooks);
|
||||
const findHookById = buildFindEntityByIdWithPool(pool)(Hooks);
|
||||
|
||||
const insertHook = buildInsertIntoWithPool(pool)<CreateHook, Hook>(Hooks, {
|
||||
const insertHook = buildInsertIntoWithPool(pool)(Hooks, {
|
||||
returning: true,
|
||||
});
|
||||
|
||||
const updateHook = buildUpdateWhereWithPool(pool)<CreateHook, Hook>(Hooks, true);
|
||||
const updateHook = buildUpdateWhereWithPool(pool)(Hooks, true);
|
||||
|
||||
const updateHookById = async (
|
||||
id: string,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { CreateLog, Log } from '@logto/schemas';
|
||||
import type { Log } from '@logto/schemas';
|
||||
import { token, Logs } from '@logto/schemas';
|
||||
import { conditionalSql, convertToIdentifiers } from '@logto/shared';
|
||||
import type { CommonQueryMethods } from 'slonik';
|
||||
|
@ -30,7 +30,7 @@ const buildLogConditionSql = (logCondition: LogCondition) =>
|
|||
});
|
||||
|
||||
export const createLogQueries = (pool: CommonQueryMethods) => {
|
||||
const insertLog = buildInsertIntoWithPool(pool)<CreateLog>(Logs);
|
||||
const insertLog = buildInsertIntoWithPool(pool)(Logs);
|
||||
|
||||
const countLogs = async (condition: LogCondition) =>
|
||||
pool.one<{ count: number }>(sql`
|
||||
|
@ -49,7 +49,7 @@ export const createLogQueries = (pool: CommonQueryMethods) => {
|
|||
offset ${offset}
|
||||
`);
|
||||
|
||||
const findLogById = buildFindEntityByIdWithPool(pool)<CreateLog, Log>(Logs);
|
||||
const findLogById = buildFindEntityByIdWithPool(pool)(Logs);
|
||||
|
||||
const getDailyActiveUserCountsByTimeInterval = async (
|
||||
startTimeExclusive: number,
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import type {
|
||||
OidcModelInstance,
|
||||
CreateOidcModelInstance,
|
||||
OidcModelInstancePayload,
|
||||
} from '@logto/schemas';
|
||||
import type { OidcModelInstance, OidcModelInstancePayload } from '@logto/schemas';
|
||||
import { OidcModelInstances } from '@logto/schemas';
|
||||
import { convertToIdentifiers, convertToTimestamp } from '@logto/shared';
|
||||
import type { Nullable } from '@silverhand/essentials';
|
||||
|
@ -59,15 +55,12 @@ const findByModel = (modelName: string) => sql`
|
|||
`;
|
||||
|
||||
export const createOidcModelInstanceQueries = (pool: CommonQueryMethods) => {
|
||||
const upsertInstance = buildInsertIntoWithPool(pool)<CreateOidcModelInstance>(
|
||||
OidcModelInstances,
|
||||
{
|
||||
onConflict: {
|
||||
fields: [fields.tenantId, fields.modelName, fields.id],
|
||||
setExcludedFields: [fields.payload, fields.expiresAt],
|
||||
},
|
||||
}
|
||||
);
|
||||
const upsertInstance = buildInsertIntoWithPool(pool)(OidcModelInstances, {
|
||||
onConflict: {
|
||||
fields: [fields.tenantId, fields.modelName, fields.id],
|
||||
setExcludedFields: [fields.payload, fields.expiresAt],
|
||||
},
|
||||
});
|
||||
|
||||
const findPayloadById = async (modelName: string, id: string) => {
|
||||
const result = await pool.maybeOne<QueryResult>(sql`
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { VerificationCodeType } from '@logto/connector-kit';
|
||||
import type { Passcode, CreatePasscode, RequestVerificationCodePayload } from '@logto/schemas';
|
||||
import type { Passcode, RequestVerificationCodePayload } from '@logto/schemas';
|
||||
import { Passcodes } from '@logto/schemas';
|
||||
import { conditionalSql, convertToIdentifiers } from '@logto/shared';
|
||||
import type { CommonQueryMethods } from 'slonik';
|
||||
|
@ -54,7 +54,7 @@ export const createPasscodeQueries = (pool: CommonQueryMethods) => {
|
|||
properties: FindByIdentifierAndTypeProperties
|
||||
) => pool.any<Passcode>(buildSqlForFindByIdentifierAndType(properties));
|
||||
|
||||
const insertPasscode = buildInsertIntoWithPool(pool)<CreatePasscode, Passcode>(Passcodes, {
|
||||
const insertPasscode = buildInsertIntoWithPool(pool)(Passcodes, {
|
||||
returning: true,
|
||||
});
|
||||
|
||||
|
|
|
@ -111,10 +111,11 @@ describe('resource query', () => {
|
|||
});
|
||||
|
||||
it('insertResource', async () => {
|
||||
const insertFields = Object.values(fields).filter((field) => field.names[0] !== 'tenant_id');
|
||||
const expectSql = sql`
|
||||
insert into ${table} (${sql.join(Object.values(fields), sql`, `)})
|
||||
insert into ${table} (${sql.join(insertFields, sql`, `)})
|
||||
values (${sql.join(
|
||||
Object.values(fields).map((_, index) => `$${index + 1}`),
|
||||
insertFields.map((_, index) => `$${index + 1}`),
|
||||
sql`, `
|
||||
)})
|
||||
returning *
|
||||
|
@ -124,7 +125,9 @@ describe('resource query', () => {
|
|||
expectSqlAssert(sql, expectSql.sql);
|
||||
|
||||
expect(values).toEqual(
|
||||
Resources.fieldKeys.map((k) => convertToPrimitiveOrSql(k, mockResource[k]))
|
||||
Resources.fieldKeys
|
||||
.filter((key) => key !== 'tenantId')
|
||||
.map((k) => convertToPrimitiveOrSql(k, mockResource[k]))
|
||||
);
|
||||
|
||||
return createMockQueryResult([mockResource]);
|
||||
|
|
|
@ -33,7 +33,7 @@ export const createResourceQueries = (pool: CommonQueryMethods) => {
|
|||
where ${fields.indicator}=${indicator}
|
||||
`);
|
||||
|
||||
const findResourceById = buildFindEntityByIdWithPool(pool)<CreateResource, Resource>(Resources);
|
||||
const findResourceById = buildFindEntityByIdWithPool(pool)(Resources);
|
||||
|
||||
const findResourcesByIds = async (resourceIds: string[]) =>
|
||||
resourceIds.length > 0
|
||||
|
@ -44,11 +44,11 @@ export const createResourceQueries = (pool: CommonQueryMethods) => {
|
|||
`)
|
||||
: [];
|
||||
|
||||
const insertResource = buildInsertIntoWithPool(pool)<CreateResource, Resource>(Resources, {
|
||||
const insertResource = buildInsertIntoWithPool(pool)(Resources, {
|
||||
returning: true,
|
||||
});
|
||||
|
||||
const updateResource = buildUpdateWhereWithPool(pool)<CreateResource, Resource>(Resources, true);
|
||||
const updateResource = buildUpdateWhereWithPool(pool)(Resources, true);
|
||||
|
||||
const updateResourceById = async (
|
||||
id: string,
|
||||
|
|
|
@ -125,7 +125,7 @@ describe('roles query', () => {
|
|||
const keys = excludeAutoSetFields(Roles.fieldKeys);
|
||||
|
||||
const expectSql = `
|
||||
insert into "roles" ("tenant_id", "id", "name", "description")
|
||||
insert into "roles" ("id", "name", "description")
|
||||
values (${keys.map((_, index) => `$${index + 1}`).join(', ')})
|
||||
returning *
|
||||
`;
|
||||
|
|
|
@ -108,13 +108,13 @@ export const createRolesQueries = (pool: CommonQueryMethods) => {
|
|||
)}
|
||||
`);
|
||||
|
||||
const insertRole = buildInsertIntoWithPool(pool)<CreateRole, Role>(Roles, {
|
||||
const insertRole = buildInsertIntoWithPool(pool)(Roles, {
|
||||
returning: true,
|
||||
});
|
||||
|
||||
const findRoleById = buildFindEntityByIdWithPool(pool)<CreateRole, Role>(Roles);
|
||||
const findRoleById = buildFindEntityByIdWithPool(pool)(Roles);
|
||||
|
||||
const updateRole = buildUpdateWhereWithPool(pool)<CreateRole, Role>(Roles, true);
|
||||
const updateRole = buildUpdateWhereWithPool(pool)(Roles, true);
|
||||
|
||||
const updateRoleById = async (id: string, set: Partial<OmitAutoSetFields<CreateRole>>) =>
|
||||
updateRole({ set, where: { id }, jsonbMode: 'merge' });
|
||||
|
|
|
@ -124,13 +124,13 @@ export const createScopeQueries = (pool: CommonQueryMethods) => {
|
|||
`)
|
||||
: [];
|
||||
|
||||
const insertScope = buildInsertIntoWithPool(pool)<CreateScope, Scope>(Scopes, {
|
||||
const insertScope = buildInsertIntoWithPool(pool)(Scopes, {
|
||||
returning: true,
|
||||
});
|
||||
|
||||
const findScopeById = buildFindEntityByIdWithPool(pool)<CreateScope, Scope>(Scopes);
|
||||
const findScopeById = buildFindEntityByIdWithPool(pool)(Scopes);
|
||||
|
||||
const updateScope = buildUpdateWhereWithPool(pool)<CreateScope, Scope>(Scopes, true);
|
||||
const updateScope = buildUpdateWhereWithPool(pool)(Scopes, true);
|
||||
|
||||
const updateScopeById = async (id: string, set: Partial<OmitAutoSetFields<CreateScope>>) =>
|
||||
updateScope({ set, where: { id }, jsonbMode: 'merge' });
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { SignInExperience, CreateSignInExperience } from '@logto/schemas';
|
||||
import type { CreateSignInExperience } from '@logto/schemas';
|
||||
import { SignInExperiences } from '@logto/schemas';
|
||||
import type { CommonQueryMethods } from 'slonik';
|
||||
|
||||
|
@ -8,18 +8,13 @@ import { buildUpdateWhereWithPool } from '#src/database/update-where.js';
|
|||
const id = 'default';
|
||||
|
||||
export const createSignInExperienceQueries = (pool: CommonQueryMethods) => {
|
||||
const updateSignInExperience = buildUpdateWhereWithPool(pool)<
|
||||
CreateSignInExperience,
|
||||
SignInExperience
|
||||
>(SignInExperiences, true);
|
||||
const updateSignInExperience = buildUpdateWhereWithPool(pool)(SignInExperiences, true);
|
||||
|
||||
const updateDefaultSignInExperience = async (set: Partial<CreateSignInExperience>) =>
|
||||
updateSignInExperience({ set, where: { id }, jsonbMode: 'replace' });
|
||||
|
||||
const findDefaultSignInExperience = async () =>
|
||||
buildFindEntityByIdWithPool(pool)<CreateSignInExperience, SignInExperience>(SignInExperiences)(
|
||||
id
|
||||
);
|
||||
buildFindEntityByIdWithPool(pool)(SignInExperiences)(id);
|
||||
|
||||
return { updateDefaultSignInExperience, findDefaultSignInExperience };
|
||||
};
|
||||
|
|
|
@ -172,7 +172,7 @@ export const createUserQueries = (pool: CommonQueryMethods) => {
|
|||
`)
|
||||
: [];
|
||||
|
||||
const updateUser = buildUpdateWhereWithPool(pool)<CreateUser, User>(Users, true);
|
||||
const updateUser = buildUpdateWhereWithPool(pool)(Users, true);
|
||||
|
||||
const updateUserById = async (
|
||||
id: string,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { CreateVerificationStatus, VerificationStatus } from '@logto/schemas';
|
||||
import type { VerificationStatus } from '@logto/schemas';
|
||||
import { VerificationStatuses } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import type { CommonQueryMethods } from 'slonik';
|
||||
|
@ -16,10 +16,7 @@ export const createVerificationStatusQueries = (pool: CommonQueryMethods) => {
|
|||
where ${fields.userId}=${userId}
|
||||
`);
|
||||
|
||||
const insertVerificationStatus = buildInsertIntoWithPool(pool)<
|
||||
CreateVerificationStatus,
|
||||
VerificationStatus
|
||||
>(VerificationStatuses, {
|
||||
const insertVerificationStatus = buildInsertIntoWithPool(pool)(VerificationStatuses, {
|
||||
returning: true,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import type { GeneratedSchema, SchemaLike } from '@logto/schemas';
|
||||
|
||||
export const isKeyOf =
|
||||
<Schema extends SchemaLike>({ fieldKeys }: GeneratedSchema<Schema>) =>
|
||||
<CreateSchema extends SchemaLike, Schema extends CreateSchema>({
|
||||
fieldKeys,
|
||||
}: GeneratedSchema<CreateSchema, Schema>) =>
|
||||
(key: string): key is keyof Schema extends string ? keyof Schema : never =>
|
||||
fieldKeys.includes(key);
|
||||
|
|
|
@ -18,7 +18,10 @@ export type SchemaLike<Key extends string = string> = {
|
|||
[key in Key]: SchemaValue;
|
||||
};
|
||||
|
||||
export type GeneratedSchema<Schema extends SchemaLike> = keyof Schema extends string
|
||||
export type GeneratedSchema<
|
||||
CreateSchema extends SchemaLike,
|
||||
Schema extends CreateSchema
|
||||
> = keyof Schema extends string
|
||||
? Readonly<{
|
||||
table: string;
|
||||
tableSingular: string;
|
||||
|
@ -26,7 +29,7 @@ export type GeneratedSchema<Schema extends SchemaLike> = keyof Schema extends st
|
|||
[key in keyof Required<Schema>]: string;
|
||||
};
|
||||
fieldKeys: ReadonlyArray<keyof Schema>;
|
||||
createGuard: CreateGuard<Schema>;
|
||||
createGuard: CreateGuard<CreateSchema>;
|
||||
guard: Guard<Schema>;
|
||||
}>
|
||||
: never;
|
||||
|
|
|
@ -75,7 +75,7 @@ export const generateSchema = ({ name, fields }: TableWithType) => {
|
|||
'',
|
||||
`export const ${camelcase(name, {
|
||||
pascalCase: true,
|
||||
})}: GeneratedSchema<${databaseEntryType}> = Object.freeze({`,
|
||||
})}: GeneratedSchema<${databaseEntryType}, ${modelName}> = Object.freeze({`,
|
||||
` table: '${name}',`,
|
||||
` tableSingular: '${pluralize(name, 1)}',`,
|
||||
' fields: {',
|
||||
|
|
|
@ -13,7 +13,7 @@ export const conditionalArraySql = <T>(
|
|||
buildSql: (value: Exclude<T[], Falsy>) => SqlSqlToken
|
||||
) => (value.length > 0 ? buildSql(value) : sql``);
|
||||
|
||||
export const autoSetFields = Object.freeze(['createdAt', 'updatedAt'] as const);
|
||||
export const autoSetFields = Object.freeze(['tenantId', 'createdAt', 'updatedAt'] as const);
|
||||
export type OmitAutoSetFields<T> = Omit<T, (typeof autoSetFields)[number]>;
|
||||
export type ExcludeAutoSetFields<T> = Exclude<T, (typeof autoSetFields)[number]>;
|
||||
export const excludeAutoSetFields = <T extends string>(fields: readonly T[]) =>
|
||||
|
|
Loading…
Add table
Reference in a new issue