0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

feat(core): put invitation status

This commit is contained in:
Gao Sun 2024-01-29 19:39:27 +08:00
parent 2e31b976ca
commit 0a20b5a6f8
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
22 changed files with 530 additions and 147 deletions

View file

@ -60,7 +60,7 @@
"@microsoft/applicationinsights-clickanalytics-js": "^3.0.2", "@microsoft/applicationinsights-clickanalytics-js": "^3.0.2",
"@microsoft/applicationinsights-react-js": "^17.0.0", "@microsoft/applicationinsights-react-js": "^17.0.0",
"@microsoft/applicationinsights-web": "^3.0.2", "@microsoft/applicationinsights-web": "^3.0.2",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"applicationinsights": "^2.7.0" "applicationinsights": "^2.7.0"
}, },
"peerDependencies": { "peerDependencies": {

View file

@ -50,7 +50,7 @@
"@logto/phrases-experience": "workspace:^1.5.0", "@logto/phrases-experience": "workspace:^1.5.0",
"@logto/schemas": "workspace:1.12.0", "@logto/schemas": "workspace:1.12.0",
"@logto/shared": "workspace:^3.0.0", "@logto/shared": "workspace:^3.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"chalk": "^5.0.0", "chalk": "^5.0.0",
"decamelize": "^6.0.0", "decamelize": "^6.0.0",
"dotenv": "^16.0.0", "dotenv": "^16.0.0",

View file

@ -23,7 +23,7 @@
"prepublishOnly": "pnpm build" "prepublishOnly": "pnpm build"
}, },
"dependencies": { "dependencies": {
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"got": "^14.0.0", "got": "^14.0.0",
"snakecase-keys": "^5.4.4", "snakecase-keys": "^5.4.4",
"zod": "^3.22.4" "zod": "^3.22.4"

View file

@ -44,7 +44,7 @@
"@parcel/transformer-svg-react": "2.9.3", "@parcel/transformer-svg-react": "2.9.3",
"@silverhand/eslint-config": "5.0.0", "@silverhand/eslint-config": "5.0.0",
"@silverhand/eslint-config-react": "5.0.0", "@silverhand/eslint-config-react": "5.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"@silverhand/ts-config": "5.0.0", "@silverhand/ts-config": "5.0.0",
"@silverhand/ts-config-react": "5.0.0", "@silverhand/ts-config-react": "5.0.0",
"@swc/core": "^1.3.52", "@swc/core": "^1.3.52",

View file

@ -43,7 +43,7 @@
"@logto/phrases-experience": "workspace:^1.5.0", "@logto/phrases-experience": "workspace:^1.5.0",
"@logto/schemas": "workspace:^1.12.0", "@logto/schemas": "workspace:^1.12.0",
"@logto/shared": "workspace:^3.0.0", "@logto/shared": "workspace:^3.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"@simplewebauthn/server": "^8.2.0", "@simplewebauthn/server": "^8.2.0",
"@withtyped/client": "^0.7.22", "@withtyped/client": "^0.7.22",
"camelcase": "^8.0.0", "camelcase": "^8.0.0",

View file

@ -1,18 +1,34 @@
import { ConnectorType, TemplateType } from '@logto/connector-kit'; import { ConnectorType, TemplateType } from '@logto/connector-kit';
import { OrganizationInvitationStatus, type CreateOrganizationInvitation } from '@logto/schemas'; import {
OrganizationInvitationStatus,
type CreateOrganizationInvitation,
type OrganizationInvitationEntity,
} from '@logto/schemas';
import { generateStandardId } from '@logto/shared'; import { generateStandardId } from '@logto/shared';
import { appendPath } from '@silverhand/essentials'; import { appendPath, removeUndefinedKeys } from '@silverhand/essentials';
import { EnvSet } from '#src/env-set/index.js'; import { EnvSet } from '#src/env-set/index.js';
import { getTenantEndpoint } from '#src/env-set/utils.js'; import { getTenantEndpoint } from '#src/env-set/utils.js';
import RequestError from '#src/errors/RequestError/index.js';
import MagicLinkQueries from '#src/queries/magic-link.js'; import MagicLinkQueries from '#src/queries/magic-link.js';
import OrganizationQueries from '#src/queries/organization/index.js'; import OrganizationQueries from '#src/queries/organization/index.js';
import { createUserQueries } from '#src/queries/user.js';
import type Queries from '#src/tenants/Queries.js'; import type Queries from '#src/tenants/Queries.js';
import { type ConnectorLibrary } from './connector.js'; import { type ConnectorLibrary } from './connector.js';
const invitationLinkPath = '/invitation'; const invitationLinkPath = '/invitation';
/**
* The ending statuses of an organization invitation per RFC 0003. It means that the invitation
* status cannot be changed anymore.
*/
const endingStatuses = Object.freeze([
OrganizationInvitationStatus.Accepted,
OrganizationInvitationStatus.Expired,
OrganizationInvitationStatus.Revoked,
]);
/** Class for managing organization invitations. */ /** Class for managing organization invitations. */
export class OrganizationInvitationLibrary { export class OrganizationInvitationLibrary {
constructor( constructor(
@ -77,6 +93,108 @@ export class OrganizationInvitationLibrary {
}); });
} }
/**
* Revokes an organization invitation. The transaction will be rolled back if the status is one
* of the ending statuses.
*
* @param id The ID of the invitation.
* @param status The new status of the invitation.
* @returns A promise that resolves to the updated invitation.
* @see {@link endingStatuses} for the ending statuses.
*/
async updateStatus(
id: string,
status: OrganizationInvitationStatus.Revoked
): Promise<OrganizationInvitationEntity>;
/**
* Updates the status of an organization invitation to `Accepted`, and assigns the user to the
* organization with the provided roles in the invitation.
*
* The transaction will be rolled back if:
* - The status is one of the ending statuses.
* - The `acceptedUserId` is not provided.
* - The `acceptedUserId` is not the same as the invitee.
*
* @param id The ID of the invitation.
* @param status The new status of the invitation (`Accepted`).
* @param acceptedUserId The user ID of the user who accepted the invitation.
* @returns A promise that resolves to the updated invitation.
* @see {@link endingStatuses} for the ending statuses.
*/
async updateStatus(
id: string,
status: OrganizationInvitationStatus.Accepted,
acceptedUserId: string
): Promise<OrganizationInvitationEntity>;
// TODO: Error i18n
async updateStatus(
id: string,
status: OrganizationInvitationStatus,
acceptedUserId?: string
): Promise<OrganizationInvitationEntity> {
const entity = await this.queries.organizations.invitations.findById(id);
if (endingStatuses.includes(entity.status)) {
throw new RequestError({
status: 422,
code: 'request.invalid_input',
details: 'The status of the invitation cannot be changed anymore.',
});
}
return this.queries.pool.transaction(async (connection) => {
const organizationQueries = new OrganizationQueries(connection);
const userQueries = createUserQueries(connection);
switch (status) {
case OrganizationInvitationStatus.Accepted: {
// Normally this shouldn't happen, so we use `TypeError` instead of `RequestError`.
if (!acceptedUserId) {
throw new TypeError('The `acceptedUserId` is required when accepting an invitation.');
}
const user = await userQueries.findUserById(acceptedUserId);
if (user.primaryEmail !== entity.invitee) {
throw new RequestError({
status: 422,
code: 'request.invalid_input',
details: 'The accepted user must have the same email as the invitee.',
});
}
await organizationQueries.relations.users.insert([entity.organizationId, acceptedUserId]);
if (entity.organizationRoles.length > 0) {
await organizationQueries.relations.rolesUsers.insert(
...entity.organizationRoles.map<[string, string, string]>((role) => [
entity.organizationId,
role.id,
acceptedUserId,
])
);
}
break;
}
case OrganizationInvitationStatus.Revoked: {
break;
}
default: {
throw new TypeError(`The status "${status}" is not supported.`);
}
}
const updated = {
status,
acceptedUserId,
updatedAt: Date.now(),
};
await organizationQueries.invitations.updateById(id, updated);
return { ...entity, ...removeUndefinedKeys(updated) };
});
}
protected async sendEmail(to: string, token: string) { protected async sendEmail(to: string, token: string) {
const emailConnector = await this.connector.getMessageConnector(ConnectorType.Email); const emailConnector = await this.connector.getMessageConnector(ConnectorType.Email);
return emailConnector.sendMessage({ return emailConnector.sendMessage({

View file

@ -17,6 +17,7 @@ import {
type OrganizationInvitationEntity, type OrganizationInvitationEntity,
MagicLinks, MagicLinks,
OrganizationInvitationRoleRelations, OrganizationInvitationRoleRelations,
OrganizationInvitationStatus,
} from '@logto/schemas'; } from '@logto/schemas';
import { conditionalSql, convertToIdentifiers } from '@logto/shared'; import { conditionalSql, convertToIdentifiers } from '@logto/shared';
import { sql, type CommonQueryMethods } from 'slonik'; import { sql, type CommonQueryMethods } from 'slonik';
@ -121,7 +122,19 @@ class OrganizationInvitationsQueries extends SchemaQueries<
return sql<OrganizationInvitationEntity>` return sql<OrganizationInvitationEntity>`
select select
${table}.*, ${sql.join(
Object.values(fields).filter((field) => field !== fields.status),
sql`, `
)},
-- Dynamically calculate the status of the invitation, note that the
-- actual status of the invitation is not changed.
case
when
${fields.status} = ${OrganizationInvitationStatus.Pending} and
${fields.expiresAt} < now()
then ${OrganizationInvitationStatus.Expired}
else ${fields.status}
end as "status",
coalesce( coalesce(
json_agg( json_agg(
json_build_object( json_build_object(

View file

@ -72,17 +72,6 @@
"get": { "get": {
"summary": "Get organization invitation", "summary": "Get organization invitation",
"description": "Get an organization invitation by ID.", "description": "Get an organization invitation by ID.",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The organization invitation ID.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": { "responses": {
"200": { "200": {
"description": "The organization invitation, also contains the organization roles to be assigned to the user when they accept the invitation, and the corresponding magic link data." "description": "The organization invitation, also contains the organization roles to be assigned to the user when they accept the invitation, and the corresponding magic link data."
@ -92,23 +81,41 @@
"delete": { "delete": {
"summary": "Delete organization invitation", "summary": "Delete organization invitation",
"description": "Delete an organization invitation by ID.", "description": "Delete an organization invitation by ID.",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The organization invitation ID.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": { "responses": {
"204": { "204": {
"description": "The organization invitation was deleted successfully." "description": "The organization invitation was deleted successfully."
} }
} }
} }
},
"/api/organization-invitations/{id}/status": {
"put": {
"summary": "Update organization invitation status",
"description": "Update the status of an organization invitation by ID.",
"requestBody": {
"description": "The organization invitation status to update.",
"required": true,
"content": {
"application/json": {
"schema": {
"properties": {
"status": {
"description": "The status of the organization invitation."
},
"acceptedUserId": {
"description": "The ID of the user who accepted the organization invitation. Required if the status is \"Accepted\"."
}
}
}
}
}
},
"responses": {
"200": {
"description": "The organization invitation status was updated successfully."
}
}
}
} }
} }
} }

View file

@ -1,4 +1,8 @@
import { OrganizationInvitations, organizationInvitationEntityGuard } from '@logto/schemas'; import {
OrganizationInvitationStatus,
OrganizationInvitations,
organizationInvitationEntityGuard,
} from '@logto/schemas';
import { yes } from '@silverhand/essentials'; import { yes } from '@silverhand/essentials';
import { z } from 'zod'; import { z } from 'zod';
@ -51,7 +55,7 @@ export default function organizationInvitationRoutes<T extends AuthedRouter>(
response: organizationInvitationEntityGuard, response: organizationInvitationEntityGuard,
status: [201], status: [201],
}), }),
async (ctx) => { async (ctx, next) => {
const { query, body } = ctx.guard; const { query, body } = ctx.guard;
assertThat( assertThat(
@ -64,6 +68,50 @@ export default function organizationInvitationRoutes<T extends AuthedRouter>(
ctx.body = await organizationInvitations.insert(body, yes(query.skipEmail)); ctx.body = await organizationInvitations.insert(body, yes(query.skipEmail));
ctx.status = 201; ctx.status = 201;
return next();
}
);
router.put(
'/:id/status',
koaGuard({
params: z.object({
id: z.string(),
}),
body: OrganizationInvitations.updateGuard
.pick({
acceptedUserId: true,
})
.extend({
status: z.enum([
OrganizationInvitationStatus.Accepted,
OrganizationInvitationStatus.Revoked,
]),
}),
response: organizationInvitationEntityGuard,
status: [200],
}),
async (ctx, next) => {
const { id } = ctx.guard.params;
const { status, acceptedUserId } = ctx.guard.body;
if (status !== OrganizationInvitationStatus.Accepted) {
ctx.body = await organizationInvitations.updateStatus(id, status);
return next();
}
// TODO: Error i18n
assertThat(
acceptedUserId,
new RequestError({
status: 422,
code: 'request.invalid_input',
details: 'The `acceptedUserId` is required when accepting an invitation.',
})
);
ctx.body = await organizationInvitations.updateStatus(id, status, acceptedUserId);
return next();
} }
); );

View file

@ -37,7 +37,7 @@
"@react-spring/web": "^9.6.1", "@react-spring/web": "^9.6.1",
"@silverhand/eslint-config": "5.0.0", "@silverhand/eslint-config": "5.0.0",
"@silverhand/eslint-config-react": "5.0.0", "@silverhand/eslint-config-react": "5.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"@silverhand/ts-config": "5.0.0", "@silverhand/ts-config": "5.0.0",
"@silverhand/ts-config-react": "5.0.0", "@silverhand/ts-config-react": "5.0.0",
"@simplewebauthn/browser": "^8.3.1", "@simplewebauthn/browser": "^8.3.1",

View file

@ -31,7 +31,7 @@
"@logto/schemas": "workspace:^1.12.0", "@logto/schemas": "workspace:^1.12.0",
"@logto/shared": "workspace:^3.0.0", "@logto/shared": "workspace:^3.0.0",
"@silverhand/eslint-config": "5.0.0", "@silverhand/eslint-config": "5.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"@silverhand/ts-config": "5.0.0", "@silverhand/ts-config": "5.0.0",
"@types/jest": "^29.4.0", "@types/jest": "^29.4.0",
"@types/node": "^20.9.5", "@types/node": "^20.9.5",

View file

@ -1,4 +1,7 @@
import { type OrganizationInvitationEntity } from '@logto/schemas'; import {
type OrganizationInvitationStatus,
type OrganizationInvitationEntity,
} from '@logto/schemas';
import { authedAdminApi } from './api.js'; import { authedAdminApi } from './api.js';
import { ApiFactory } from './factory.js'; import { ApiFactory } from './factory.js';
@ -29,4 +32,15 @@ export class OrganizationInvitationApi extends ApiFactory<
}) })
.json<OrganizationInvitationEntity>(); .json<OrganizationInvitationEntity>();
} }
async updateStatus(id: string, status: OrganizationInvitationStatus, acceptedUserId?: string) {
return authedAdminApi
.put(`${this.path}/${id}/status`, {
json: {
status,
acceptedUserId,
},
})
.json<OrganizationInvitationEntity>();
}
} }

View file

@ -15,7 +15,7 @@ const expectErrorResponse = (error: unknown, status: number, code: string) => {
expect(body).toMatchObject({ code }); expect(body).toMatchObject({ code });
}; };
describe('organization invitations', () => { describe('organization invitation creation', () => {
const invitationApi = new OrganizationInvitationApiTest(); const invitationApi = new OrganizationInvitationApiTest();
const organizationApi = new OrganizationApiTest(); const organizationApi = new OrganizationApiTest();

View file

@ -0,0 +1,187 @@
import assert from 'node:assert';
import { OrganizationInvitationStatus } from '@logto/schemas';
import { generateStandardId } from '@logto/shared';
import { HTTPError } from 'got';
import { OrganizationApiTest, OrganizationInvitationApiTest } from '#src/helpers/organization.js';
import { UserApiTest } from '#src/helpers/user.js';
const randomId = () => generateStandardId(4);
const expectErrorResponse = (error: unknown, status: number, code: string) => {
assert(error instanceof HTTPError);
const { statusCode, body: raw } = error.response;
const body: unknown = JSON.parse(String(raw));
expect(statusCode).toBe(status);
expect(body).toMatchObject({ code });
};
describe('organization invitation status update', () => {
const invitationApi = new OrganizationInvitationApiTest();
const organizationApi = new OrganizationApiTest();
const userApi = new UserApiTest();
afterEach(async () => {
await Promise.all([
organizationApi.cleanUp(),
organizationApi.roleApi.cleanUp(),
invitationApi.cleanUp(),
userApi.cleanUp(),
]);
});
it('should expire invitations and disable update after the expiration date', async () => {
const organization = await organizationApi.create({ name: 'test' });
const invitation = await invitationApi.create(
{
organizationId: organization.id,
invitee: `${randomId()}@example.com`,
expiresAt: Date.now() + 100,
},
true
);
expect(invitation.status).toBe('Pending');
await new Promise((resolve) => {
setTimeout(resolve, 200);
});
const invitationById = await invitationApi.get(invitation.id);
expect(invitationById.status).toBe('Expired');
const error = await invitationApi
.updateStatus(invitation.id, OrganizationInvitationStatus.Accepted)
.catch((error: unknown) => error);
expectErrorResponse(error, 422, 'request.invalid_input');
});
it('should be able to accept an invitation', async () => {
const organization = await organizationApi.create({ name: 'test' });
const invitation = await invitationApi.create(
{
organizationId: organization.id,
invitee: `${randomId()}@example.com`,
expiresAt: Date.now() + 1_000_000,
},
true
);
expect(invitation.status).toBe('Pending');
const user = await userApi.create({
primaryEmail: invitation.invitee,
});
const updated = await invitationApi.updateStatus(
invitation.id,
OrganizationInvitationStatus.Accepted,
user.id
);
expect(updated.status).toBe('Accepted');
const userOrganizations = await organizationApi.getUserOrganizations(user.id);
expect(userOrganizations).toContainEqual(
expect.objectContaining({
id: organization.id,
name: organization.name,
})
);
});
it('should be able to accept an invitation with roles', async () => {
const organization = await organizationApi.create({ name: 'test' });
const role = await organizationApi.roleApi.create({ name: 'test' });
const invitation = await invitationApi.create(
{
organizationId: organization.id,
invitee: `${randomId()}@example.com`,
expiresAt: Date.now() + 1_000_000,
organizationRoleIds: [role.id],
},
true
);
expect(invitation.status).toBe('Pending');
const user = await userApi.create({
primaryEmail: invitation.invitee,
});
const updated = await invitationApi.updateStatus(
invitation.id,
OrganizationInvitationStatus.Accepted,
user.id
);
expect(updated.status).toBe('Accepted');
const userOrganizations = await organizationApi.getUserOrganizations(user.id);
expect(userOrganizations).toContainEqual(
expect.objectContaining({
id: organization.id,
name: organization.name,
organizationRoles: [expect.objectContaining({ id: role.id, name: role.name })],
})
);
});
it('should not be able to accept an invitation with a different email', async () => {
const organization = await organizationApi.create({ name: 'test' });
const invitation = await invitationApi.create(
{
organizationId: organization.id,
invitee: `${randomId()}@example.com`,
expiresAt: Date.now() + 1_000_000,
},
true
);
expect(invitation.status).toBe('Pending');
const user = await userApi.create({
primaryEmail: `${randomId()}@example.com`,
});
const error = await invitationApi
.updateStatus(invitation.id, OrganizationInvitationStatus.Accepted, user.id)
.catch((error: unknown) => error);
expectErrorResponse(error, 422, 'request.invalid_input');
});
it('should not be able to accept an invitation with an invalid user id', async () => {
const organization = await organizationApi.create({ name: 'test' });
const invitation = await invitationApi.create(
{
organizationId: organization.id,
invitee: `${randomId()}@example.com`,
expiresAt: Date.now() + 1_000_000,
},
true
);
expect(invitation.status).toBe('Pending');
const error = await invitationApi
.updateStatus(invitation.id, OrganizationInvitationStatus.Accepted, 'invalid')
.catch((error: unknown) => error);
expectErrorResponse(error, 404, 'entity.not_found');
});
it('should not be able to update the status of an ended invitation', async () => {
const organization = await organizationApi.create({ name: 'test' });
const invitation = await invitationApi.create(
{
organizationId: organization.id,
invitee: `${randomId()}@example.com`,
expiresAt: Date.now() + 1_000_000,
},
true
);
expect(invitation.status).toBe('Pending');
await invitationApi.updateStatus(invitation.id, OrganizationInvitationStatus.Revoked);
const error = await invitationApi
.updateStatus(invitation.id, OrganizationInvitationStatus.Accepted)
.catch((error: unknown) => error);
expectErrorResponse(error, 422, 'request.invalid_input');
});
});

View file

@ -35,7 +35,7 @@
"dependencies": { "dependencies": {
"@logto/core-kit": "workspace:^2.2.1", "@logto/core-kit": "workspace:^2.2.1",
"@logto/language-kit": "workspace:^1.0.0", "@logto/language-kit": "workspace:^1.0.0",
"@silverhand/essentials": "^2.8.4" "@silverhand/essentials": "^2.8.8"
}, },
"peerDependencies": { "peerDependencies": {
"zod": "^3.22.4" "zod": "^3.22.4"

View file

@ -34,7 +34,7 @@
}, },
"dependencies": { "dependencies": {
"@logto/language-kit": "workspace:^1.0.0", "@logto/language-kit": "workspace:^1.0.0",
"@silverhand/essentials": "^2.8.4" "@silverhand/essentials": "^2.8.8"
}, },
"peerDependencies": { "peerDependencies": {
"zod": "^3.22.4" "zod": "^3.22.4"

View file

@ -41,7 +41,7 @@
}, },
"devDependencies": { "devDependencies": {
"@silverhand/eslint-config": "5.0.0", "@silverhand/eslint-config": "5.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"@silverhand/ts-config": "5.0.0", "@silverhand/ts-config": "5.0.0",
"@types/inquirer": "^9.0.0", "@types/inquirer": "^9.0.0",
"@types/jest": "^29.4.0", "@types/jest": "^29.4.0",

View file

@ -93,12 +93,12 @@ export type OrganizationWithFeatured = Organization & {
* - `organizationRoles`: The roles to be assigned to the user when accepting the invitation. * - `organizationRoles`: The roles to be assigned to the user when accepting the invitation.
*/ */
export type OrganizationInvitationEntity = OrganizationInvitation & { export type OrganizationInvitationEntity = OrganizationInvitation & {
magicLink: MagicLink; magicLink?: MagicLink;
organizationRoles: OrganizationRoleEntity[]; organizationRoles: OrganizationRoleEntity[];
}; };
export const organizationInvitationEntityGuard: z.ZodType<OrganizationInvitationEntity> = export const organizationInvitationEntityGuard: z.ZodType<OrganizationInvitationEntity> =
OrganizationInvitations.guard.extend({ OrganizationInvitations.guard.extend({
magicLink: MagicLinks.guard, magicLink: MagicLinks.guard.optional(),
organizationRoles: organizationRoleEntityGuard.array(), organizationRoles: organizationRoleEntityGuard.array(),
}); });

View file

@ -60,7 +60,7 @@
}, },
"prettier": "@silverhand/eslint-config/.prettierrc", "prettier": "@silverhand/eslint-config/.prettierrc",
"dependencies": { "dependencies": {
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"chalk": "^5.0.0", "chalk": "^5.0.0",
"find-up": "^7.0.0", "find-up": "^7.0.0",
"libphonenumber-js": "^1.9.49", "libphonenumber-js": "^1.9.49",

View file

@ -37,7 +37,7 @@
}, },
"dependencies": { "dependencies": {
"@logto/language-kit": "workspace:^1.0.0", "@logto/language-kit": "workspace:^1.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"@withtyped/client": "^0.7.22", "@withtyped/client": "^0.7.22",
"@withtyped/server": "^0.12.9" "@withtyped/server": "^0.12.9"
}, },

View file

@ -53,7 +53,7 @@
"devDependencies": { "devDependencies": {
"@jest/types": "^29.0.3", "@jest/types": "^29.0.3",
"@silverhand/eslint-config": "5.0.0", "@silverhand/eslint-config": "5.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.8",
"@silverhand/ts-config": "5.0.0", "@silverhand/ts-config": "5.0.0",
"@silverhand/ts-config-react": "5.0.0", "@silverhand/ts-config-react": "5.0.0",
"@types/color": "^3.0.3", "@types/color": "^3.0.3",

View file

@ -49,8 +49,8 @@ importers:
specifier: ^3.0.2 specifier: ^3.0.2
version: 3.0.2(tslib@2.4.1)(typescript@5.3.3) version: 3.0.2(tslib@2.4.1)(typescript@5.3.3)
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
applicationinsights: applicationinsights:
specifier: ^2.7.0 specifier: ^2.7.0
version: 2.7.0 version: 2.7.0
@ -125,8 +125,8 @@ importers:
specifier: workspace:^3.0.0 specifier: workspace:^3.0.0
version: link:../shared version: link:../shared
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
chalk: chalk:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.1.2 version: 5.1.2
@ -243,8 +243,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
dayjs: dayjs:
specifier: ^1.10.5 specifier: ^1.10.5
version: 1.11.6 version: 1.11.6
@ -331,8 +331,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
dayjs: dayjs:
specifier: ^1.10.5 specifier: ^1.10.5
version: 1.11.6 version: 1.11.6
@ -419,8 +419,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -498,8 +498,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -580,8 +580,8 @@ importers:
specifier: workspace:^3.0.0 specifier: workspace:^3.0.0
version: link:../../shared version: link:../../shared
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -668,8 +668,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -750,8 +750,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -829,8 +829,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -908,8 +908,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -987,8 +987,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1066,8 +1066,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1148,8 +1148,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1227,8 +1227,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1306,8 +1306,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1388,8 +1388,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1467,8 +1467,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1546,8 +1546,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1625,8 +1625,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1704,8 +1704,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1783,8 +1783,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1862,8 +1862,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -1941,8 +1941,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2020,8 +2020,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2105,8 +2105,8 @@ importers:
specifier: workspace:^3.0.0 specifier: workspace:^3.0.0
version: link:../../shared version: link:../../shared
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2190,8 +2190,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
fast-xml-parser: fast-xml-parser:
specifier: ^4.2.5 specifier: ^4.2.5
version: 4.2.5 version: 4.2.5
@ -2275,8 +2275,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2354,8 +2354,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2433,8 +2433,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2518,8 +2518,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2597,8 +2597,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2676,8 +2676,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2755,8 +2755,8 @@ importers:
specifier: workspace:^2.0.0 specifier: workspace:^2.0.0
version: link:../../toolkit/connector-kit version: link:../../toolkit/connector-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.6 version: 2.8.8
got: got:
specifier: ^14.0.0 specifier: ^14.0.0
version: 14.0.0 version: 14.0.0
@ -2894,8 +2894,8 @@ importers:
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(eslint@8.44.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.0.0)(typescript@5.3.3) version: 5.0.0(eslint@8.44.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.0.0)(typescript@5.3.3)
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
'@silverhand/ts-config': '@silverhand/ts-config':
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(typescript@5.3.3) version: 5.0.0(typescript@5.3.3)
@ -3182,8 +3182,8 @@ importers:
specifier: workspace:^3.0.0 specifier: workspace:^3.0.0
version: link:../shared version: link:../shared
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
'@simplewebauthn/server': '@simplewebauthn/server':
specifier: ^8.2.0 specifier: ^8.2.0
version: 8.2.0 version: 8.2.0
@ -3570,8 +3570,8 @@ importers:
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(eslint@8.44.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.0.0)(typescript@5.3.3) version: 5.0.0(eslint@8.44.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.0.0)(typescript@5.3.3)
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
'@silverhand/ts-config': '@silverhand/ts-config':
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(typescript@5.3.3) version: 5.0.0(typescript@5.3.3)
@ -3772,8 +3772,8 @@ importers:
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3) version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3)
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
'@silverhand/ts-config': '@silverhand/ts-config':
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(typescript@5.3.3) version: 5.0.0(typescript@5.3.3)
@ -3835,8 +3835,8 @@ importers:
specifier: workspace:^1.0.0 specifier: workspace:^1.0.0
version: link:../toolkit/language-kit version: link:../toolkit/language-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
zod: zod:
specifier: ^3.22.4 specifier: ^3.22.4
version: 3.22.4 version: 3.22.4
@ -3869,8 +3869,8 @@ importers:
specifier: workspace:^1.0.0 specifier: workspace:^1.0.0
version: link:../toolkit/language-kit version: link:../toolkit/language-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
zod: zod:
specifier: ^3.22.4 specifier: ^3.22.4
version: 3.22.4 version: 3.22.4
@ -3928,8 +3928,8 @@ importers:
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3) version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3)
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
'@silverhand/ts-config': '@silverhand/ts-config':
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(typescript@5.3.3) version: 5.0.0(typescript@5.3.3)
@ -3982,8 +3982,8 @@ importers:
packages/shared: packages/shared:
dependencies: dependencies:
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
chalk: chalk:
specifier: ^5.0.0 specifier: ^5.0.0
version: 5.1.2 version: 5.1.2
@ -4037,8 +4037,8 @@ importers:
specifier: workspace:^1.0.0 specifier: workspace:^1.0.0
version: link:../language-kit version: link:../language-kit
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
'@withtyped/client': '@withtyped/client':
specifier: ^0.7.22 specifier: ^0.7.22
version: 0.7.22(zod@3.22.4) version: 0.7.22(zod@3.22.4)
@ -4107,8 +4107,8 @@ importers:
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3) version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3)
'@silverhand/essentials': '@silverhand/essentials':
specifier: ^2.8.4 specifier: ^2.8.8
version: 2.8.4 version: 2.8.8
'@silverhand/ts-config': '@silverhand/ts-config':
specifier: 5.0.0 specifier: 5.0.0
version: 5.0.0(typescript@5.3.3) version: 5.0.0(typescript@5.3.3)
@ -7569,7 +7569,7 @@ packages:
resolution: {integrity: sha512-yDWSZMI2Qo/xoYU92tnwSP/gnSvq8+CLK5DqD/4brO42QJa7xjt7eA+HSyuMmSUrKffY2nP3riU81gs+nR8DkA==} resolution: {integrity: sha512-yDWSZMI2Qo/xoYU92tnwSP/gnSvq8+CLK5DqD/4brO42QJa7xjt7eA+HSyuMmSUrKffY2nP3riU81gs+nR8DkA==}
engines: {node: ^18.12.0} engines: {node: ^18.12.0}
dependencies: dependencies:
'@silverhand/essentials': 2.8.6 '@silverhand/essentials': 2.8.8
tiny-cookie: 2.4.1 tiny-cookie: 2.4.1
dev: false dev: false
@ -7577,7 +7577,7 @@ packages:
resolution: {integrity: sha512-8kKh1EcAm19smnEMvw0M51d2EQXEEH77G1JEKh1iLifUScmxD+c7HcN/5mLekaBz36MUVNiA2gE7s9L2GOpWrg==} resolution: {integrity: sha512-8kKh1EcAm19smnEMvw0M51d2EQXEEH77G1JEKh1iLifUScmxD+c7HcN/5mLekaBz36MUVNiA2gE7s9L2GOpWrg==}
dependencies: dependencies:
'@logto/client': 2.3.0 '@logto/client': 2.3.0
'@silverhand/essentials': 2.8.6 '@silverhand/essentials': 2.8.8
js-base64: 3.7.5 js-base64: 3.7.5
dev: true dev: true
@ -7585,7 +7585,7 @@ packages:
resolution: {integrity: sha512-VrzsF+QtnrVXnDFbsdYTeGatjThlTFwtjTT/jJMaFdyRg0lno8vHxsjuyG8ba4wVSu22tSmJAr7okpAwRyhtcg==} resolution: {integrity: sha512-VrzsF+QtnrVXnDFbsdYTeGatjThlTFwtjTT/jJMaFdyRg0lno8vHxsjuyG8ba4wVSu22tSmJAr7okpAwRyhtcg==}
dependencies: dependencies:
'@logto/js': 3.0.1 '@logto/js': 3.0.1
'@silverhand/essentials': 2.8.6 '@silverhand/essentials': 2.8.8
camelcase-keys: 7.0.2 camelcase-keys: 7.0.2
jose: 5.0.1 jose: 5.0.1
dev: true dev: true
@ -7594,7 +7594,7 @@ packages:
resolution: {integrity: sha512-cDKxCBFeZcG0CiGIa6mBY1Zgu3+tuvhYxs/qN0nQcj7MLSQ0AXHK9m1GeSJQH+Nu/jspggLmg27Ks8gdCHQUcg==} resolution: {integrity: sha512-cDKxCBFeZcG0CiGIa6mBY1Zgu3+tuvhYxs/qN0nQcj7MLSQ0AXHK9m1GeSJQH+Nu/jspggLmg27Ks8gdCHQUcg==}
engines: {node: ^20.9.0} engines: {node: ^20.9.0}
dependencies: dependencies:
'@silverhand/essentials': 2.8.6 '@silverhand/essentials': 2.8.8
'@withtyped/server': 0.12.9(zod@3.22.4) '@withtyped/server': 0.12.9(zod@3.22.4)
transitivePeerDependencies: transitivePeerDependencies:
- zod - zod
@ -7603,7 +7603,7 @@ packages:
/@logto/js@3.0.1: /@logto/js@3.0.1:
resolution: {integrity: sha512-vsU6mH5oiiW3k00pMyVA4V31K2Bd0rOT9qWch2l5e5o1yCQLJ3zUIOjGjChu3m2TRu1d920iiUpZU3Lzf6Pwdw==} resolution: {integrity: sha512-vsU6mH5oiiW3k00pMyVA4V31K2Bd0rOT9qWch2l5e5o1yCQLJ3zUIOjGjChu3m2TRu1d920iiUpZU3Lzf6Pwdw==}
dependencies: dependencies:
'@silverhand/essentials': 2.8.6 '@silverhand/essentials': 2.8.8
camelcase-keys: 7.0.2 camelcase-keys: 7.0.2
jose: 5.0.1 jose: 5.0.1
dev: true dev: true
@ -7612,7 +7612,7 @@ packages:
resolution: {integrity: sha512-xzVCnlrev/bqLtXOAw9I35h7njU1bed1jt6fL/VZfY4RUUJVZ36LG7fq2b7GsGg5xGRLchJ//+/VP1ac3+27YA==} resolution: {integrity: sha512-xzVCnlrev/bqLtXOAw9I35h7njU1bed1jt6fL/VZfY4RUUJVZ36LG7fq2b7GsGg5xGRLchJ//+/VP1ac3+27YA==}
dependencies: dependencies:
'@logto/client': 2.3.0 '@logto/client': 2.3.0
'@silverhand/essentials': 2.8.6 '@silverhand/essentials': 2.8.8
js-base64: 3.7.5 js-base64: 3.7.5
node-fetch: 2.7.0 node-fetch: 2.7.0
transitivePeerDependencies: transitivePeerDependencies:
@ -7625,7 +7625,7 @@ packages:
react: '>=16.8.0 || ^18.0.0' react: '>=16.8.0 || ^18.0.0'
dependencies: dependencies:
'@logto/browser': 2.2.0 '@logto/browser': 2.2.0
'@silverhand/essentials': 2.8.6 '@silverhand/essentials': 2.8.8
react: 18.2.0 react: 18.2.0
dev: true dev: true
@ -9298,13 +9298,9 @@ packages:
lodash: 4.17.21 lodash: 4.17.21
dev: true dev: true
/@silverhand/essentials@2.8.4: /@silverhand/essentials@2.8.8:
resolution: {integrity: sha512-VaI00QyD2trA7n7/wHNcGNGRXoSr8dUGs/hQCu4Rju4Edl3vso7CeCXdfGU2aNDuT2uMs75of6Ph8gqVJhWlYQ==} resolution: {integrity: sha512-JCiNjdF9IcsF/7Gd4ZMAL3ykdujKrIvEpKa2Iz6YqUaoCSJEeyLwspE5xAHo38a0oT55Qa2pC+wLjEEgWAD8zA==}
engines: {node: ^16.13.0 || ^18.12.0 || ^19.2.0, pnpm: ^8.0.0} engines: {node: ^18.12.0 || ^20.9.0, pnpm: ^8.0.0}
/@silverhand/essentials@2.8.6:
resolution: {integrity: sha512-qNyc6CvZRngP66hTA8sbpXGsiu9j6Hu62jCy7LV3tJiytg/hmxJB5oM9k5tpaUa9kHwYJ2X9CManX7SYYNrzHg==}
engines: {node: ^16.13.0 || ^18.12.0 || ^19.2.0, pnpm: ^8.0.0}
/@silverhand/ts-config-react@5.0.0(typescript@5.3.3): /@silverhand/ts-config-react@5.0.0(typescript@5.3.3):
resolution: {integrity: sha512-DQpaG49sY36FhpyFIRAmTA5bG9ASFUVXu+yi29bMdLls51r9nEoBuWxWv2Sh3GnSGxKLq4gmFf+U8Zy/qcnX1w==} resolution: {integrity: sha512-DQpaG49sY36FhpyFIRAmTA5bG9ASFUVXu+yi29bMdLls51r9nEoBuWxWv2Sh3GnSGxKLq4gmFf+U8Zy/qcnX1w==}
@ -10466,7 +10462,7 @@ packages:
peerDependencies: peerDependencies:
zod: ^3.19.1 zod: ^3.19.1
dependencies: dependencies:
'@silverhand/essentials': 2.8.4 '@silverhand/essentials': 2.8.8
'@withtyped/shared': 0.2.2 '@withtyped/shared': 0.2.2
zod: 3.22.4 zod: 3.22.4