mirror of
https://github.com/logto-io/logto.git
synced 2025-03-17 22:31:28 -05:00
refactor(core,cli): extract common utils to @logto/shared
This commit is contained in:
parent
4b0970b6d8
commit
ba09de9b1e
52 changed files with 295 additions and 148 deletions
|
@ -1 +1,7 @@
|
|||
export { default } from '@silverhand/jest-config';
|
||||
import { merge, Config } from '@silverhand/jest-config';
|
||||
|
||||
const config: Config.InitialOptions = merge({
|
||||
roots: ['./src'],
|
||||
});
|
||||
|
||||
export default config;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@logto/schemas": "^1.0.0-beta.10",
|
||||
"@logto/shared": "^1.0.0-beta.10",
|
||||
"@silverhand/essentials": "^1.2.1",
|
||||
"chalk": "^4.1.2",
|
||||
"decamelize": "^5.0.0",
|
||||
|
|
|
@ -2,6 +2,7 @@ import { readdir, readFile } from 'fs/promises';
|
|||
import path from 'path';
|
||||
|
||||
import { logtoConfigGuards, LogtoOidcConfigKey, seeds } from '@logto/schemas';
|
||||
import { buildApplicationSecret } from '@logto/shared';
|
||||
import chalk from 'chalk';
|
||||
import { DatabasePool, DatabaseTransactionConnection, sql } from 'slonik';
|
||||
import { raw } from 'slonik-sql-tag-raw';
|
||||
|
@ -14,7 +15,7 @@ import {
|
|||
updateDatabaseTimestamp,
|
||||
updateValueByKey,
|
||||
} from '../../../queries/logto-config';
|
||||
import { buildApplicationSecret, getPathInModule, log, oraPromise } from '../../../utilities';
|
||||
import { getPathInModule, log, oraPromise } from '../../../utilities';
|
||||
import { getLatestAlterationTimestamp } from '../alteration';
|
||||
import { oidcConfigReaders } from './oidc-config';
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { SchemaLike, SchemaValue, SchemaValuePrimitive } from '@logto/schemas';
|
||||
import { SchemaLike } from '@logto/schemas';
|
||||
import { convertToPrimitiveOrSql } from '@logto/shared';
|
||||
import decamelize from 'decamelize';
|
||||
import { createPool, IdentifierSqlToken, parseDsn, sql, SqlToken, stringifyDsn } from 'slonik';
|
||||
import { createPool, parseDsn, sql, stringifyDsn } from 'slonik';
|
||||
import { createInterceptors } from 'slonik-interceptor-preset';
|
||||
import { z } from 'zod';
|
||||
|
||||
|
@ -62,67 +63,6 @@ export const createPoolAndDatabaseIfNeeded = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
// TODO: Move database utils to `core-kit`
|
||||
export type Table = { table: string; fields: Record<string, string> };
|
||||
export type FieldIdentifiers<Key extends string | number | symbol> = {
|
||||
[key in Key]: IdentifierSqlToken;
|
||||
};
|
||||
|
||||
export const convertToIdentifiers = <T extends Table>({ table, fields }: T, withPrefix = false) => {
|
||||
const fieldsIdentifiers = Object.entries<string>(fields).map<
|
||||
[keyof T['fields'], IdentifierSqlToken]
|
||||
>(([key, value]) => [key, sql.identifier(withPrefix ? [table, value] : [value])]);
|
||||
|
||||
return {
|
||||
table: sql.identifier([table]),
|
||||
// Key value inferred from the original fields directly
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
fields: Object.fromEntries(fieldsIdentifiers) as FieldIdentifiers<keyof T['fields']>,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Note `undefined` is removed from the acceptable list,
|
||||
* since you should NOT call this function if ignoring the field is the desired behavior.
|
||||
* Calling this function with `null` means an explicit `null` setting in database is expected.
|
||||
* @param key The key of value. Will treat as `timestamp` if it ends with `_at` or 'At' AND value is a number;
|
||||
* @param value The value to convert.
|
||||
* @returns A primitive that can be saved into database.
|
||||
*/
|
||||
// eslint-disable-next-line complexity
|
||||
export const convertToPrimitiveOrSql = (
|
||||
key: string,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
value: NonNullable<SchemaValue> | null
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
): NonNullable<SchemaValuePrimitive> | SqlToken | null => {
|
||||
if (value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof value === 'object') {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
|
||||
if (['_at', 'At'].some((value) => key.endsWith(value)) && typeof value === 'number') {
|
||||
return sql`to_timestamp(${value}::double precision / 1000)`;
|
||||
}
|
||||
|
||||
if (typeof value === 'number' || typeof value === 'boolean') {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
if (value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new Error(`Cannot convert ${key} to primitive`);
|
||||
};
|
||||
|
||||
export const insertInto = <T extends SchemaLike>(object: T, table: string) => {
|
||||
const keys = Object.keys(object);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { AlterationStateKey, LogtoConfigs } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
|
||||
import { convertToIdentifiers } from '../database';
|
||||
import { expectSqlAssert, QueryType } from '../test-utilities';
|
||||
import { updateDatabaseTimestamp, getCurrentDatabaseAlterationTimestamp } from './logto-config';
|
||||
|
||||
|
|
|
@ -6,11 +6,10 @@ import {
|
|||
LogtoConfigs,
|
||||
AlterationStateKey,
|
||||
} from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { DatabasePool, DatabaseTransactionConnection, sql } from 'slonik';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { convertToIdentifiers } from '../database';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(LogtoConfigs);
|
||||
|
||||
export const getRowsByKeys = async (
|
||||
|
|
|
@ -7,7 +7,6 @@ import chalk from 'chalk';
|
|||
import got, { Progress } from 'got';
|
||||
import { HttpsProxyAgent } from 'hpagent';
|
||||
import inquirer from 'inquirer';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import ora from 'ora';
|
||||
|
||||
export const safeExecSync = (command: string) => {
|
||||
|
@ -159,9 +158,3 @@ export const getCliConfig = async ({ key, readableKey, comments, defaultValue }:
|
|||
export const noop = () => {};
|
||||
|
||||
export const deduplicate = <T>(array: T[]) => [...new Set(array)];
|
||||
|
||||
export const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
export const buildIdGenerator = (size: number) => customAlphabet(alphabet, size);
|
||||
|
||||
export const buildApplicationSecret = buildIdGenerator(21);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
"@logto/phrases": "^1.0.0-beta.10",
|
||||
"@logto/phrases-ui": "^1.0.0-beta.10",
|
||||
"@logto/schemas": "^1.0.0-beta.10",
|
||||
"@logto/shared": "^1.0.0-beta.10",
|
||||
"@silverhand/essentials": "^1.2.1",
|
||||
"chalk": "^4",
|
||||
"clean-deep": "^3.4.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { SchemaLike, GeneratedSchema } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { sql, NotFoundError } from 'slonik';
|
||||
|
||||
import { convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import assertThat from '@/utils/assert-that';
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { CreateUser, Users } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import decamelize from 'decamelize';
|
||||
|
||||
import envSet from '@/env-set';
|
||||
|
@ -6,7 +7,6 @@ import { InsertionError } from '@/errors/SlonikError';
|
|||
import { createTestPool } from '@/utils/test-utils';
|
||||
|
||||
import { buildInsertInto } from './insert-into';
|
||||
import { convertToIdentifiers } from './utils';
|
||||
|
||||
const poolSpy = jest.spyOn(envSet, 'pool', 'get');
|
||||
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import { GeneratedSchema, SchemaLike } from '@logto/schemas';
|
||||
import {
|
||||
OmitAutoSetFields,
|
||||
convertToIdentifiers,
|
||||
excludeAutoSetFields,
|
||||
convertToPrimitiveOrSql,
|
||||
conditionalSql,
|
||||
} from '@logto/shared';
|
||||
import { has } from '@silverhand/essentials';
|
||||
import { IdentifierSqlToken, sql } from 'slonik';
|
||||
|
||||
|
@ -6,14 +13,6 @@ import envSet from '@/env-set';
|
|||
import { InsertionError } from '@/errors/SlonikError';
|
||||
import assertThat from '@/utils/assert-that';
|
||||
|
||||
import {
|
||||
conditionalSql,
|
||||
convertToIdentifiers,
|
||||
convertToPrimitiveOrSql,
|
||||
excludeAutoSetFields,
|
||||
OmitAutoSetFields,
|
||||
} from './utils';
|
||||
|
||||
const setExcluded = (...fields: IdentifierSqlToken[]) =>
|
||||
sql.join(
|
||||
fields.map((field) => sql`${field}=excluded.${field}`),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { CreateUser, Users, Applications, User } from '@logto/schemas';
|
||||
import { UpdateWhereData } from '@logto/shared';
|
||||
|
||||
import envSet from '@/env-set';
|
||||
import { UpdateError } from '@/errors/SlonikError';
|
||||
import { createTestPool } from '@/utils/test-utils';
|
||||
|
||||
import { UpdateWhereData } from './types';
|
||||
import { buildUpdateWhere } from './update-where';
|
||||
|
||||
const poolSpy = jest.spyOn(envSet, 'pool', 'get');
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import { SchemaLike, GeneratedSchema } from '@logto/schemas';
|
||||
import {
|
||||
UpdateWhereData,
|
||||
convertToIdentifiers,
|
||||
convertToPrimitiveOrSql,
|
||||
conditionalSql,
|
||||
} from '@logto/shared';
|
||||
import { notFalsy, Truthy } from '@silverhand/essentials';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
|
@ -7,9 +13,6 @@ import { UpdateError } from '@/errors/SlonikError';
|
|||
import assertThat from '@/utils/assert-that';
|
||||
import { isKeyOf } from '@/utils/schema';
|
||||
|
||||
import { UpdateWhereData } from './types';
|
||||
import { conditionalSql, convertToIdentifiers, convertToPrimitiveOrSql } from './utils';
|
||||
|
||||
type BuildUpdateWhere = {
|
||||
<Schema extends SchemaLike, ReturnType extends SchemaLike>(
|
||||
schema: GeneratedSchema<Schema>,
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import { SchemaLike, GeneratedSchema } from '@logto/schemas';
|
||||
import { OmitAutoSetFields, UpdateWhereData } from '@logto/shared';
|
||||
import { SlonikError } from 'slonik';
|
||||
|
||||
import { UpdateWhereData } from '@/database/types';
|
||||
import { OmitAutoSetFields } from '@/database/utils';
|
||||
|
||||
export class DeletionError extends SlonikError {
|
||||
table?: string;
|
||||
id?: string;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { User, CreateUser, Users, UsersPasswordEncryptionMethod } from '@logto/schemas';
|
||||
import { buildIdGenerator } from '@logto/shared';
|
||||
import { argon2Verify } from 'hash-wasm';
|
||||
import pRetry from 'p-retry';
|
||||
|
||||
|
@ -7,7 +8,6 @@ import envSet from '@/env-set';
|
|||
import { findRolesByRoleNames, insertRoles } from '@/queries/roles';
|
||||
import { findUserByUsername, hasUserWithId } from '@/queries/user';
|
||||
import assertThat from '@/utils/assert-that';
|
||||
import { buildIdGenerator } from '@/utils/id';
|
||||
import { encryptPassword } from '@/utils/password';
|
||||
|
||||
const userId = buildIdGenerator(12);
|
||||
|
|
|
@ -27,7 +27,7 @@ jest.mock('@/queries/oidc-model-instance', () => ({
|
|||
revokeInstanceByGrantId: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/utils/id', () => ({
|
||||
jest.mock('@logto/shared', () => ({
|
||||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||
buildIdGenerator: jest.fn(() => () => 'randomId'),
|
||||
}));
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import { Applications } from '@logto/schemas';
|
||||
import { convertToIdentifiers, convertToPrimitiveOrSql, excludeAutoSetFields } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
import { snakeCase } from 'snake-case';
|
||||
|
||||
import { mockApplication } from '@/__mocks__';
|
||||
import {
|
||||
convertToIdentifiers,
|
||||
convertToPrimitiveOrSql,
|
||||
excludeAutoSetFields,
|
||||
} from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
import { expectSqlAssert, QueryType } from '@/utils/test-utils';
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
import { Application, CreateApplication, Applications } from '@logto/schemas';
|
||||
import { convertToIdentifiers, OmitAutoSetFields, conditionalSql, manyRows } from '@logto/shared';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import { buildFindEntityById } from '@/database/find-entity-by-id';
|
||||
import { buildInsertInto } from '@/database/insert-into';
|
||||
import { getTotalRowCount } from '@/database/row-count';
|
||||
import { buildUpdateWhere } from '@/database/update-where';
|
||||
import {
|
||||
convertToIdentifiers,
|
||||
OmitAutoSetFields,
|
||||
conditionalSql,
|
||||
manyRows,
|
||||
} from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Connectors } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
|
||||
import { mockConnector } from '@/__mocks__';
|
||||
import { convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { expectSqlAssert, QueryType } from '@/utils/test-utils';
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Connector, CreateConnector, Connectors } from '@logto/schemas';
|
||||
import { convertToIdentifiers, manyRows } from '@logto/shared';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import { buildInsertInto } from '@/database/insert-into';
|
||||
import { buildUpdateWhere } from '@/database/update-where';
|
||||
import { convertToIdentifiers, manyRows } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Connectors);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { CreateCustomPhrase, CustomPhrase, CustomPhrases } from '@logto/schemas';
|
||||
import { convertToIdentifiers, manyRows } from '@logto/shared';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import { buildInsertInto } from '@/database/insert-into';
|
||||
import { convertToIdentifiers, manyRows } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { CreateLog, Log, Logs, LogType } from '@logto/schemas';
|
||||
import { conditionalSql, convertToIdentifiers } from '@logto/shared';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import { buildFindEntityById } from '@/database/find-entity-by-id';
|
||||
import { buildInsertInto } from '@/database/insert-into';
|
||||
import { conditionalSql, convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Logs);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { OidcModelInstances, CreateOidcModelInstance } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
|
||||
import { convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { expectSqlAssert, QueryType } from '@/utils/test-utils';
|
||||
|
||||
|
@ -24,8 +24,8 @@ jest.spyOn(envSet, 'pool', 'get').mockReturnValue(
|
|||
})
|
||||
);
|
||||
|
||||
jest.mock('@/database/utils', () => ({
|
||||
...jest.requireActual('@/database/utils'),
|
||||
jest.mock('@logto/shared', () => ({
|
||||
...jest.requireActual('@logto/shared'),
|
||||
convertToTimestamp: () => 100,
|
||||
}));
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ import {
|
|||
OidcModelInstancePayload,
|
||||
OidcModelInstances,
|
||||
} from '@logto/schemas';
|
||||
import { convertToIdentifiers, convertToTimestamp } from '@logto/shared';
|
||||
import { conditional, Nullable } from '@silverhand/essentials';
|
||||
import dayjs from 'dayjs';
|
||||
import { sql, ValueExpression } from 'slonik';
|
||||
|
||||
import { buildInsertInto } from '@/database/insert-into';
|
||||
import { convertToIdentifiers, convertToTimestamp } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
|
||||
export type WithConsumed<T> = T & { consumed?: boolean };
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import { Passcodes, PasscodeType } from '@logto/schemas';
|
||||
import { convertToIdentifiers, convertToPrimitiveOrSql, excludeAutoSetFields } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
import { snakeCase } from 'snake-case';
|
||||
|
||||
import { mockPasscode } from '@/__mocks__';
|
||||
import {
|
||||
convertToIdentifiers,
|
||||
convertToPrimitiveOrSql,
|
||||
excludeAutoSetFields,
|
||||
} from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
import { expectSqlAssert, QueryType } from '@/utils/test-utils';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { PasscodeType, Passcode, Passcodes, CreatePasscode } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import { buildInsertInto } from '@/database/insert-into';
|
||||
import { convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Resources } from '@logto/schemas';
|
||||
import { convertToIdentifiers, convertToPrimitiveOrSql } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
|
||||
import { mockResource } from '@/__mocks__';
|
||||
import { convertToIdentifiers, convertToPrimitiveOrSql } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
import { expectSqlAssert, QueryType } from '@/utils/test-utils';
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
import { Resource, CreateResource, Resources } from '@logto/schemas';
|
||||
import { convertToIdentifiers, OmitAutoSetFields, conditionalSql, manyRows } from '@logto/shared';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import { buildFindEntityById } from '@/database/find-entity-by-id';
|
||||
import { buildInsertInto } from '@/database/insert-into';
|
||||
import { getTotalRowCount } from '@/database/row-count';
|
||||
import { buildUpdateWhere } from '@/database/update-where';
|
||||
import {
|
||||
convertToIdentifiers,
|
||||
OmitAutoSetFields,
|
||||
conditionalSql,
|
||||
manyRows,
|
||||
} from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Roles } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
|
||||
import { mockRole } from '@/__mocks__';
|
||||
import { convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { expectSqlAssert, QueryType } from '@/utils/test-utils';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Roles, Role } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import { convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
|
||||
const { table, fields } = convertToIdentifiers(Roles);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Settings } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
|
||||
import { mockSetting } from '@/__mocks__';
|
||||
import { convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { expectSqlAssert, QueryType } from '@/utils/test-utils';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Setting, CreateSetting, Settings } from '@logto/schemas';
|
||||
import { OmitAutoSetFields } from '@logto/shared';
|
||||
|
||||
import { buildFindEntityById } from '@/database/find-entity-by-id';
|
||||
import { buildUpdateWhere } from '@/database/update-where';
|
||||
import { OmitAutoSetFields } from '@/database/utils';
|
||||
|
||||
export const defaultSettingId = 'default';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { UserRole, Users } from '@logto/schemas';
|
||||
import { convertToIdentifiers } from '@logto/shared';
|
||||
import { createMockPool, createMockQueryResult, sql } from 'slonik';
|
||||
|
||||
import { mockUser } from '@/__mocks__';
|
||||
import { convertToIdentifiers } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
import { expectSqlAssert, QueryType } from '@/utils/test-utils';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { User, CreateUser, Users, UserRole } from '@logto/schemas';
|
||||
import { conditionalSql, convertToIdentifiers, OmitAutoSetFields } from '@logto/shared';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import { buildUpdateWhere } from '@/database/update-where';
|
||||
import { conditionalSql, convertToIdentifiers, OmitAutoSetFields } from '@/database/utils';
|
||||
import envSet from '@/env-set';
|
||||
import { DeletionError } from '@/errors/SlonikError';
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ jest.mock('@/queries/application', () => ({
|
|||
),
|
||||
}));
|
||||
|
||||
jest.mock('@/utils/id', () => ({
|
||||
jest.mock('@logto/shared', () => ({
|
||||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||
buildIdGenerator: jest.fn(() => () => 'randomId'),
|
||||
buildApplicationSecret: jest.fn(() => 'randomId'),
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Applications } from '@logto/schemas';
|
||||
import { buildApplicationSecret, buildIdGenerator } from '@logto/shared';
|
||||
import { object, string } from 'zod';
|
||||
|
||||
import koaGuard from '@/middleware/koa-guard';
|
||||
|
@ -12,7 +13,6 @@ import {
|
|||
updateApplicationById,
|
||||
findTotalNumberOfApplications,
|
||||
} from '@/queries/application';
|
||||
import { buildApplicationSecret, buildIdGenerator } from '@/utils/id';
|
||||
|
||||
import { AuthedRouter } from './types';
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ jest.mock('@/queries/resource', () => ({
|
|||
deleteResourceById: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/utils/id', () => ({
|
||||
jest.mock('@logto/shared', () => ({
|
||||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||
buildIdGenerator: jest.fn(() => () => 'randomId'),
|
||||
}));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Resources } from '@logto/schemas';
|
||||
import { buildIdGenerator } from '@logto/shared';
|
||||
import { object, string } from 'zod';
|
||||
|
||||
import koaGuard from '@/middleware/koa-guard';
|
||||
|
@ -11,7 +12,6 @@ import {
|
|||
updateResourceById,
|
||||
deleteResourceById,
|
||||
} from '@/queries/resource';
|
||||
import { buildIdGenerator } from '@/utils/id';
|
||||
|
||||
import { AuthedRouter } from './types';
|
||||
|
||||
|
|
7
packages/shared/jest.config.ts
Normal file
7
packages/shared/jest.config.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { merge, Config } from '@silverhand/jest-config';
|
||||
|
||||
const config: Config.InitialOptions = merge({
|
||||
roots: ['./src'],
|
||||
});
|
||||
|
||||
export default config;
|
48
packages/shared/package.json
Normal file
48
packages/shared/package.json
Normal file
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"name": "@logto/shared",
|
||||
"version": "1.0.0-beta.10",
|
||||
"main": "lib/index.js",
|
||||
"author": "Silverhand Inc. <contact@silverhand.io>",
|
||||
"license": "MPL-2.0",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"build": "rm -rf lib/ && tsc -p tsconfig.build.json",
|
||||
"dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental",
|
||||
"lint": "eslint --ext .ts src",
|
||||
"prepack": "pnpm build",
|
||||
"test": "jest",
|
||||
"test:ci": "jest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@silverhand/eslint-config": "1.0.0",
|
||||
"@silverhand/jest-config": "1.0.0",
|
||||
"@silverhand/ts-config": "1.0.0",
|
||||
"@types/jest": "^29.1.2",
|
||||
"eslint": "^8.21.0",
|
||||
"jest": "^28.1.3",
|
||||
"lint-staged": "^13.0.0",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.0.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "@silverhand",
|
||||
"rules": {
|
||||
"@typescript-eslint/ban-types": "off"
|
||||
}
|
||||
},
|
||||
"prettier": "@silverhand/eslint-config/.prettierrc",
|
||||
"dependencies": {
|
||||
"@logto/schemas": "^1.0.0-beta.10",
|
||||
"@silverhand/essentials": "^1.2.1",
|
||||
"dayjs": "^1.10.5",
|
||||
"nanoid": "^3.3.4",
|
||||
"slonik": "^30.0.0"
|
||||
}
|
||||
}
|
2
packages/shared/src/database/index.ts
Normal file
2
packages/shared/src/database/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from './types';
|
||||
export * from './utils';
|
|
@ -29,11 +29,10 @@ export const excludeAutoSetFields = <T extends string>(fields: readonly T[]) =>
|
|||
* @param value The value to convert.
|
||||
* @returns A primitive that can be saved into database.
|
||||
*/
|
||||
// eslint-disable-next-line complexity
|
||||
export const convertToPrimitiveOrSql = (
|
||||
key: string,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
value: NonNullable<SchemaValue> | null
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
): NonNullable<SchemaValuePrimitive> | SqlToken | null => {
|
||||
if (value === null) {
|
||||
return null;
|
2
packages/shared/src/index.ts
Normal file
2
packages/shared/src/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from './database';
|
||||
export * from './utils';
|
1
packages/shared/src/utils/index.ts
Normal file
1
packages/shared/src/utils/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './id';
|
4
packages/shared/tsconfig.build.json
Normal file
4
packages/shared/tsconfig.build.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "./tsconfig",
|
||||
"include": ["src"]
|
||||
}
|
11
packages/shared/tsconfig.json
Normal file
11
packages/shared/tsconfig.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "@silverhand/ts-config/tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib",
|
||||
"declaration": true
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"jest.config.ts"
|
||||
]
|
||||
}
|
3
packages/shared/tsconfig.test.json
Normal file
3
packages/shared/tsconfig.test.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"extends": "./tsconfig"
|
||||
}
|
167
pnpm-lock.yaml
generated
167
pnpm-lock.yaml
generated
|
@ -21,6 +21,7 @@ importers:
|
|||
packages/cli:
|
||||
specifiers:
|
||||
'@logto/schemas': ^1.0.0-beta.10
|
||||
'@logto/shared': ^1.0.0-beta.10
|
||||
'@silverhand/eslint-config': 1.0.0
|
||||
'@silverhand/essentials': ^1.2.1
|
||||
'@silverhand/jest-config': 1.0.0
|
||||
|
@ -60,6 +61,7 @@ importers:
|
|||
zod: ^3.18.0
|
||||
dependencies:
|
||||
'@logto/schemas': link:../schemas
|
||||
'@logto/shared': link:../shared
|
||||
'@silverhand/essentials': 1.2.1
|
||||
chalk: 4.1.2
|
||||
decamelize: 5.0.1
|
||||
|
@ -244,6 +246,7 @@ importers:
|
|||
'@logto/phrases': ^1.0.0-beta.10
|
||||
'@logto/phrases-ui': ^1.0.0-beta.10
|
||||
'@logto/schemas': ^1.0.0-beta.10
|
||||
'@logto/shared': ^1.0.0-beta.10
|
||||
'@shopify/jest-koa-mocks': ^5.0.0
|
||||
'@silverhand/eslint-config': 1.0.0
|
||||
'@silverhand/essentials': ^1.2.1
|
||||
|
@ -326,6 +329,7 @@ importers:
|
|||
'@logto/phrases': link:../phrases
|
||||
'@logto/phrases-ui': link:../phrases-ui
|
||||
'@logto/schemas': link:../schemas
|
||||
'@logto/shared': link:../shared
|
||||
'@silverhand/essentials': 1.2.1
|
||||
chalk: 4.1.2
|
||||
clean-deep: 3.4.0
|
||||
|
@ -613,6 +617,39 @@ importers:
|
|||
ts-node: 10.9.1_ccwudyfw5se7hgalwgkzhn2yp4
|
||||
typescript: 4.7.4
|
||||
|
||||
packages/shared:
|
||||
specifiers:
|
||||
'@logto/schemas': ^1.0.0-beta.10
|
||||
'@silverhand/eslint-config': 1.0.0
|
||||
'@silverhand/essentials': ^1.2.1
|
||||
'@silverhand/jest-config': 1.0.0
|
||||
'@silverhand/ts-config': 1.0.0
|
||||
'@types/jest': ^29.1.2
|
||||
dayjs: ^1.10.5
|
||||
eslint: ^8.21.0
|
||||
jest: ^28.1.3
|
||||
lint-staged: ^13.0.0
|
||||
nanoid: ^3.3.4
|
||||
prettier: ^2.7.1
|
||||
slonik: ^30.0.0
|
||||
typescript: ^4.7.4
|
||||
dependencies:
|
||||
'@logto/schemas': link:../schemas
|
||||
'@silverhand/essentials': 1.2.1
|
||||
dayjs: 1.10.7
|
||||
nanoid: 3.3.4
|
||||
slonik: 30.1.2
|
||||
devDependencies:
|
||||
'@silverhand/eslint-config': 1.0.0_swk2g7ygmfleszo5c33j4vooni
|
||||
'@silverhand/jest-config': 1.0.0_bi2kohzqnxavgozw3csgny5hju
|
||||
'@silverhand/ts-config': 1.0.0_typescript@4.7.4
|
||||
'@types/jest': 29.1.2
|
||||
eslint: 8.21.0
|
||||
jest: 28.1.3
|
||||
lint-staged: 13.0.0
|
||||
prettier: 2.7.1
|
||||
typescript: 4.7.4
|
||||
|
||||
packages/ui:
|
||||
specifiers:
|
||||
'@logto/core-kit': ^1.0.0-beta.13
|
||||
|
@ -882,11 +919,11 @@ packages:
|
|||
/@babel/helper-validator-identifier/7.16.7:
|
||||
resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: false
|
||||
|
||||
/@babel/helper-validator-identifier/7.18.6:
|
||||
resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/helper-validator-option/7.16.7:
|
||||
resolution: {integrity: sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==}
|
||||
|
@ -908,7 +945,7 @@ packages:
|
|||
resolution: {integrity: sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.16.7
|
||||
'@babel/helper-validator-identifier': 7.18.6
|
||||
chalk: 2.4.2
|
||||
js-tokens: 4.0.0
|
||||
|
||||
|
@ -1545,6 +1582,13 @@ packages:
|
|||
jest-get-type: 28.0.2
|
||||
dev: true
|
||||
|
||||
/@jest/expect-utils/29.1.2:
|
||||
resolution: {integrity: sha512-4a48bhKfGj/KAH39u0ppzNTABXQ8QPccWAFUFobWBaEMSMp+sB31Z2fK/l47c4a/Mu1po2ffmfAIPxXbVTXdtg==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
jest-get-type: 29.0.0
|
||||
dev: true
|
||||
|
||||
/@jest/expect/28.1.3:
|
||||
resolution: {integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
|
@ -1635,6 +1679,13 @@ packages:
|
|||
'@sinclair/typebox': 0.24.26
|
||||
dev: true
|
||||
|
||||
/@jest/schemas/29.0.0:
|
||||
resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@sinclair/typebox': 0.24.26
|
||||
dev: true
|
||||
|
||||
/@jest/source-map/28.1.2:
|
||||
resolution: {integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
|
@ -1710,6 +1761,18 @@ packages:
|
|||
chalk: 4.1.2
|
||||
dev: true
|
||||
|
||||
/@jest/types/29.1.2:
|
||||
resolution: {integrity: sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@jest/schemas': 29.0.0
|
||||
'@types/istanbul-lib-coverage': 2.0.3
|
||||
'@types/istanbul-reports': 3.0.1
|
||||
'@types/node': 17.0.23
|
||||
'@types/yargs': 17.0.13
|
||||
chalk: 4.1.2
|
||||
dev: true
|
||||
|
||||
/@jridgewell/gen-mapping/0.3.2:
|
||||
resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
@ -4489,6 +4552,13 @@ packages:
|
|||
pretty-format: 28.1.3
|
||||
dev: true
|
||||
|
||||
/@types/jest/29.1.2:
|
||||
resolution: {integrity: sha512-y+nlX0h87U0R+wsGn6EBuoRWYyv3KFtwRNP3QWp9+k2tJ2/bqcGS3UxD7jgT+tiwJWWq3UsyV4Y+T6rsMT4XMg==}
|
||||
dependencies:
|
||||
expect: 29.1.2
|
||||
pretty-format: 29.1.2
|
||||
dev: true
|
||||
|
||||
/@types/js-yaml/4.0.5:
|
||||
resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==}
|
||||
dev: true
|
||||
|
@ -6654,6 +6724,11 @@ packages:
|
|||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dev: true
|
||||
|
||||
/diff-sequences/29.0.0:
|
||||
resolution: {integrity: sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dev: true
|
||||
|
||||
/diff/4.0.2:
|
||||
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
|
@ -6940,7 +7015,7 @@ packages:
|
|||
resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=}
|
||||
|
||||
/escape-string-regexp/1.0.5:
|
||||
resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=}
|
||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
||||
/escape-string-regexp/2.0.0:
|
||||
|
@ -7523,6 +7598,17 @@ packages:
|
|||
jest-util: 28.1.3
|
||||
dev: true
|
||||
|
||||
/expect/29.1.2:
|
||||
resolution: {integrity: sha512-AuAGn1uxva5YBbBlXb+2JPxJRuemZsmlGcapPXWNSBNsQtAULfjioREGBWuI0EOvYUKjDnrCy8PW5Zlr1md5mw==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@jest/expect-utils': 29.1.2
|
||||
jest-get-type: 29.0.0
|
||||
jest-matcher-utils: 29.1.2
|
||||
jest-message-util: 29.1.2
|
||||
jest-util: 29.1.2
|
||||
dev: true
|
||||
|
||||
/extend/3.0.2:
|
||||
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
|
||||
dev: true
|
||||
|
@ -7847,7 +7933,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/functional-red-black-tree/1.0.1:
|
||||
resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=}
|
||||
resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==}
|
||||
dev: true
|
||||
|
||||
/functions-have-names/1.2.3:
|
||||
|
@ -8215,7 +8301,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/has-flag/3.0.0:
|
||||
resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=}
|
||||
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
/has-flag/4.0.0:
|
||||
|
@ -8705,7 +8791,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/imurmurhash/0.1.4:
|
||||
resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=}
|
||||
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
|
||||
engines: {node: '>=0.8.19'}
|
||||
dev: true
|
||||
|
||||
|
@ -8840,7 +8926,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/is-arrayish/0.2.1:
|
||||
resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
|
||||
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
|
||||
|
||||
/is-arrayish/0.3.2:
|
||||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
||||
|
@ -8933,7 +9019,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/is-extglob/2.1.1:
|
||||
resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
|
||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
|
@ -9175,7 +9261,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/isexe/2.0.0:
|
||||
resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=}
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
dev: true
|
||||
|
||||
/iso8601-duration/1.3.0:
|
||||
|
@ -9582,6 +9668,16 @@ packages:
|
|||
pretty-format: 28.1.3
|
||||
dev: true
|
||||
|
||||
/jest-diff/29.1.2:
|
||||
resolution: {integrity: sha512-4GQts0aUopVvecIT4IwD/7xsBaMhKTYoM4/njE/aVw9wpw+pIUVp8Vab/KnSzSilr84GnLBkaP3JLDnQYCKqVQ==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
diff-sequences: 29.0.0
|
||||
jest-get-type: 29.0.0
|
||||
pretty-format: 29.1.2
|
||||
dev: true
|
||||
|
||||
/jest-docblock/28.1.1:
|
||||
resolution: {integrity: sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
|
@ -9661,6 +9757,11 @@ packages:
|
|||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dev: true
|
||||
|
||||
/jest-get-type/29.0.0:
|
||||
resolution: {integrity: sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dev: true
|
||||
|
||||
/jest-haste-map/28.1.3:
|
||||
resolution: {integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
|
@ -9702,6 +9803,16 @@ packages:
|
|||
pretty-format: 28.1.3
|
||||
dev: true
|
||||
|
||||
/jest-matcher-utils/29.1.2:
|
||||
resolution: {integrity: sha512-MV5XrD3qYSW2zZSHRRceFzqJ39B2z11Qv0KPyZYxnzDHFeYZGJlgGi0SW+IXSJfOewgJp/Km/7lpcFT+cgZypw==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
jest-diff: 29.1.2
|
||||
jest-get-type: 29.0.0
|
||||
pretty-format: 29.1.2
|
||||
dev: true
|
||||
|
||||
/jest-message-util/27.5.1:
|
||||
resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==}
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
|
@ -9732,6 +9843,21 @@ packages:
|
|||
stack-utils: 2.0.5
|
||||
dev: true
|
||||
|
||||
/jest-message-util/29.1.2:
|
||||
resolution: {integrity: sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.16.7
|
||||
'@jest/types': 29.1.2
|
||||
'@types/stack-utils': 2.0.1
|
||||
chalk: 4.1.2
|
||||
graceful-fs: 4.2.9
|
||||
micromatch: 4.0.5
|
||||
pretty-format: 29.1.2
|
||||
slash: 3.0.0
|
||||
stack-utils: 2.0.5
|
||||
dev: true
|
||||
|
||||
/jest-mock/27.5.1:
|
||||
resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==}
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
|
@ -9931,6 +10057,18 @@ packages:
|
|||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/jest-util/29.1.2:
|
||||
resolution: {integrity: sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@jest/types': 29.1.2
|
||||
'@types/node': 17.0.23
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.3.2
|
||||
graceful-fs: 4.2.9
|
||||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/jest-validate/28.1.3:
|
||||
resolution: {integrity: sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
|
@ -11571,7 +11709,7 @@ packages:
|
|||
dev: true
|
||||
|
||||
/multi-fork/0.0.2:
|
||||
resolution: {integrity: sha512-SHWGuze0cZNiH+JGJQFlB1k7kZLGFCvW1Xo5Fcpe86KICkC3aVTJWpjUcmyYcLCB0I6gdzKLCia/bTIw2ggl8A==}
|
||||
resolution: {integrity: sha1-gFiuxGFBJMftqhWBm4juiJ0+tOA=}
|
||||
|
||||
/multimatch/5.0.0:
|
||||
resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==}
|
||||
|
@ -12974,6 +13112,15 @@ packages:
|
|||
react-is: 18.2.0
|
||||
dev: true
|
||||
|
||||
/pretty-format/29.1.2:
|
||||
resolution: {integrity: sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@jest/schemas': 29.0.0
|
||||
ansi-styles: 5.2.0
|
||||
react-is: 18.2.0
|
||||
dev: true
|
||||
|
||||
/pretty-ms/6.0.1:
|
||||
resolution: {integrity: sha512-ke4njoVmlotekHlHyCZ3wI/c5AMT8peuHs8rKJqekj/oR5G8lND2dVpicFlUz5cbZgE290vvkMuDwfj/OcW1kw==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
Loading…
Add table
Reference in a new issue