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:
parent
2e31b976ca
commit
0a20b5a6f8
22 changed files with 530 additions and 147 deletions
|
@ -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": {
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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');
|
||||||
|
});
|
||||||
|
});
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
|
@ -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",
|
||||||
|
|
202
pnpm-lock.yaml
202
pnpm-lock.yaml
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue