mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat: return and store connector raw data
This commit is contained in:
parent
d3d0f5133b
commit
57d97a4df8
47 changed files with 1070 additions and 154 deletions
8
.changeset/gentle-shoes-push.md
Normal file
8
.changeset/gentle-shoes-push.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
"@logto/connector-kit": major
|
||||||
|
---
|
||||||
|
|
||||||
|
update `SocialUserInfo` and `GetUserInfo` types
|
||||||
|
|
||||||
|
- Added `rawData?: Json` to `SocialUserInfo`
|
||||||
|
- `GetUserInfo` now does not accept unknown keys in the return object, since the raw data is now stored in `SocialUserInfo`
|
7
.changeset/new-tables-breathe.md
Normal file
7
.changeset/new-tables-breathe.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
"@logto/connector-kit": major
|
||||||
|
---
|
||||||
|
|
||||||
|
guard results of `parseJson` and `parseJsonObject`
|
||||||
|
|
||||||
|
Now `parseJson` and `parseJsonObject` are type safe.
|
21
.changeset/olive-cycles-sip.md
Normal file
21
.changeset/olive-cycles-sip.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
"@logto/connector-alipay-native": minor
|
||||||
|
"@logto/connector-wechat-native": minor
|
||||||
|
"@logto/connector-mock-social": minor
|
||||||
|
"@logto/connector-alipay-web": minor
|
||||||
|
"@logto/connector-feishu-web": minor
|
||||||
|
"@logto/connector-wechat-web": minor
|
||||||
|
"@logto/connector-facebook": minor
|
||||||
|
"@logto/connector-azuread": minor
|
||||||
|
"@logto/connector-discord": minor
|
||||||
|
"@logto/connector-github": minor
|
||||||
|
"@logto/connector-google": minor
|
||||||
|
"@logto/connector-oauth": minor
|
||||||
|
"@logto/connector-apple": minor
|
||||||
|
"@logto/connector-kakao": minor
|
||||||
|
"@logto/connector-naver": minor
|
||||||
|
"@logto/connector-wecom": minor
|
||||||
|
"@logto/connector-oidc": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
return and store social connector raw data
|
5
.changeset/wild-hotels-drop.md
Normal file
5
.changeset/wild-hotels-drop.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"@logto/connector-kit": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
add `jsonGuard()` and `jsonObjectGuard()`
|
|
@ -12,7 +12,7 @@ tasks:
|
||||||
cd packages/core
|
cd packages/core
|
||||||
pnpm build
|
pnpm build
|
||||||
cd -
|
cd -
|
||||||
pnpm connectors:build
|
pnpm connectors build
|
||||||
pnpm cli connector link
|
pnpm cli connector link
|
||||||
command: |
|
command: |
|
||||||
gp ports await 5432
|
gp ports await 5432
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"cli": "logto",
|
"cli": "logto",
|
||||||
"changeset": "changeset",
|
"changeset": "changeset",
|
||||||
"alteration": "logto db alt",
|
"alteration": "logto db alt",
|
||||||
"connectors:build": "pnpm -r --filter \"./packages/connectors/connector-*\" build",
|
"connectors": "pnpm -r --filter \"./packages/connectors/connector-*\"",
|
||||||
"//": "# `changeset version` won't run version lifecycle scripts, see https://github.com/changesets/changesets/issues/860",
|
"//": "# `changeset version` won't run version lifecycle scripts, see https://github.com/changesets/changesets/issues/860",
|
||||||
"ci:version": "changeset version && pnpm -r version",
|
"ci:version": "changeset version && pnpm -r version",
|
||||||
"ci:build": "pnpm -r build",
|
"ci:build": "pnpm -r build",
|
||||||
|
|
|
@ -156,10 +156,23 @@ describe('getUserInfo', () => {
|
||||||
sign: '<signature>',
|
sign: '<signature>',
|
||||||
});
|
});
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const { id, name, avatar } = await connector.getUserInfo({ auth_code: 'code' }, jest.fn());
|
const { id, name, avatar, rawData } = await connector.getUserInfo(
|
||||||
|
{ auth_code: 'code' },
|
||||||
|
jest.fn()
|
||||||
|
);
|
||||||
expect(id).toEqual('2088000000000000');
|
expect(id).toEqual('2088000000000000');
|
||||||
expect(name).toEqual('PlayboyEric');
|
expect(name).toEqual('PlayboyEric');
|
||||||
expect(avatar).toEqual('https://www.alipay.com/xxx.jpg');
|
expect(avatar).toEqual('https://www.alipay.com/xxx.jpg');
|
||||||
|
expect(rawData).toEqual({
|
||||||
|
alipay_user_info_share_response: {
|
||||||
|
code: '10000',
|
||||||
|
msg: 'Success',
|
||||||
|
user_id: '2088000000000000',
|
||||||
|
nick_name: 'PlayboyEric',
|
||||||
|
avatar: 'https://www.alipay.com/xxx.jpg',
|
||||||
|
},
|
||||||
|
sign: '<signature>',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw SocialAccessTokenInvalid with code 20001', async () => {
|
it('should throw SocialAccessTokenInvalid with code 20001', async () => {
|
||||||
|
|
|
@ -131,8 +131,8 @@ const getUserInfo =
|
||||||
searchParams: signedSearchParameters,
|
searchParams: signedSearchParameters,
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -148,7 +148,7 @@ const getUserInfo =
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { id, avatar, name };
|
return { id, avatar, name, rawData };
|
||||||
};
|
};
|
||||||
|
|
||||||
const errorHandler: ErrorHandler = ({ code, msg, sub_code, sub_msg }) => {
|
const errorHandler: ErrorHandler = ({ code, msg, sub_code, sub_msg }) => {
|
||||||
|
|
|
@ -142,10 +142,23 @@ describe('getUserInfo', () => {
|
||||||
sign: '<signature>',
|
sign: '<signature>',
|
||||||
});
|
});
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const { id, name, avatar } = await connector.getUserInfo({ auth_code: 'code' }, jest.fn());
|
const { id, name, avatar, rawData } = await connector.getUserInfo(
|
||||||
|
{ auth_code: 'code' },
|
||||||
|
jest.fn()
|
||||||
|
);
|
||||||
expect(id).toEqual('2088000000000000');
|
expect(id).toEqual('2088000000000000');
|
||||||
expect(name).toEqual('PlayboyEric');
|
expect(name).toEqual('PlayboyEric');
|
||||||
expect(avatar).toEqual('https://www.alipay.com/xxx.jpg');
|
expect(avatar).toEqual('https://www.alipay.com/xxx.jpg');
|
||||||
|
expect(rawData).toEqual({
|
||||||
|
alipay_user_info_share_response: {
|
||||||
|
code: '10000',
|
||||||
|
msg: 'Success',
|
||||||
|
user_id: '2088000000000000',
|
||||||
|
nick_name: 'PlayboyEric',
|
||||||
|
avatar: 'https://www.alipay.com/xxx.jpg',
|
||||||
|
},
|
||||||
|
sign: '<signature>',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw General error if auth_code not provided in input', async () => {
|
it('throw General error if auth_code not provided in input', async () => {
|
||||||
|
|
|
@ -130,10 +130,8 @@ const getUserInfo =
|
||||||
searchParams: signedSearchParameters,
|
searchParams: signedSearchParameters,
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const { body: rawBody } = httpResponse;
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(rawBody));
|
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -149,7 +147,7 @@ const getUserInfo =
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { id, avatar, name };
|
return { id, avatar, name, rawData };
|
||||||
};
|
};
|
||||||
|
|
||||||
const errorHandler: ErrorHandler = ({ code, msg, sub_code, sub_msg }) => {
|
const errorHandler: ErrorHandler = ({ code, msg, sub_code, sub_msg }) => {
|
||||||
|
|
|
@ -60,7 +60,11 @@ describe('getUserInfo', () => {
|
||||||
}));
|
}));
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const userInfo = await connector.getUserInfo({ id_token: 'idToken' }, jest.fn());
|
const userInfo = await connector.getUserInfo({ id_token: 'idToken' }, jest.fn());
|
||||||
expect(userInfo).toEqual({ id: userId, email: 'foo@bar.com' });
|
expect(userInfo).toEqual({
|
||||||
|
id: userId,
|
||||||
|
email: 'foo@bar.com',
|
||||||
|
rawData: { id_token: 'idToken' },
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should ignore unverified email', async () => {
|
it('should ignore unverified email', async () => {
|
||||||
|
@ -69,7 +73,7 @@ describe('getUserInfo', () => {
|
||||||
}));
|
}));
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const userInfo = await connector.getUserInfo({ id_token: 'idToken' }, jest.fn());
|
const userInfo = await connector.getUserInfo({ id_token: 'idToken' }, jest.fn());
|
||||||
expect(userInfo).toEqual({ id: 'userId' });
|
expect(userInfo).toEqual({ id: 'userId', rawData: { id_token: 'idToken' } });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get user info from the `user` field', async () => {
|
it('should get user info from the `user` field', async () => {
|
||||||
|
@ -89,7 +93,18 @@ describe('getUserInfo', () => {
|
||||||
jest.fn()
|
jest.fn()
|
||||||
);
|
);
|
||||||
// Should use info from `user` field first
|
// Should use info from `user` field first
|
||||||
expect(userInfo).toEqual({ id: userId, email: 'foo2@bar.com', name: 'foo bar' });
|
expect(userInfo).toEqual({
|
||||||
|
id: userId,
|
||||||
|
email: 'foo2@bar.com',
|
||||||
|
name: 'foo bar',
|
||||||
|
rawData: {
|
||||||
|
id_token: 'idToken',
|
||||||
|
user: JSON.stringify({
|
||||||
|
email: 'foo2@bar.com',
|
||||||
|
name: { firstName: 'foo', lastName: 'bar' },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if id token is missing', async () => {
|
it('should throw if id token is missing', async () => {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
ConnectorErrorCodes,
|
ConnectorErrorCodes,
|
||||||
validateConfig,
|
validateConfig,
|
||||||
ConnectorType,
|
ConnectorType,
|
||||||
|
jsonGuard,
|
||||||
} from '@logto/connector-kit';
|
} from '@logto/connector-kit';
|
||||||
import { generateStandardId } from '@logto/shared/universal';
|
import { generateStandardId } from '@logto/shared/universal';
|
||||||
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
||||||
|
@ -112,6 +113,7 @@ const getUserInfo =
|
||||||
user?.email ??
|
user?.email ??
|
||||||
(payload.email && payload.email_verified === true ? String(payload.email) : undefined),
|
(payload.email && payload.email_verified === true ? String(payload.email) : undefined),
|
||||||
name: [user?.name?.firstName, user?.name?.lastName].filter(Boolean).join(' ') || undefined,
|
name: [user?.name?.firstName, user?.name?.lastName].filter(Boolean).join(' ') || undefined,
|
||||||
|
rawData: jsonGuard.parse(data),
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.SocialIdTokenInvalid);
|
throw new ConnectorError(ConnectorErrorCodes.SocialIdTokenInvalid);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
"description": "Microsoft Azure AD connector implementation.",
|
"description": "Microsoft Azure AD connector implementation.",
|
||||||
"author": "Mobilist Inc. <info@mobilist.com.tr>",
|
"author": "Mobilist Inc. <info@mobilist.com.tr>",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@logto/connector-kit": "workspace:^2.1.0",
|
"@azure/msal-node": "^2.0.0",
|
||||||
"@azure/msal-node": "^2.0.0"
|
"@logto/connector-kit": "workspace:^2.1.0"
|
||||||
},
|
},
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"module": "./lib/index.js",
|
"module": "./lib/index.js",
|
||||||
|
@ -25,9 +25,8 @@
|
||||||
"dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental",
|
"dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental",
|
||||||
"lint": "eslint --ext .ts src",
|
"lint": "eslint --ext .ts src",
|
||||||
"lint:report": "pnpm lint --format json --output-file report.json",
|
"lint:report": "pnpm lint --format json --output-file report.json",
|
||||||
"test:only": "NODE_OPTIONS=--experimental-vm-modules jest",
|
"test": "vitest src",
|
||||||
"test": "pnpm build:test && pnpm test:only",
|
"test:ci": "pnpm run test --silent --coverage",
|
||||||
"test:ci": "pnpm test:only --silent --coverage",
|
|
||||||
"prepublishOnly": "pnpm build"
|
"prepublishOnly": "pnpm build"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -48,5 +47,9 @@
|
||||||
"prettier": "@silverhand/eslint-config/.prettierrc",
|
"prettier": "@silverhand/eslint-config/.prettierrc",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitest/coverage-v8": "^1.4.0",
|
||||||
|
"vitest": "^1.4.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,76 @@
|
||||||
import type { GetConnectorConfig } from '@logto/connector-kit';
|
import nock from 'nock';
|
||||||
|
|
||||||
|
import { vi, describe, beforeAll, it, expect } from 'vitest';
|
||||||
|
|
||||||
|
import { graphAPIEndpoint } from './constant.js';
|
||||||
import createConnector from './index.js';
|
import createConnector from './index.js';
|
||||||
|
|
||||||
const { jest } = import.meta;
|
vi.mock('@azure/msal-node', async () => ({
|
||||||
|
ConfidentialClientApplication: class {
|
||||||
|
async acquireTokenByCode() {
|
||||||
|
return {
|
||||||
|
accessToken: 'accessToken',
|
||||||
|
scopes: ['scopes'],
|
||||||
|
tokenType: 'tokenType',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
const getConnectorConfig = jest.fn() as GetConnectorConfig;
|
const getConnectorConfig = vi.fn().mockResolvedValue({
|
||||||
|
clientId: 'clientId',
|
||||||
|
clientSecret: 'clientSecret',
|
||||||
|
cloudInstance: 'https://login.microsoftonline.com',
|
||||||
|
tenantId: 'tenantId',
|
||||||
|
});
|
||||||
|
|
||||||
describe('Azure AD connector', () => {
|
describe('Azure AD connector', () => {
|
||||||
it('init without exploding', () => {
|
it('init without exploding', () => {
|
||||||
expect(async () => createConnector({ getConfig: getConnectorConfig })).not.toThrow();
|
expect(async () => createConnector({ getConfig: getConnectorConfig })).not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getUserInfo', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
const graphMeUrl = new URL(graphAPIEndpoint);
|
||||||
|
nock(graphMeUrl.origin).get(graphMeUrl.pathname).reply(200, {
|
||||||
|
id: 'id',
|
||||||
|
displayName: 'displayName',
|
||||||
|
mail: 'mail',
|
||||||
|
userPrincipalName: 'userPrincipalName',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get user info from graph api', async () => {
|
||||||
|
const connector = await createConnector({ getConfig: getConnectorConfig });
|
||||||
|
const userInfo = await connector.getUserInfo(
|
||||||
|
{ code: 'code', redirectUri: 'redirectUri' },
|
||||||
|
vi.fn()
|
||||||
|
);
|
||||||
|
expect(userInfo).toEqual({
|
||||||
|
id: 'id',
|
||||||
|
name: 'displayName',
|
||||||
|
email: 'mail',
|
||||||
|
rawData: {
|
||||||
|
id: 'id',
|
||||||
|
displayName: 'displayName',
|
||||||
|
mail: 'mail',
|
||||||
|
userPrincipalName: 'userPrincipalName',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw if graph api response has no id', async () => {
|
||||||
|
const graphMeUrl = new URL(graphAPIEndpoint);
|
||||||
|
nock(graphMeUrl.origin).get(graphMeUrl.pathname).reply(200, {
|
||||||
|
displayName: 'displayName',
|
||||||
|
mail: 'mail',
|
||||||
|
userPrincipalName: 'userPrincipalName',
|
||||||
|
});
|
||||||
|
|
||||||
|
const connector = await createConnector({ getConfig: getConnectorConfig });
|
||||||
|
const userInfo = connector.getUserInfo({ code: 'code', redirectUri: 'redirectUri' }, vi.fn());
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||||
|
await expect(userInfo).rejects.toThrow(expect.objectContaining({ code: 'invalid_response' }));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { got, HTTPError } from 'got';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
import type { AuthorizationCodeRequest, AuthorizationUrlRequest } from '@azure/msal-node';
|
import type { AuthorizationCodeRequest, AuthorizationUrlRequest } from '@azure/msal-node';
|
||||||
import { ConfidentialClientApplication, CryptoProvider } from '@azure/msal-node';
|
import { ConfidentialClientApplication } from '@azure/msal-node';
|
||||||
import type {
|
import type {
|
||||||
GetAuthorizationUri,
|
GetAuthorizationUri,
|
||||||
GetUserInfo,
|
GetUserInfo,
|
||||||
|
@ -31,10 +31,6 @@ import {
|
||||||
// eslint-disable-next-line @silverhand/fp/no-let
|
// eslint-disable-next-line @silverhand/fp/no-let
|
||||||
let authCodeRequest: AuthorizationCodeRequest;
|
let authCodeRequest: AuthorizationCodeRequest;
|
||||||
|
|
||||||
// This `cryptoProvider` seems not used.
|
|
||||||
// Temporarily keep this as this is a refactor, which should not change the logics.
|
|
||||||
const cryptoProvider = new CryptoProvider();
|
|
||||||
|
|
||||||
const getAuthorizationUri =
|
const getAuthorizationUri =
|
||||||
(getConfig: GetConnectorConfig): GetAuthorizationUri =>
|
(getConfig: GetConnectorConfig): GetAuthorizationUri =>
|
||||||
async ({ state, redirectUri }) => {
|
async ({ state, redirectUri }) => {
|
||||||
|
@ -85,7 +81,6 @@ const getAccessToken = async (config: AzureADConfig, code: string, redirectUri:
|
||||||
});
|
});
|
||||||
|
|
||||||
const authResult = await clientApplication.acquireTokenByCode(codeRequest);
|
const authResult = await clientApplication.acquireTokenByCode(codeRequest);
|
||||||
|
|
||||||
const result = accessTokenResponseGuard.safeParse(authResult);
|
const result = accessTokenResponseGuard.safeParse(authResult);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
|
@ -117,8 +112,8 @@ const getUserInfo =
|
||||||
},
|
},
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -130,6 +125,7 @@ const getUserInfo =
|
||||||
id,
|
id,
|
||||||
email: conditional(mail),
|
email: conditional(mail),
|
||||||
name: conditional(displayName),
|
name: conditional(displayName),
|
||||||
|
rawData,
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof HTTPError) {
|
if (error instanceof HTTPError) {
|
||||||
|
|
|
@ -101,11 +101,18 @@ describe('Discord connector', () => {
|
||||||
},
|
},
|
||||||
jest.fn()
|
jest.fn()
|
||||||
);
|
);
|
||||||
expect(socialUserInfo).toMatchObject({
|
expect(socialUserInfo).toStrictEqual({
|
||||||
id: '1234567890',
|
id: '1234567890',
|
||||||
name: 'Whumpus',
|
name: 'Whumpus',
|
||||||
avatar: 'https://cdn.discordapp.com/avatars/1234567890/avatar_id',
|
avatar: 'https://cdn.discordapp.com/avatars/1234567890/avatar_id',
|
||||||
email: 'whumpus@discord.com',
|
email: 'whumpus@discord.com',
|
||||||
|
rawData: {
|
||||||
|
id: '1234567890',
|
||||||
|
username: 'Whumpus',
|
||||||
|
avatar: 'avatar_id',
|
||||||
|
email: 'whumpus@discord.com',
|
||||||
|
verified: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,8 @@ const getUserInfo =
|
||||||
},
|
},
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -124,7 +124,7 @@ const getUserInfo =
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, userInfoResult.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, userInfoResult.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return userInfoResult.data;
|
return { ...userInfoResult.data, rawData };
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof HTTPError) {
|
if (error instanceof HTTPError) {
|
||||||
const { statusCode, body: rawBody } = error.response;
|
const { statusCode, body: rawBody } = error.response;
|
||||||
|
|
|
@ -132,11 +132,17 @@ describe('Facebook connector', () => {
|
||||||
},
|
},
|
||||||
jest.fn()
|
jest.fn()
|
||||||
);
|
);
|
||||||
expect(socialUserInfo).toMatchObject({
|
expect(socialUserInfo).toStrictEqual({
|
||||||
id: '1234567890',
|
id: '1234567890',
|
||||||
avatar,
|
avatar,
|
||||||
name: 'monalisa octocat',
|
name: 'monalisa octocat',
|
||||||
email: 'octocat@facebook.com',
|
email: 'octocat@facebook.com',
|
||||||
|
rawData: {
|
||||||
|
id: '1234567890',
|
||||||
|
name: 'monalisa octocat',
|
||||||
|
email: 'octocat@facebook.com',
|
||||||
|
picture: { data: { url: avatar } },
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,8 @@ const getUserInfo =
|
||||||
},
|
},
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -119,6 +119,7 @@ const getUserInfo =
|
||||||
avatar: picture?.data.url,
|
avatar: picture?.data.url,
|
||||||
email,
|
email,
|
||||||
name,
|
name,
|
||||||
|
rawData,
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof HTTPError) {
|
if (error instanceof HTTPError) {
|
||||||
|
|
|
@ -112,7 +112,7 @@ describe('getUserInfo', () => {
|
||||||
const accessTokenUrl = new URL(accessTokenEndpoint);
|
const accessTokenUrl = new URL(accessTokenEndpoint);
|
||||||
|
|
||||||
it('should get userInfo with accessToken', async () => {
|
it('should get userInfo with accessToken', async () => {
|
||||||
nock(userInfoUrl.origin).get(userInfoUrl.pathname).query(true).once().reply(200, {
|
const jsonResponse = Object.freeze({
|
||||||
sub: 'ou_caecc734c2e3328a62489fe0648c4b98779515d3',
|
sub: 'ou_caecc734c2e3328a62489fe0648c4b98779515d3',
|
||||||
name: '李雷',
|
name: '李雷',
|
||||||
picture: 'https://www.feishu.cn/avatar',
|
picture: 'https://www.feishu.cn/avatar',
|
||||||
|
@ -129,9 +129,10 @@ describe('getUserInfo', () => {
|
||||||
employee_no: '111222333',
|
employee_no: '111222333',
|
||||||
mobile: '+86130xxxx0000',
|
mobile: '+86130xxxx0000',
|
||||||
});
|
});
|
||||||
|
nock(userInfoUrl.origin).get(userInfoUrl.pathname).query(true).once().reply(200, jsonResponse);
|
||||||
|
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const { id, name, avatar } = await connector.getUserInfo(
|
const { id, name, avatar, rawData } = await connector.getUserInfo(
|
||||||
{
|
{
|
||||||
code: 'code',
|
code: 'code',
|
||||||
redirectUri: 'http://localhost:3000',
|
redirectUri: 'http://localhost:3000',
|
||||||
|
@ -141,6 +142,7 @@ describe('getUserInfo', () => {
|
||||||
expect(id).toEqual('ou_caecc734c2e3328a62489fe0648c4b98779515d3');
|
expect(id).toEqual('ou_caecc734c2e3328a62489fe0648c4b98779515d3');
|
||||||
expect(name).toEqual('李雷');
|
expect(name).toEqual('李雷');
|
||||||
expect(avatar).toEqual('www.feishu.cn/avatar/icon');
|
expect(avatar).toEqual('www.feishu.cn/avatar/icon');
|
||||||
|
expect(rawData).toEqual(jsonResponse);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw General error if code not provided in input', async () => {
|
it('throw General error if code not provided in input', async () => {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
ConnectorErrorCodes,
|
ConnectorErrorCodes,
|
||||||
ConnectorPlatform,
|
ConnectorPlatform,
|
||||||
ConnectorType,
|
ConnectorType,
|
||||||
|
jsonGuard,
|
||||||
validateConfig,
|
validateConfig,
|
||||||
} from '@logto/connector-kit';
|
} from '@logto/connector-kit';
|
||||||
|
|
||||||
|
@ -153,6 +154,7 @@ export function getUserInfo(getConfig: GetConnectorConfig): GetUserInfo {
|
||||||
email: conditional(email),
|
email: conditional(email),
|
||||||
userId: conditional(user_id),
|
userId: conditional(user_id),
|
||||||
phone: conditional(mobile),
|
phone: conditional(mobile),
|
||||||
|
rawData: jsonGuard.parse(response.body),
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof ConnectorError) {
|
if (error instanceof ConnectorError) {
|
||||||
|
|
|
@ -91,14 +91,22 @@ describe('getUserInfo', () => {
|
||||||
avatar_url: 'https://github.com/images/error/octocat_happy.gif',
|
avatar_url: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
name: 'monalisa octocat',
|
name: 'monalisa octocat',
|
||||||
email: 'octocat@github.com',
|
email: 'octocat@github.com',
|
||||||
|
foo: 'bar',
|
||||||
});
|
});
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const socialUserInfo = await connector.getUserInfo({ code: 'code' }, jest.fn());
|
const socialUserInfo = await connector.getUserInfo({ code: 'code' }, jest.fn());
|
||||||
expect(socialUserInfo).toMatchObject({
|
expect(socialUserInfo).toStrictEqual({
|
||||||
id: '1',
|
id: '1',
|
||||||
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
name: 'monalisa octocat',
|
name: 'monalisa octocat',
|
||||||
email: 'octocat@github.com',
|
email: 'octocat@github.com',
|
||||||
|
rawData: {
|
||||||
|
id: 1,
|
||||||
|
avatar_url: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
|
name: 'monalisa octocat',
|
||||||
|
email: 'octocat@github.com',
|
||||||
|
foo: 'bar',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -113,6 +121,12 @@ describe('getUserInfo', () => {
|
||||||
const socialUserInfo = await connector.getUserInfo({ code: 'code' }, jest.fn());
|
const socialUserInfo = await connector.getUserInfo({ code: 'code' }, jest.fn());
|
||||||
expect(socialUserInfo).toMatchObject({
|
expect(socialUserInfo).toMatchObject({
|
||||||
id: '1',
|
id: '1',
|
||||||
|
rawData: {
|
||||||
|
id: 1,
|
||||||
|
avatar_url: null,
|
||||||
|
name: null,
|
||||||
|
email: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -117,8 +117,8 @@ const getUserInfo =
|
||||||
},
|
},
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -131,6 +131,7 @@ const getUserInfo =
|
||||||
avatar: conditional(avatar),
|
avatar: conditional(avatar),
|
||||||
email: conditional(email),
|
email: conditional(email),
|
||||||
name: conditional(name),
|
name: conditional(name),
|
||||||
|
rawData,
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof HTTPError) {
|
if (error instanceof HTTPError) {
|
||||||
|
|
|
@ -79,7 +79,7 @@ describe('google connector', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get valid SocialUserInfo', async () => {
|
it('should get valid SocialUserInfo', async () => {
|
||||||
nock(userInfoEndpoint).post('').reply(200, {
|
const jsonResponse = Object.freeze({
|
||||||
sub: '1234567890',
|
sub: '1234567890',
|
||||||
name: 'monalisa octocat',
|
name: 'monalisa octocat',
|
||||||
given_name: 'monalisa',
|
given_name: 'monalisa',
|
||||||
|
@ -89,6 +89,7 @@ describe('google connector', () => {
|
||||||
email_verified: true,
|
email_verified: true,
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
});
|
});
|
||||||
|
nock(userInfoEndpoint).post('').reply(200, jsonResponse);
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const socialUserInfo = await connector.getUserInfo(
|
const socialUserInfo = await connector.getUserInfo(
|
||||||
{
|
{
|
||||||
|
@ -97,11 +98,12 @@ describe('google connector', () => {
|
||||||
},
|
},
|
||||||
jest.fn()
|
jest.fn()
|
||||||
);
|
);
|
||||||
expect(socialUserInfo).toMatchObject({
|
expect(socialUserInfo).toStrictEqual({
|
||||||
id: '1234567890',
|
id: '1234567890',
|
||||||
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
name: 'monalisa octocat',
|
name: 'monalisa octocat',
|
||||||
email: 'octocat@google.com',
|
email: 'octocat@google.com',
|
||||||
|
rawData: jsonResponse,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,8 @@ const getUserInfo =
|
||||||
},
|
},
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -115,6 +115,7 @@ const getUserInfo =
|
||||||
avatar,
|
avatar,
|
||||||
email: conditional(email_verified && email),
|
email: conditional(email_verified && email),
|
||||||
name,
|
name,
|
||||||
|
rawData,
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
return getUserInfoErrorHandler(error);
|
return getUserInfoErrorHandler(error);
|
||||||
|
|
|
@ -79,20 +79,19 @@ describe('kakao connector', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get valid SocialUserInfo', async () => {
|
it('should get valid SocialUserInfo', async () => {
|
||||||
nock(userInfoEndpoint)
|
const jsonResponse = Object.freeze({
|
||||||
.post('')
|
id: 1_234_567_890,
|
||||||
.reply(200, {
|
kakao_account: {
|
||||||
id: 1_234_567_890,
|
is_email_valid: true,
|
||||||
kakao_account: {
|
email: 'ruddbs5302@gmail.com',
|
||||||
is_email_valid: true,
|
profile: {
|
||||||
email: 'ruddbs5302@gmail.com',
|
nickname: 'pemassi',
|
||||||
profile: {
|
profile_image_url: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
nickname: 'pemassi',
|
is_default_image: false,
|
||||||
profile_image_url: 'https://github.com/images/error/octocat_happy.gif',
|
|
||||||
is_default_image: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
nock(userInfoEndpoint).post('').reply(200, jsonResponse);
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const socialUserInfo = await connector.getUserInfo(
|
const socialUserInfo = await connector.getUserInfo(
|
||||||
{
|
{
|
||||||
|
@ -101,11 +100,12 @@ describe('kakao connector', () => {
|
||||||
},
|
},
|
||||||
jest.fn()
|
jest.fn()
|
||||||
);
|
);
|
||||||
expect(socialUserInfo).toMatchObject({
|
expect(socialUserInfo).toStrictEqual({
|
||||||
id: '1234567890',
|
id: '1234567890',
|
||||||
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
name: 'pemassi',
|
name: 'pemassi',
|
||||||
email: 'ruddbs5302@gmail.com',
|
email: 'ruddbs5302@gmail.com',
|
||||||
|
rawData: jsonResponse,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,8 @@ const getUserInfo =
|
||||||
},
|
},
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -118,6 +118,7 @@ const getUserInfo =
|
||||||
avatar: conditional(profile && !profile.is_default_image && profile.profile_image_url),
|
avatar: conditional(profile && !profile.is_default_image && profile.profile_image_url),
|
||||||
email: conditional(is_email_valid && email),
|
email: conditional(is_email_valid && email),
|
||||||
name: conditional(profile?.nickname),
|
name: conditional(profile?.nickname),
|
||||||
|
rawData,
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
return getUserInfoErrorHandler(error);
|
return getUserInfoErrorHandler(error);
|
||||||
|
|
|
@ -7,7 +7,12 @@ import type {
|
||||||
CreateConnector,
|
CreateConnector,
|
||||||
SocialConnector,
|
SocialConnector,
|
||||||
} from '@logto/connector-kit';
|
} from '@logto/connector-kit';
|
||||||
import { ConnectorError, ConnectorErrorCodes, ConnectorType } from '@logto/connector-kit';
|
import {
|
||||||
|
ConnectorError,
|
||||||
|
ConnectorErrorCodes,
|
||||||
|
ConnectorType,
|
||||||
|
jsonGuard,
|
||||||
|
} from '@logto/connector-kit';
|
||||||
|
|
||||||
import { defaultMetadata } from './constant.js';
|
import { defaultMetadata } from './constant.js';
|
||||||
import { mockSocialConfigGuard } from './types.js';
|
import { mockSocialConfigGuard } from './types.js';
|
||||||
|
@ -35,6 +40,7 @@ const getUserInfo: GetUserInfo = async (data) => {
|
||||||
return {
|
return {
|
||||||
id: userId ?? `mock-social-sub-${randomUUID()}`,
|
id: userId ?? `mock-social-sub-${randomUUID()}`,
|
||||||
...rest,
|
...rest,
|
||||||
|
rawData: jsonGuard.parse(data),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -79,22 +79,21 @@ describe('naver connector', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get valid SocialUserInfo', async () => {
|
it('should get valid SocialUserInfo', async () => {
|
||||||
nock(userInfoEndpoint)
|
const jsonResponse = Object.freeze({
|
||||||
.post('')
|
resultcode: '00',
|
||||||
.reply(200, {
|
message: 'success',
|
||||||
resultcode: '00',
|
response: {
|
||||||
message: 'success',
|
email: 'openapi@naver.com',
|
||||||
response: {
|
nickname: 'OpenAPI',
|
||||||
email: 'openapi@naver.com',
|
profile_image: 'https://ssl.pstatic.net/static/pwe/address/nodata_33x33.gif',
|
||||||
nickname: 'OpenAPI',
|
age: '40-49',
|
||||||
profile_image: 'https://ssl.pstatic.net/static/pwe/address/nodata_33x33.gif',
|
gender: 'F',
|
||||||
age: '40-49',
|
id: '32742776',
|
||||||
gender: 'F',
|
name: '오픈 API',
|
||||||
id: '32742776',
|
birthday: '10-01',
|
||||||
name: '오픈 API',
|
},
|
||||||
birthday: '10-01',
|
});
|
||||||
},
|
nock(userInfoEndpoint).post('').reply(200, jsonResponse);
|
||||||
});
|
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const socialUserInfo = await connector.getUserInfo(
|
const socialUserInfo = await connector.getUserInfo(
|
||||||
{
|
{
|
||||||
|
@ -108,6 +107,7 @@ describe('naver connector', () => {
|
||||||
avatar: 'https://ssl.pstatic.net/static/pwe/address/nodata_33x33.gif',
|
avatar: 'https://ssl.pstatic.net/static/pwe/address/nodata_33x33.gif',
|
||||||
name: 'OpenAPI',
|
name: 'OpenAPI',
|
||||||
email: 'openapi@naver.com',
|
email: 'openapi@naver.com',
|
||||||
|
rawData: jsonResponse,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,8 @@ const getUserInfo =
|
||||||
},
|
},
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -114,6 +114,7 @@ const getUserInfo =
|
||||||
avatar: conditional(profile_image),
|
avatar: conditional(profile_image),
|
||||||
email: conditional(email),
|
email: conditional(email),
|
||||||
name: conditional(nickname),
|
name: conditional(nickname),
|
||||||
|
rawData,
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
return getUserInfoErrorHandler(error);
|
return getUserInfoErrorHandler(error);
|
||||||
|
|
|
@ -59,6 +59,7 @@ describe('getUserInfo', () => {
|
||||||
const userInfoEndpointUrl = new URL(mockConfig.userInfoEndpoint);
|
const userInfoEndpointUrl = new URL(mockConfig.userInfoEndpoint);
|
||||||
nock(userInfoEndpointUrl.origin).get(userInfoEndpointUrl.pathname).query(true).reply(200, {
|
nock(userInfoEndpointUrl.origin).get(userInfoEndpointUrl.pathname).query(true).reply(200, {
|
||||||
sub: userId,
|
sub: userId,
|
||||||
|
foo: 'bar',
|
||||||
});
|
});
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const userInfo = await connector.getUserInfo(
|
const userInfo = await connector.getUserInfo(
|
||||||
|
@ -67,6 +68,6 @@ describe('getUserInfo', () => {
|
||||||
return { redirectUri: 'http://localhost:3001/callback' };
|
return { redirectUri: 'http://localhost:3001/callback' };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
expect(userInfo).toEqual({ id: userId });
|
expect(userInfo).toStrictEqual({ id: userId, rawData: { sub: userId, foo: 'bar' } });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -71,8 +71,9 @@ const getUserInfo =
|
||||||
},
|
},
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJsonObject(httpResponse.body);
|
||||||
|
|
||||||
return userProfileMapping(parseJsonObject(httpResponse.body), parsedConfig.profileMap);
|
return { ...userProfileMapping(rawData, parsedConfig.profileMap), rawData };
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof HTTPError) {
|
if (error instanceof HTTPError) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(error.response.body));
|
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(error.response.body));
|
||||||
|
|
|
@ -69,6 +69,6 @@ describe('getUserInfo', () => {
|
||||||
return { nonce: 'nonce', redirectUri: 'http://localhost:3001/callback' };
|
return { nonce: 'nonce', redirectUri: 'http://localhost:3001/callback' };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
expect(userInfo).toEqual({ id: userId });
|
expect(userInfo).toMatchObject({ id: userId, rawData: { sub: userId, nonce: 'nonce' } });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
ConnectorErrorCodes,
|
ConnectorErrorCodes,
|
||||||
validateConfig,
|
validateConfig,
|
||||||
ConnectorType,
|
ConnectorType,
|
||||||
|
jsonGuard,
|
||||||
} from '@logto/connector-kit';
|
} from '@logto/connector-kit';
|
||||||
import { generateStandardId } from '@logto/shared/universal';
|
import { generateStandardId } from '@logto/shared/universal';
|
||||||
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
||||||
|
@ -137,6 +138,7 @@ const getUserInfo =
|
||||||
avatar: conditional(picture),
|
avatar: conditional(picture),
|
||||||
email: conditional(email_verified && email),
|
email: conditional(email_verified && email),
|
||||||
phone: conditional(phone_verified && phone),
|
phone: conditional(phone_verified && phone),
|
||||||
|
rawData: jsonGuard.parse(payload),
|
||||||
};
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof HTTPError) {
|
if (error instanceof HTTPError) {
|
||||||
|
|
|
@ -139,17 +139,22 @@ describe('getUserInfo', () => {
|
||||||
const parameters = new URLSearchParams({ access_token: 'access_token', openid: 'openid' });
|
const parameters = new URLSearchParams({ access_token: 'access_token', openid: 'openid' });
|
||||||
|
|
||||||
it('should get valid SocialUserInfo', async () => {
|
it('should get valid SocialUserInfo', async () => {
|
||||||
nock(userInfoEndpointUrl.origin).get(userInfoEndpointUrl.pathname).query(parameters).reply(0, {
|
const jsonResponse = Object.freeze({
|
||||||
unionid: 'this_is_an_arbitrary_wechat_union_id',
|
unionid: 'this_is_an_arbitrary_wechat_union_id',
|
||||||
headimgurl: 'https://github.com/images/error/octocat_happy.gif',
|
headimgurl: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
nickname: 'wechat bot',
|
nickname: 'wechat bot',
|
||||||
});
|
});
|
||||||
|
nock(userInfoEndpointUrl.origin)
|
||||||
|
.get(userInfoEndpointUrl.pathname)
|
||||||
|
.query(parameters)
|
||||||
|
.reply(0, jsonResponse);
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const socialUserInfo = await connector.getUserInfo({ code: 'code' }, jest.fn());
|
const socialUserInfo = await connector.getUserInfo({ code: 'code' }, jest.fn());
|
||||||
expect(socialUserInfo).toMatchObject({
|
expect(socialUserInfo).toMatchObject({
|
||||||
id: 'this_is_an_arbitrary_wechat_union_id',
|
id: 'this_is_an_arbitrary_wechat_union_id',
|
||||||
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
name: 'wechat bot',
|
name: 'wechat bot',
|
||||||
|
rawData: jsonResponse,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,8 @@ const getUserInfo =
|
||||||
searchParams: { access_token: accessToken, openid },
|
searchParams: { access_token: accessToken, openid },
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -114,7 +114,7 @@ const getUserInfo =
|
||||||
// 'errmsg' and 'errcode' turn to non-empty values or empty values at the same time. Hence, if 'errmsg' is non-empty then 'errcode' should be non-empty.
|
// 'errmsg' and 'errcode' turn to non-empty values or empty values at the same time. Hence, if 'errmsg' is non-empty then 'errcode' should be non-empty.
|
||||||
userInfoResponseMessageParser(result.data);
|
userInfoResponseMessageParser(result.data);
|
||||||
|
|
||||||
return { id: unionid ?? openid, avatar: headimgurl, name: nickname };
|
return { id: unionid ?? openid, avatar: headimgurl, name: nickname, rawData };
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
return getUserInfoErrorHandler(error);
|
return getUserInfoErrorHandler(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,11 +130,15 @@ describe('getUserInfo', () => {
|
||||||
const parameters = new URLSearchParams({ access_token: 'access_token', openid: 'openid' });
|
const parameters = new URLSearchParams({ access_token: 'access_token', openid: 'openid' });
|
||||||
|
|
||||||
it('should get valid SocialUserInfo', async () => {
|
it('should get valid SocialUserInfo', async () => {
|
||||||
nock(userInfoEndpointUrl.origin).get(userInfoEndpointUrl.pathname).query(parameters).reply(0, {
|
const jsonResponse = Object.freeze({
|
||||||
unionid: 'this_is_an_arbitrary_wechat_union_id',
|
unionid: 'this_is_an_arbitrary_wechat_union_id',
|
||||||
headimgurl: 'https://github.com/images/error/octocat_happy.gif',
|
headimgurl: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
nickname: 'wechat bot',
|
nickname: 'wechat bot',
|
||||||
});
|
});
|
||||||
|
nock(userInfoEndpointUrl.origin)
|
||||||
|
.get(userInfoEndpointUrl.pathname)
|
||||||
|
.query(parameters)
|
||||||
|
.reply(0, jsonResponse);
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const socialUserInfo = await connector.getUserInfo(
|
const socialUserInfo = await connector.getUserInfo(
|
||||||
{
|
{
|
||||||
|
@ -146,6 +150,7 @@ describe('getUserInfo', () => {
|
||||||
id: 'this_is_an_arbitrary_wechat_union_id',
|
id: 'this_is_an_arbitrary_wechat_union_id',
|
||||||
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
avatar: 'https://github.com/images/error/octocat_happy.gif',
|
||||||
name: 'wechat bot',
|
name: 'wechat bot',
|
||||||
|
rawData: jsonResponse,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,8 @@ const getUserInfo =
|
||||||
searchParams: { access_token: accessToken, openid },
|
searchParams: { access_token: accessToken, openid },
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -115,7 +115,7 @@ const getUserInfo =
|
||||||
// 'errmsg' and 'errcode' turn to non-empty values or empty values at the same time. Hence, if 'errmsg' is non-empty then 'errcode' should be non-empty.
|
// 'errmsg' and 'errcode' turn to non-empty values or empty values at the same time. Hence, if 'errmsg' is non-empty then 'errcode' should be non-empty.
|
||||||
userInfoResponseMessageParser(result.data);
|
userInfoResponseMessageParser(result.data);
|
||||||
|
|
||||||
return { id: unionid ?? openid, avatar: headimgurl, name: nickname };
|
return { id: unionid ?? openid, avatar: headimgurl, name: nickname, rawData };
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
return getUserInfoErrorHandler(error);
|
return getUserInfoErrorHandler(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,9 +135,14 @@ describe('getUserInfo', () => {
|
||||||
const parameters = new URLSearchParams({ access_token: 'access_token', code: 'code' });
|
const parameters = new URLSearchParams({ access_token: 'access_token', code: 'code' });
|
||||||
|
|
||||||
it('should get valid SocialUserInfo', async () => {
|
it('should get valid SocialUserInfo', async () => {
|
||||||
nock(userInfoEndpointUrl.origin).get(userInfoEndpointUrl.pathname).query(parameters).reply(0, {
|
const jsonResponse = Object.freeze({
|
||||||
userid: 'wecom_id',
|
userid: 'wecom_id',
|
||||||
|
foo: 'bar',
|
||||||
});
|
});
|
||||||
|
nock(userInfoEndpointUrl.origin)
|
||||||
|
.get(userInfoEndpointUrl.pathname)
|
||||||
|
.query(parameters)
|
||||||
|
.reply(0, jsonResponse);
|
||||||
const connector = await createConnector({ getConfig });
|
const connector = await createConnector({ getConfig });
|
||||||
const socialUserInfo = await connector.getUserInfo(
|
const socialUserInfo = await connector.getUserInfo(
|
||||||
{
|
{
|
||||||
|
@ -149,6 +154,7 @@ describe('getUserInfo', () => {
|
||||||
id: 'wecom_id',
|
id: 'wecom_id',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
name: 'wecom_id',
|
name: 'wecom_id',
|
||||||
|
rawData: jsonResponse,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -106,8 +106,8 @@ const getUserInfo =
|
||||||
searchParams: { access_token: accessToken, code },
|
searchParams: { access_token: accessToken, code },
|
||||||
timeout: { request: defaultTimeout },
|
timeout: { request: defaultTimeout },
|
||||||
});
|
});
|
||||||
|
const rawData = parseJson(httpResponse.body);
|
||||||
const result = userInfoResponseGuard.safeParse(parseJson(httpResponse.body));
|
const result = userInfoResponseGuard.safeParse(rawData);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
|
||||||
|
@ -118,15 +118,18 @@ const getUserInfo =
|
||||||
errorResponseHandler(result.data);
|
errorResponseHandler(result.data);
|
||||||
//
|
//
|
||||||
const { userid, openid } = result.data;
|
const { userid, openid } = result.data;
|
||||||
|
const id = userid ?? openid;
|
||||||
|
|
||||||
if (userid) {
|
if (!id) {
|
||||||
return { id: userid, avatar: '', name: userid };
|
throw new Error('Both userid and openid are undefined or null.');
|
||||||
}
|
}
|
||||||
if (openid) {
|
|
||||||
return { id: openid, avatar: '', name: openid };
|
return {
|
||||||
}
|
id,
|
||||||
throw new Error('Both userid and openid are undefined or null.');
|
avatar: '',
|
||||||
// Both userid and openid are null
|
name: id,
|
||||||
|
rawData,
|
||||||
|
};
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
return getUserInfoErrorHandler(error);
|
return getUserInfoErrorHandler(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import {
|
import {
|
||||||
type CreateSsoConnector,
|
type CreateSsoConnector,
|
||||||
SignInIdentifier,
|
SignInIdentifier,
|
||||||
demoAppApplicationId,
|
|
||||||
SsoProviderName,
|
SsoProviderName,
|
||||||
|
demoAppApplicationId,
|
||||||
} from '@logto/schemas';
|
} from '@logto/schemas';
|
||||||
import { appendPath, getEnv } from '@silverhand/essentials';
|
import { appendPath, getEnv } from '@silverhand/essentials';
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ export const demoAppUrl = appendPath(new URL(logtoUrl), 'demo-app');
|
||||||
|
|
||||||
export const discoveryUrl = `${logtoUrl}/oidc/.well-known/openid-configuration`;
|
export const discoveryUrl = `${logtoUrl}/oidc/.well-known/openid-configuration`;
|
||||||
|
|
||||||
export const demoAppRedirectUri = `${logtoUrl}/${demoAppApplicationId}`;
|
export const demoAppRedirectUri = appendPath(new URL(logtoUrl), demoAppApplicationId).href;
|
||||||
export const adminConsoleRedirectUri = `${logtoConsoleUrl}/console/callback`;
|
export const adminConsoleRedirectUri = `${logtoConsoleUrl}/console/callback`;
|
||||||
|
|
||||||
export const signUpIdentifiers = {
|
export const signUpIdentifiers = {
|
||||||
|
|
|
@ -193,6 +193,13 @@ describe('admin console user management', () => {
|
||||||
details: {
|
details: {
|
||||||
id: socialUserId,
|
id: socialUserId,
|
||||||
email: socialUserEmail,
|
email: socialUserEmail,
|
||||||
|
rawData: {
|
||||||
|
code,
|
||||||
|
email: socialUserEmail,
|
||||||
|
redirectUri,
|
||||||
|
state,
|
||||||
|
userId: socialUserId,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -202,6 +209,13 @@ describe('admin console user management', () => {
|
||||||
expect(updatedIdentity).toHaveProperty(mockSocialConnectorTarget);
|
expect(updatedIdentity).toHaveProperty(mockSocialConnectorTarget);
|
||||||
expect(updatedIdentity[mockSocialConnectorTarget]).toMatchObject({
|
expect(updatedIdentity[mockSocialConnectorTarget]).toMatchObject({
|
||||||
userId: anotherSocialUserId,
|
userId: anotherSocialUserId,
|
||||||
|
rawData: {
|
||||||
|
code,
|
||||||
|
email: socialUserEmail,
|
||||||
|
redirectUri,
|
||||||
|
state,
|
||||||
|
userId: anotherSocialUserId,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const updatedIdentities = await putUserIdentity(userId, socialTarget, socialIdentity);
|
const updatedIdentities = await putUserIdentity(userId, socialTarget, socialIdentity);
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { ConnectorType, InteractionEvent, SignInIdentifier } from '@logto/schemas';
|
import { ConnectorType, InteractionEvent, SignInIdentifier } from '@logto/schemas';
|
||||||
|
|
||||||
import { mockSocialConnectorId } from '#src/__mocks__/connectors-mock.js';
|
import {
|
||||||
|
mockSocialConnectorId,
|
||||||
|
mockSocialConnectorTarget,
|
||||||
|
} from '#src/__mocks__/connectors-mock.js';
|
||||||
import {
|
import {
|
||||||
createSocialAuthorizationUri,
|
createSocialAuthorizationUri,
|
||||||
putInteraction,
|
putInteraction,
|
||||||
|
@ -131,8 +134,24 @@ describe('Social Identifier Interactions', () => {
|
||||||
|
|
||||||
const uid = await processSession(client, redirectTo);
|
const uid = await processSession(client, redirectTo);
|
||||||
|
|
||||||
const { primaryEmail } = await getUser(uid);
|
const { primaryEmail, identities } = await getUser(uid);
|
||||||
expect(primaryEmail).toBe(socialEmail);
|
expect(primaryEmail).toBe(socialEmail);
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
expect(identities[mockSocialConnectorTarget]).toStrictEqual({
|
||||||
|
details: {
|
||||||
|
email: expect.any(String),
|
||||||
|
id: expect.any(String),
|
||||||
|
rawData: {
|
||||||
|
code: 'auth_code_foo',
|
||||||
|
email: expect.any(String),
|
||||||
|
redirectUri: 'http://foo.dev/callback',
|
||||||
|
state: 'foo_state',
|
||||||
|
userId: expect.any(String),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
userId: expect.any(String),
|
||||||
|
});
|
||||||
|
/* eslint-enable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
|
||||||
await logoutClient(client);
|
await logoutClient(client);
|
||||||
await deleteUser(uid);
|
await deleteUser(uid);
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
import type { Json } from '@withtyped/server';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
export * from './custom-domain.js';
|
export * from './custom-domain.js';
|
||||||
export * from './hooks.js';
|
export * from './hooks.js';
|
||||||
export * from './logs.js';
|
export * from './logs.js';
|
||||||
|
@ -15,17 +12,8 @@ export * from './applications.js';
|
||||||
export {
|
export {
|
||||||
configurableConnectorMetadataGuard,
|
configurableConnectorMetadataGuard,
|
||||||
type ConfigurableConnectorMetadata,
|
type ConfigurableConnectorMetadata,
|
||||||
|
jsonGuard,
|
||||||
|
jsonObjectGuard,
|
||||||
} from '@logto/connector-kit';
|
} from '@logto/connector-kit';
|
||||||
|
|
||||||
export type { Json, JsonObject } from '@withtyped/server';
|
export type { Json, JsonObject } from '@withtyped/server';
|
||||||
|
|
||||||
/* === Commonly Used === */
|
|
||||||
|
|
||||||
// Copied from https://github.com/colinhacks/zod#json-type
|
|
||||||
const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
|
||||||
|
|
||||||
export const jsonGuard: z.ZodType<Json> = z.lazy(() =>
|
|
||||||
z.union([literalSchema, z.array(jsonGuard), z.record(jsonGuard)])
|
|
||||||
);
|
|
||||||
|
|
||||||
export const jsonObjectGuard = z.record(jsonGuard);
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { type Json, type JsonObject } from '@withtyped/server';
|
||||||
import type { ZodType, ZodTypeDef } from 'zod';
|
import type { ZodType, ZodTypeDef } from 'zod';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -5,6 +6,8 @@ import {
|
||||||
ConnectorErrorCodes,
|
ConnectorErrorCodes,
|
||||||
type SendMessagePayload,
|
type SendMessagePayload,
|
||||||
ConnectorType,
|
ConnectorType,
|
||||||
|
jsonGuard,
|
||||||
|
jsonObjectGuard,
|
||||||
} from './types/index.js';
|
} from './types/index.js';
|
||||||
|
|
||||||
export * from './types/index.js';
|
export * from './types/index.js';
|
||||||
|
@ -24,38 +27,24 @@ export const parseJson = (
|
||||||
jsonString: string,
|
jsonString: string,
|
||||||
errorCode: ConnectorErrorCodes = ConnectorErrorCodes.InvalidResponse,
|
errorCode: ConnectorErrorCodes = ConnectorErrorCodes.InvalidResponse,
|
||||||
errorPayload?: unknown
|
errorPayload?: unknown
|
||||||
): unknown => {
|
): Json => {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(jsonString);
|
return jsonGuard.parse(JSON.parse(jsonString));
|
||||||
} catch {
|
} catch {
|
||||||
throw new ConnectorError(errorCode, errorPayload ?? jsonString);
|
throw new ConnectorError(errorCode, errorPayload ?? jsonString);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isRecordOrArray = (parsed: unknown): parsed is Record<string, unknown> | unknown[] => {
|
export const parseJsonObject = (
|
||||||
if (Array.isArray(parsed)) {
|
...[jsonString, errorCode = ConnectorErrorCodes.InvalidResponse, errorPayload]: Parameters<
|
||||||
return true;
|
typeof parseJson
|
||||||
|
>
|
||||||
|
): JsonObject => {
|
||||||
|
try {
|
||||||
|
return jsonObjectGuard.parse(JSON.parse(jsonString));
|
||||||
|
} catch {
|
||||||
|
throw new ConnectorError(errorCode, errorPayload ?? jsonString);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(parsed !== null && typeof parsed === 'object')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.getOwnPropertySymbols(parsed).length > 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const parseJsonObject = (...args: Parameters<typeof parseJson>) => {
|
|
||||||
const parsed = parseJson(...args);
|
|
||||||
|
|
||||||
if (!isRecordOrArray(parsed)) {
|
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsed;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @deprecated Use {@link mockConnectorFilePaths} instead. */
|
/** @deprecated Use {@link mockConnectorFilePaths} instead. */
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// MARK: Social connector
|
// MARK: Social connector
|
||||||
|
import { type Json } from '@withtyped/server';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { type BaseConnector, type ConnectorType } from './foundation.js';
|
import { type BaseConnector, type ConnectorType } from './foundation.js';
|
||||||
|
@ -22,20 +23,38 @@ export type GetAuthorizationUri = (
|
||||||
setSession: SetSession
|
setSession: SetSession
|
||||||
) => Promise<string>;
|
) => Promise<string>;
|
||||||
|
|
||||||
|
// Copied from https://github.com/colinhacks/zod#json-type
|
||||||
|
const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
||||||
|
|
||||||
|
export const jsonGuard: z.ZodType<Json> = z.lazy(() =>
|
||||||
|
z.union([literalSchema, z.array(jsonGuard), z.record(jsonGuard)])
|
||||||
|
);
|
||||||
|
|
||||||
|
export const jsonObjectGuard = z.record(jsonGuard);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalized social user info that can be used in the system. The raw data returned from the
|
||||||
|
* social provider is also included in the `rawData` field.
|
||||||
|
*/
|
||||||
|
export type SocialUserInfo = {
|
||||||
|
id: string;
|
||||||
|
email?: string;
|
||||||
|
phone?: string;
|
||||||
|
name?: string;
|
||||||
|
avatar?: string;
|
||||||
|
rawData?: Json;
|
||||||
|
};
|
||||||
|
|
||||||
export const socialUserInfoGuard = z.object({
|
export const socialUserInfoGuard = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
email: z.string().optional(),
|
email: z.string().optional(),
|
||||||
phone: z.string().optional(),
|
phone: z.string().optional(),
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
avatar: z.string().optional(),
|
avatar: z.string().optional(),
|
||||||
});
|
rawData: jsonGuard.optional(),
|
||||||
|
}) satisfies z.ZodType<SocialUserInfo>;
|
||||||
|
|
||||||
export type SocialUserInfo = z.infer<typeof socialUserInfoGuard>;
|
export type GetUserInfo = (data: unknown, getSession: GetSession) => Promise<SocialUserInfo>;
|
||||||
|
|
||||||
export type GetUserInfo = (
|
|
||||||
data: unknown,
|
|
||||||
getSession: GetSession
|
|
||||||
) => Promise<SocialUserInfo & Record<string, string | boolean | number | undefined>>;
|
|
||||||
|
|
||||||
export const connectorSessionGuard = z
|
export const connectorSessionGuard = z
|
||||||
.object({
|
.object({
|
||||||
|
|
678
pnpm-lock.yaml
678
pnpm-lock.yaml
|
@ -786,6 +786,9 @@ importers:
|
||||||
'@types/supertest':
|
'@types/supertest':
|
||||||
specifier: ^6.0.0
|
specifier: ^6.0.0
|
||||||
version: 6.0.1
|
version: 6.0.1
|
||||||
|
'@vitest/coverage-v8':
|
||||||
|
specifier: ^1.4.0
|
||||||
|
version: 1.4.0(vitest@1.4.0)
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^8.44.0
|
specifier: ^8.44.0
|
||||||
version: 8.44.0
|
version: 8.44.0
|
||||||
|
@ -816,6 +819,9 @@ importers:
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.3.3
|
specifier: ^5.3.3
|
||||||
version: 5.3.3
|
version: 5.3.3
|
||||||
|
vitest:
|
||||||
|
specifier: ^1.4.0
|
||||||
|
version: 1.4.0(@types/node@20.11.20)
|
||||||
|
|
||||||
packages/connectors/connector-discord:
|
packages/connectors/connector-discord:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -4274,6 +4280,14 @@ packages:
|
||||||
'@jridgewell/trace-mapping': 0.3.18
|
'@jridgewell/trace-mapping': 0.3.18
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@ampproject/remapping@2.3.0:
|
||||||
|
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/gen-mapping': 0.3.5
|
||||||
|
'@jridgewell/trace-mapping': 0.3.25
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@apidevtools/json-schema-ref-parser@9.0.6:
|
/@apidevtools/json-schema-ref-parser@9.0.6:
|
||||||
resolution: {integrity: sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg==}
|
resolution: {integrity: sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -6264,6 +6278,16 @@ packages:
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@babel/helper-string-parser@7.23.4:
|
||||||
|
resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@babel/helper-validator-identifier@7.22.20:
|
||||||
|
resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@babel/helper-validator-identifier@7.22.5:
|
/@babel/helper-validator-identifier@7.22.5:
|
||||||
resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
|
resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
@ -6302,6 +6326,14 @@ packages:
|
||||||
'@babel/types': 7.20.2
|
'@babel/types': 7.20.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@babel/parser@7.24.0:
|
||||||
|
resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.24.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@babel/plugin-proposal-object-rest-spread@7.12.1(@babel/core@7.12.9):
|
/@babel/plugin-proposal-object-rest-spread@7.12.1(@babel/core@7.12.9):
|
||||||
resolution: {integrity: sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==}
|
resolution: {integrity: sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -6525,6 +6557,15 @@ packages:
|
||||||
to-fast-properties: 2.0.0
|
to-fast-properties: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@babel/types@7.24.0:
|
||||||
|
resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/helper-string-parser': 7.23.4
|
||||||
|
'@babel/helper-validator-identifier': 7.22.20
|
||||||
|
to-fast-properties: 2.0.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@bcoe/v8-coverage@0.2.3:
|
/@bcoe/v8-coverage@0.2.3:
|
||||||
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
|
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -7007,6 +7048,213 @@ packages:
|
||||||
postcss-selector-parser: 6.0.15
|
postcss-selector-parser: 6.0.15
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@esbuild/aix-ppc64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [ppc64]
|
||||||
|
os: [aix]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/android-arm64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/android-arm@0.19.12:
|
||||||
|
resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [android]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/android-x64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [android]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/darwin-arm64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/darwin-x64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/freebsd-arm64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [freebsd]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/freebsd-x64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [freebsd]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-arm64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-arm@0.19.12:
|
||||||
|
resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-ia32@0.19.12:
|
||||||
|
resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [ia32]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-loong64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [loong64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-mips64el@0.19.12:
|
||||||
|
resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [mips64el]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-ppc64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [ppc64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-riscv64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-s390x@0.19.12:
|
||||||
|
resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [s390x]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-x64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/netbsd-x64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [netbsd]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/openbsd-x64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [openbsd]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/sunos-x64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [sunos]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/win32-arm64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/win32-ia32@0.19.12:
|
||||||
|
resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [ia32]
|
||||||
|
os: [win32]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/win32-x64@0.19.12:
|
||||||
|
resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
/@eslint-community/eslint-utils@4.4.0(eslint@8.44.0):
|
/@eslint-community/eslint-utils@4.4.0(eslint@8.44.0):
|
||||||
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
|
@ -7510,6 +7758,15 @@ packages:
|
||||||
'@jridgewell/trace-mapping': 0.3.18
|
'@jridgewell/trace-mapping': 0.3.18
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@jridgewell/gen-mapping@0.3.5:
|
||||||
|
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/set-array': 1.2.1
|
||||||
|
'@jridgewell/sourcemap-codec': 1.4.15
|
||||||
|
'@jridgewell/trace-mapping': 0.3.25
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@jridgewell/resolve-uri@3.1.0:
|
/@jridgewell/resolve-uri@3.1.0:
|
||||||
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
|
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
|
@ -7520,6 +7777,11 @@ packages:
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@jridgewell/set-array@1.2.1:
|
||||||
|
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@jridgewell/source-map@0.3.5:
|
/@jridgewell/source-map@0.3.5:
|
||||||
resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
|
resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -7542,6 +7804,13 @@ packages:
|
||||||
'@jridgewell/sourcemap-codec': 1.4.14
|
'@jridgewell/sourcemap-codec': 1.4.14
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@jridgewell/trace-mapping@0.3.25:
|
||||||
|
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/resolve-uri': 3.1.0
|
||||||
|
'@jridgewell/sourcemap-codec': 1.4.15
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@jridgewell/trace-mapping@0.3.9:
|
/@jridgewell/trace-mapping@0.3.9:
|
||||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -10573,6 +10842,69 @@ packages:
|
||||||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@vitest/coverage-v8@1.4.0(vitest@1.4.0):
|
||||||
|
resolution: {integrity: sha512-4hDGyH1SvKpgZnIByr9LhGgCEuF9DKM34IBLCC/fVfy24Z3+PZ+Ii9hsVBsHvY1umM1aGPEjceRkzxCfcQ10wg==}
|
||||||
|
peerDependencies:
|
||||||
|
vitest: 1.4.0
|
||||||
|
dependencies:
|
||||||
|
'@ampproject/remapping': 2.3.0
|
||||||
|
'@bcoe/v8-coverage': 0.2.3
|
||||||
|
debug: 4.3.4
|
||||||
|
istanbul-lib-coverage: 3.2.2
|
||||||
|
istanbul-lib-report: 3.0.1
|
||||||
|
istanbul-lib-source-maps: 5.0.4
|
||||||
|
istanbul-reports: 3.1.7
|
||||||
|
magic-string: 0.30.7
|
||||||
|
magicast: 0.3.3
|
||||||
|
picocolors: 1.0.0
|
||||||
|
std-env: 3.7.0
|
||||||
|
strip-literal: 2.0.0
|
||||||
|
test-exclude: 6.0.0
|
||||||
|
v8-to-istanbul: 9.2.0
|
||||||
|
vitest: 1.4.0(@types/node@20.11.20)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vitest/expect@1.4.0:
|
||||||
|
resolution: {integrity: sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==}
|
||||||
|
dependencies:
|
||||||
|
'@vitest/spy': 1.4.0
|
||||||
|
'@vitest/utils': 1.4.0
|
||||||
|
chai: 4.4.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vitest/runner@1.4.0:
|
||||||
|
resolution: {integrity: sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==}
|
||||||
|
dependencies:
|
||||||
|
'@vitest/utils': 1.4.0
|
||||||
|
p-limit: 5.0.0
|
||||||
|
pathe: 1.1.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vitest/snapshot@1.4.0:
|
||||||
|
resolution: {integrity: sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==}
|
||||||
|
dependencies:
|
||||||
|
magic-string: 0.30.7
|
||||||
|
pathe: 1.1.2
|
||||||
|
pretty-format: 29.7.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vitest/spy@1.4.0:
|
||||||
|
resolution: {integrity: sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==}
|
||||||
|
dependencies:
|
||||||
|
tinyspy: 2.2.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@vitest/utils@1.4.0:
|
||||||
|
resolution: {integrity: sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==}
|
||||||
|
dependencies:
|
||||||
|
diff-sequences: 29.6.3
|
||||||
|
estree-walker: 3.0.3
|
||||||
|
loupe: 2.3.7
|
||||||
|
pretty-format: 29.7.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@withtyped/client@0.8.4(zod@3.22.4):
|
/@withtyped/client@0.8.4(zod@3.22.4):
|
||||||
resolution: {integrity: sha512-oX19xZRjUASZLWUzQW4LKhLsDgtwFfWU7mgReKiY/tddwvHLoakLqz1o1MvRDuz+EOoYrQM+VpkwJeMsnbNT1w==}
|
resolution: {integrity: sha512-oX19xZRjUASZLWUzQW4LKhLsDgtwFfWU7mgReKiY/tddwvHLoakLqz1o1MvRDuz+EOoYrQM+VpkwJeMsnbNT1w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -10659,12 +10991,23 @@ packages:
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/acorn-walk@8.3.2:
|
||||||
|
resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
|
||||||
|
engines: {node: '>=0.4.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/acorn@8.10.0:
|
/acorn@8.10.0:
|
||||||
resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
|
resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/acorn@8.11.3:
|
||||||
|
resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==}
|
||||||
|
engines: {node: '>=0.4.0'}
|
||||||
|
hasBin: true
|
||||||
|
dev: true
|
||||||
|
|
||||||
/agent-base@6.0.2:
|
/agent-base@6.0.2:
|
||||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||||
engines: {node: '>= 6.0.0'}
|
engines: {node: '>= 6.0.0'}
|
||||||
|
@ -10907,6 +11250,10 @@ packages:
|
||||||
tslib: 2.6.2
|
tslib: 2.6.2
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/assertion-error@1.1.0:
|
||||||
|
resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/ast-types-flow@0.0.7:
|
/ast-types-flow@0.0.7:
|
||||||
resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==}
|
resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -11233,6 +11580,11 @@ packages:
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/cac@6.7.14:
|
||||||
|
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/cache-content-type@1.0.1:
|
/cache-content-type@1.0.1:
|
||||||
resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==}
|
resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==}
|
||||||
engines: {node: '>= 6.0.0'}
|
engines: {node: '>= 6.0.0'}
|
||||||
|
@ -11350,6 +11702,19 @@ packages:
|
||||||
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/chai@4.4.1:
|
||||||
|
resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dependencies:
|
||||||
|
assertion-error: 1.1.0
|
||||||
|
check-error: 1.0.3
|
||||||
|
deep-eql: 4.1.3
|
||||||
|
get-func-name: 2.0.2
|
||||||
|
loupe: 2.3.7
|
||||||
|
pathval: 1.1.1
|
||||||
|
type-detect: 4.0.8
|
||||||
|
dev: true
|
||||||
|
|
||||||
/chalk@2.4.2:
|
/chalk@2.4.2:
|
||||||
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -11398,6 +11763,12 @@ packages:
|
||||||
/chardet@0.7.0:
|
/chardet@0.7.0:
|
||||||
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
|
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
|
||||||
|
|
||||||
|
/check-error@1.0.3:
|
||||||
|
resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
|
||||||
|
dependencies:
|
||||||
|
get-func-name: 2.0.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/chokidar@3.5.3:
|
/chokidar@3.5.3:
|
||||||
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
|
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
|
||||||
engines: {node: '>= 8.10.0'}
|
engines: {node: '>= 8.10.0'}
|
||||||
|
@ -12163,6 +12534,13 @@ packages:
|
||||||
optional: true
|
optional: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/deep-eql@4.1.3:
|
||||||
|
resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dependencies:
|
||||||
|
type-detect: 4.0.8
|
||||||
|
dev: true
|
||||||
|
|
||||||
/deep-equal@1.0.1:
|
/deep-equal@1.0.1:
|
||||||
resolution: {integrity: sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=}
|
resolution: {integrity: sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=}
|
||||||
|
|
||||||
|
@ -12574,6 +12952,37 @@ packages:
|
||||||
is-symbol: 1.0.4
|
is-symbol: 1.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/esbuild@0.19.12:
|
||||||
|
resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
hasBin: true
|
||||||
|
requiresBuild: true
|
||||||
|
optionalDependencies:
|
||||||
|
'@esbuild/aix-ppc64': 0.19.12
|
||||||
|
'@esbuild/android-arm': 0.19.12
|
||||||
|
'@esbuild/android-arm64': 0.19.12
|
||||||
|
'@esbuild/android-x64': 0.19.12
|
||||||
|
'@esbuild/darwin-arm64': 0.19.12
|
||||||
|
'@esbuild/darwin-x64': 0.19.12
|
||||||
|
'@esbuild/freebsd-arm64': 0.19.12
|
||||||
|
'@esbuild/freebsd-x64': 0.19.12
|
||||||
|
'@esbuild/linux-arm': 0.19.12
|
||||||
|
'@esbuild/linux-arm64': 0.19.12
|
||||||
|
'@esbuild/linux-ia32': 0.19.12
|
||||||
|
'@esbuild/linux-loong64': 0.19.12
|
||||||
|
'@esbuild/linux-mips64el': 0.19.12
|
||||||
|
'@esbuild/linux-ppc64': 0.19.12
|
||||||
|
'@esbuild/linux-riscv64': 0.19.12
|
||||||
|
'@esbuild/linux-s390x': 0.19.12
|
||||||
|
'@esbuild/linux-x64': 0.19.12
|
||||||
|
'@esbuild/netbsd-x64': 0.19.12
|
||||||
|
'@esbuild/openbsd-x64': 0.19.12
|
||||||
|
'@esbuild/sunos-x64': 0.19.12
|
||||||
|
'@esbuild/win32-arm64': 0.19.12
|
||||||
|
'@esbuild/win32-ia32': 0.19.12
|
||||||
|
'@esbuild/win32-x64': 0.19.12
|
||||||
|
dev: true
|
||||||
|
|
||||||
/escalade@3.1.1:
|
/escalade@3.1.1:
|
||||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
@ -13104,6 +13513,12 @@ packages:
|
||||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/estree-walker@3.0.3:
|
||||||
|
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
|
||||||
|
dependencies:
|
||||||
|
'@types/estree': 1.0.5
|
||||||
|
dev: true
|
||||||
|
|
||||||
/esutils@2.0.3:
|
/esutils@2.0.3:
|
||||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -13680,6 +14095,10 @@ packages:
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/get-func-name@2.0.2:
|
||||||
|
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/get-intrinsic@1.1.3:
|
/get-intrinsic@1.1.3:
|
||||||
resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==}
|
resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -14893,6 +15312,11 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/istanbul-lib-coverage@3.2.2:
|
||||||
|
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/istanbul-lib-instrument@5.2.1:
|
/istanbul-lib-instrument@5.2.1:
|
||||||
resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
|
resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -14928,6 +15352,15 @@ packages:
|
||||||
supports-color: 7.2.0
|
supports-color: 7.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/istanbul-lib-report@3.0.1:
|
||||||
|
resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dependencies:
|
||||||
|
istanbul-lib-coverage: 3.2.2
|
||||||
|
make-dir: 4.0.0
|
||||||
|
supports-color: 7.2.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/istanbul-lib-source-maps@4.0.1:
|
/istanbul-lib-source-maps@4.0.1:
|
||||||
resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
|
resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
@ -14939,6 +15372,17 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/istanbul-lib-source-maps@5.0.4:
|
||||||
|
resolution: {integrity: sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/trace-mapping': 0.3.25
|
||||||
|
debug: 4.3.4
|
||||||
|
istanbul-lib-coverage: 3.2.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
/istanbul-reports@3.1.5:
|
/istanbul-reports@3.1.5:
|
||||||
resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==}
|
resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -14947,6 +15391,14 @@ packages:
|
||||||
istanbul-lib-report: 3.0.0
|
istanbul-lib-report: 3.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/istanbul-reports@3.1.7:
|
||||||
|
resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
dependencies:
|
||||||
|
html-escaper: 2.0.2
|
||||||
|
istanbul-lib-report: 3.0.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/jest-changed-files@29.7.0:
|
/jest-changed-files@29.7.0:
|
||||||
resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==}
|
resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==}
|
||||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||||
|
@ -15711,6 +16163,10 @@ packages:
|
||||||
/js-tokens@4.0.0:
|
/js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
|
/js-tokens@8.0.3:
|
||||||
|
resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/js-types@1.0.0:
|
/js-types@1.0.0:
|
||||||
resolution: {integrity: sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==}
|
resolution: {integrity: sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -16298,6 +16754,14 @@ packages:
|
||||||
engines: {node: '>= 12.13.0'}
|
engines: {node: '>= 12.13.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/local-pkg@0.5.0:
|
||||||
|
resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
dependencies:
|
||||||
|
mlly: 1.6.1
|
||||||
|
pkg-types: 1.0.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
/locate-path@5.0.0:
|
/locate-path@5.0.0:
|
||||||
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -16441,6 +16905,12 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
js-tokens: 4.0.0
|
js-tokens: 4.0.0
|
||||||
|
|
||||||
|
/loupe@2.3.7:
|
||||||
|
resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
|
||||||
|
dependencies:
|
||||||
|
get-func-name: 2.0.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/lower-case@2.0.2:
|
/lower-case@2.0.2:
|
||||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -16498,6 +16968,14 @@ packages:
|
||||||
'@jridgewell/sourcemap-codec': 1.4.15
|
'@jridgewell/sourcemap-codec': 1.4.15
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/magicast@0.3.3:
|
||||||
|
resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==}
|
||||||
|
dependencies:
|
||||||
|
'@babel/parser': 7.24.0
|
||||||
|
'@babel/types': 7.24.0
|
||||||
|
source-map-js: 1.0.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/make-dir@3.1.0:
|
/make-dir@3.1.0:
|
||||||
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
|
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -16505,6 +16983,13 @@ packages:
|
||||||
semver: 6.3.1
|
semver: 6.3.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/make-dir@4.0.0:
|
||||||
|
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dependencies:
|
||||||
|
semver: 7.6.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/make-error@1.3.6:
|
/make-error@1.3.6:
|
||||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -17160,6 +17645,15 @@ packages:
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/mlly@1.6.1:
|
||||||
|
resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==}
|
||||||
|
dependencies:
|
||||||
|
acorn: 8.11.3
|
||||||
|
pathe: 1.1.2
|
||||||
|
pkg-types: 1.0.3
|
||||||
|
ufo: 1.5.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/module-details-from-path@1.0.3:
|
/module-details-from-path@1.0.3:
|
||||||
resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==}
|
resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -17753,7 +18247,6 @@ packages:
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
dependencies:
|
dependencies:
|
||||||
yocto-queue: 1.0.0
|
yocto-queue: 1.0.0
|
||||||
dev: false
|
|
||||||
|
|
||||||
/p-locate@4.1.0:
|
/p-locate@4.1.0:
|
||||||
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
|
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
|
||||||
|
@ -17972,6 +18465,14 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pathe@1.1.2:
|
||||||
|
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/pathval@1.1.1:
|
||||||
|
resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/pend@1.2.0:
|
/pend@1.2.0:
|
||||||
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
|
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -18133,6 +18634,14 @@ packages:
|
||||||
find-up: 5.0.0
|
find-up: 5.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pkg-types@1.0.3:
|
||||||
|
resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
|
||||||
|
dependencies:
|
||||||
|
jsonc-parser: 3.2.0
|
||||||
|
mlly: 1.6.1
|
||||||
|
pathe: 1.1.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/pluralize@8.0.0:
|
/pluralize@8.0.0:
|
||||||
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
@ -19647,6 +20156,10 @@ packages:
|
||||||
get-intrinsic: 1.1.3
|
get-intrinsic: 1.1.3
|
||||||
object-inspect: 1.12.2
|
object-inspect: 1.12.2
|
||||||
|
|
||||||
|
/siginfo@2.0.0:
|
||||||
|
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/signal-exit@3.0.7:
|
/signal-exit@3.0.7:
|
||||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||||
|
|
||||||
|
@ -19887,6 +20400,10 @@ packages:
|
||||||
escape-string-regexp: 2.0.0
|
escape-string-regexp: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/stackback@0.0.2:
|
||||||
|
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/state-local@1.0.7:
|
/state-local@1.0.7:
|
||||||
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
|
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -19904,6 +20421,10 @@ packages:
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/std-env@3.7.0:
|
||||||
|
resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/stdin-discarder@0.2.2:
|
/stdin-discarder@0.2.2:
|
||||||
resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==}
|
resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
@ -20069,6 +20590,12 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/strip-literal@2.0.0:
|
||||||
|
resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==}
|
||||||
|
dependencies:
|
||||||
|
js-tokens: 8.0.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
/strnum@1.0.5:
|
/strnum@1.0.5:
|
||||||
resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
|
resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -20548,10 +21075,24 @@ packages:
|
||||||
globrex: 0.1.2
|
globrex: 0.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/tinybench@2.6.0:
|
||||||
|
resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/tinycolor2@1.6.0:
|
/tinycolor2@1.6.0:
|
||||||
resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
|
resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/tinypool@0.8.2:
|
||||||
|
resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/tinyspy@2.2.1:
|
||||||
|
resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/titleize@4.0.0:
|
/titleize@4.0.0:
|
||||||
resolution: {integrity: sha512-ZgUJ1K83rhdu7uh7EHAC2BgY5DzoX8V5rTvoWI4vFysggi6YjLe5gUXABPWAU7VkvGP7P/0YiWq+dcPeYDsf1g==}
|
resolution: {integrity: sha512-ZgUJ1K83rhdu7uh7EHAC2BgY5DzoX8V5rTvoWI4vFysggi6YjLe5gUXABPWAU7VkvGP7P/0YiWq+dcPeYDsf1g==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
@ -20829,6 +21370,10 @@ packages:
|
||||||
resolution: {integrity: sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==}
|
resolution: {integrity: sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/ufo@1.5.2:
|
||||||
|
resolution: {integrity: sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/unbox-primitive@1.0.2:
|
/unbox-primitive@1.0.2:
|
||||||
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
|
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -21059,6 +21604,15 @@ packages:
|
||||||
convert-source-map: 1.9.0
|
convert-source-map: 1.9.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/v8-to-istanbul@9.2.0:
|
||||||
|
resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==}
|
||||||
|
engines: {node: '>=10.12.0'}
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/trace-mapping': 0.3.18
|
||||||
|
'@types/istanbul-lib-coverage': 2.0.4
|
||||||
|
convert-source-map: 2.0.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
/validate-npm-package-license@3.0.4:
|
/validate-npm-package-license@3.0.4:
|
||||||
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
|
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -21105,6 +21659,119 @@ packages:
|
||||||
vfile-message: 4.0.2
|
vfile-message: 4.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/vite-node@1.4.0(@types/node@20.11.20):
|
||||||
|
resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==}
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
cac: 6.7.14
|
||||||
|
debug: 4.3.4
|
||||||
|
pathe: 1.1.2
|
||||||
|
picocolors: 1.0.0
|
||||||
|
vite: 5.1.6(@types/node@20.11.20)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/node'
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- sass
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/vite@5.1.6(@types/node@20.11.20):
|
||||||
|
resolution: {integrity: sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==}
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
'@types/node': ^18.0.0 || >=20.0.0
|
||||||
|
less: '*'
|
||||||
|
lightningcss: ^1.21.0
|
||||||
|
sass: '*'
|
||||||
|
stylus: '*'
|
||||||
|
sugarss: '*'
|
||||||
|
terser: ^5.4.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
|
less:
|
||||||
|
optional: true
|
||||||
|
lightningcss:
|
||||||
|
optional: true
|
||||||
|
sass:
|
||||||
|
optional: true
|
||||||
|
stylus:
|
||||||
|
optional: true
|
||||||
|
sugarss:
|
||||||
|
optional: true
|
||||||
|
terser:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 20.11.20
|
||||||
|
esbuild: 0.19.12
|
||||||
|
postcss: 8.4.35
|
||||||
|
rollup: 4.12.0
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents: 2.3.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/vitest@1.4.0(@types/node@20.11.20):
|
||||||
|
resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==}
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
'@edge-runtime/vm': '*'
|
||||||
|
'@types/node': ^18.0.0 || >=20.0.0
|
||||||
|
'@vitest/browser': 1.4.0
|
||||||
|
'@vitest/ui': 1.4.0
|
||||||
|
happy-dom: '*'
|
||||||
|
jsdom: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@edge-runtime/vm':
|
||||||
|
optional: true
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
|
'@vitest/browser':
|
||||||
|
optional: true
|
||||||
|
'@vitest/ui':
|
||||||
|
optional: true
|
||||||
|
happy-dom:
|
||||||
|
optional: true
|
||||||
|
jsdom:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 20.11.20
|
||||||
|
'@vitest/expect': 1.4.0
|
||||||
|
'@vitest/runner': 1.4.0
|
||||||
|
'@vitest/snapshot': 1.4.0
|
||||||
|
'@vitest/spy': 1.4.0
|
||||||
|
'@vitest/utils': 1.4.0
|
||||||
|
acorn-walk: 8.3.2
|
||||||
|
chai: 4.4.1
|
||||||
|
debug: 4.3.4
|
||||||
|
execa: 8.0.1
|
||||||
|
local-pkg: 0.5.0
|
||||||
|
magic-string: 0.30.7
|
||||||
|
pathe: 1.1.2
|
||||||
|
picocolors: 1.0.0
|
||||||
|
std-env: 3.7.0
|
||||||
|
strip-literal: 2.0.0
|
||||||
|
tinybench: 2.6.0
|
||||||
|
tinypool: 0.8.2
|
||||||
|
vite: 5.1.6(@types/node@20.11.20)
|
||||||
|
vite-node: 1.4.0(@types/node@20.11.20)
|
||||||
|
why-is-node-running: 2.2.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- sass
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
dev: true
|
||||||
|
|
||||||
/void-elements@3.1.0:
|
/void-elements@3.1.0:
|
||||||
resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=}
|
resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -21241,6 +21908,15 @@ packages:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/why-is-node-running@2.2.2:
|
||||||
|
resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
siginfo: 2.0.0
|
||||||
|
stackback: 0.0.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/word-wrap@1.2.3:
|
/word-wrap@1.2.3:
|
||||||
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
|
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
Loading…
Reference in a new issue